Use Handler To Post In To UI Thread
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;
}
}
}
droidev
Professionally Android developer. Love to work on MEAN Stack.
Updated on February 16, 2020Comments
-
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 almost 9 yearsthat sounds good, but then what is the difference between Looper.getMainLooper() and Looper.myLooper() ?
-
Sunny Shah almost 9 yearsLooper.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