Search code examples
androidmultithreadinghandlermessage-queue

Use Handler To Post In To UI Thread


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()


Solution

  • 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();
                        }
                    });