Use Handler To Post In To UI Thread

20,284

Solution 1

Your application is getting terminated because you are calling notifyDataSetChanged() from a non UI Thread.

Replace:

 new Handler().post(new Runnable() { // Tried new Handler(Looper.myLopper()) also
                        @Override
                        public void run() {
                            mAdapter.notifyDataSetChanged();
                        }
                    }); 

With this:

new Handler(Looper.getMainLooper()).post(new Runnable() { // Tried new Handler(Looper.myLopper()) also
                    @Override
                    public void run() {
                        mAdapter.notifyDataSetChanged();
                    }
                });

Solution 2

The thread you defined does not have a Looper, and no message queue,so you can not send message in this thread. AsyncTask has its own Looper which you can find it in its source code. This is handler defined in AsyncTask:

private static class InternalHandler extends Handler {
    public InternalHandler() {
        super(Looper.getMainLooper());
    }

    @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
    @Override
    public void handleMessage(Message msg) {
        AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
        switch (msg.what) {
            case MESSAGE_POST_RESULT:
                // There is only one result
                result.mTask.finish(result.mData[0]);
                break;
            case MESSAGE_POST_PROGRESS:
                result.mTask.onProgressUpdate(result.mData);
                break;
        }
    }
}
Share:
20,284
droidev
Author by

droidev

Professionally Android developer. Love to work on MEAN Stack.

Updated on February 16, 2020

Comments

  • droidev
    droidev over 4 years

    I am working on an android application, that fetches image from Internet and show in the user interface. I am using RecyclerView for showing the image. I am planning to download the image using a separate thread. and update RecyclerView via the handler. I dont know wether this concept is correct or not, (I know AsyncTask, but for learning purpose I am trying to implement Handler.) So I coded for the same as below

    private void loadNewsThumbnailImage(ArrayList<DataItem> dataList) {
        for (DataItem item : DataList) { //DataItem is the model class
            loadThumbnailFromInternet(item);
            }
    }
    
    
    
    private void loadThumbnailFromInternet(final DataItem dataItem) {
    
            Thread imageDowloaderThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    Bitmap bitmap = null;
                    try {
                        bitmap = getDataItemBitmap(dataItem.getmImageUrl());
                        dataItem.setmThumbnail(bitmap);
                        new Handler().post(new Runnable() { // Tried new Handler(Looper.myLopper()) also
                            @Override
                            public void run() {
                                mAdapter.notifyDataSetChanged();
                            }
                        });
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
            imageDowloaderThread.start();
    
        }
    

    I have executed this code but I am getting error, and application is terminated, I don't know why this is happening . please any one help me to sort it out. and explain what is the problem for the current code.

    (Please do not suggest to use AsyncTask (I have tried that and it works fine))

    UPDATE

    Error getting :java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()

  • droidev
    droidev almost 9 years
    that sounds good, but then what is the difference between Looper.getMainLooper() and Looper.myLooper() ?
  • Sunny Shah
    Sunny Shah almost 9 years
    Looper.getMainLooper() gets the application's main looper whereas Looper.myLooper() returns the Looper associated with the current thread. refere: developer.android.com/reference/android/os/Looper.html