インターネットから画像を取得してユーザーインターフェイスに表示するAndroidアプリケーションに取り組んでいます。画像を表示するためにRecyclerViewを使用しています。別のスレッドを使用して画像をダウンロードする予定です。ハンドラーを介してRecyclerViewを更新します。この概念が正しいかどうかはわかりません(AsyncTaskは知っていますが、学習目的でHandlerを実装しようとしています。)したがって、以下と同じようにコーディングしました。
_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();
}
_
このコードを実行しましたが、エラーが発生し、アプリケーションが終了しました。なぜこれが発生しているのかわかりません。誰かが私がそれを整理するのを手伝ってください。現在のコードの問題点を説明します。
(AsyncTaskの使用を提案しないでください(私はそれを試しましたが、正常に動作します))
[〜#〜] update [〜#〜]
取得エラー:Java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
UI以外のスレッドからnotifyDataSetChanged()を呼び出しているため、アプリケーションが終了します。
交換:
new Handler().post(new Runnable() { // Tried new Handler(Looper.myLopper()) also
@Override
public void run() {
mAdapter.notifyDataSetChanged();
}
});
これとともに:
new Handler(Looper.getMainLooper()).post(new Runnable() { // Tried new Handler(Looper.myLopper()) also
@Override
public void run() {
mAdapter.notifyDataSetChanged();
}
});
定義したスレッドにはルーパーとメッセージキューがないため、このスレッドでメッセージを送信することはできません。 AsyncTaskには独自のルーパーがあり、ソースコードで見つけることができます。これは、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;
}
}
}