Collecter
Collecter

Reputation: 306

Handler will not bind to main thread

So my code seems to run just fine until it hits this line

adapter.notifyDataSetChanged();

The error that pops up in the logcat is CalledFromWrongThreadException. The debug also shows the handler being run in the Background thread. How do I get the handler to bind to the main thread, and not the background one? I thought I just had to create the handler in the main thread, but I guess I am wrong, quite possible I am new to andriod. How do I fix this?

//Imports are included
public class DirectoryActivity extends ListActivity {
    private ProgressDialog ProgressDialog = null;
    private ArrayList<DirectoryListing> listing = null;
    private DirectoryAdapter adapter;
    private Runnable viewOrders;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.directory);
    final Handler handler = new Handler() {

        @Override
        public void handleMessage(Message msg) {


            if (listing != null && listing.size() > 0) {
                adapter.notifyDataSetChanged();
                for (int i = 0; i < listing.size(); i++)
                    adapter.add(listing.get(i));
                Log.e("log_tag", "\nStill running\n");
            }
            ProgressDialog.dismiss();
            adapter.notifyDataSetChanged();

        }

    };
    listing = new ArrayList<DirectoryListing>();
    adapter = new DirectoryAdapter(this, R.layout.rows, listing);
    setListAdapter(adapter);
    ProgressDialog = ProgressDialog.show(DirectoryActivity.this, "Please wait...", "Retrieving data ...", true);
    viewOrders = new Runnable() {
        @Override
        public void run() {
            listing = PreparePage.getArrayList();
            handler.handleMessage(null);
        }
    };
    Thread thread = new Thread(null, viewOrders, "Background");
    thread.start();




}


private static class PreparePage {
    protected static ArrayList<DirectoryListing> getArrayList() {

        ArrayList<DirectoryListing> listings = new ArrayList<DirectoryListing>();
        JSONObject information = GetPageData.getJSONFromURL(url);
        Iterator key = information.keys();

        while (key.hasNext()) {
            String id = (String) key.next();
            JSONObject info = null;
            try {
                info = information.getJSONObject(id);
            } catch (JSONException e) {
                e.printStackTrace();
            }
            String name = "", title = "", photo = "";
            try {
                name = info.get("firstName") + " " + info.get("lastName");
                title = info.getJSONObject("position").getString("name");
                photo = info.optString("photoPath", "none");
            } catch (JSONException e) {
                e.printStackTrace();
            }
            listings.add(new DirectoryListing(name, title, photo));

        }
        return listings;
    }
}

}

Upvotes: 1

Views: 490

Answers (2)

FoamyGuy
FoamyGuy

Reputation: 46846

Try calling handler.sendEmptyMessage(0); instead of handler.handleMessage(null);

I don't know why this would cause the errors you are seeing, but this is how I have it set up when I use handler and thread instead of AsyncTask. And I have have never seen that error doing it this way.

@Nguyen is right though AsyncTask is the preferred way to handle these types of things now. And it actually makes it much easier to do.

AsyncTask docs

AsyncTask Example

Upvotes: 1

Nguyen  Minh Binh
Nguyen Minh Binh

Reputation: 24423

In my experience, you should create your own class that extends AsyncTask class to do something at background. This is a simpler and more effectively than using thread + handler.

Upvotes: 1

Related Questions