У вас проблемы с производительностью, потому что вы вызываете метод get()
на вашем AsyncTask
.Метод get()
в основном заставляет основной поток ждать, пока код в AsyncTask
завершит выполнение, прежде чем основной поток продолжит выполнение других инструкций.Почему Google добавил этот метод, по меньшей мере, любопытно.Так что сделайте это, чтобы исправить ваш код.
Создайте новый файл класса Java.Назовите файл «DownloadImageTask» и добавьте этот код:
public interface DownloadImageListener {
void onCompletedImageDownload(Bitmap bm);
}
public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
private static final String TAG = DownloadImageTask.class.getSimpleName();
private DownloadImageListener mListener;
private String imageUrl = "";
public DownloadImageTask(String imageUrl, DownloadImageListener listener){
this.imageUrl = imageUrl;
this.mListener = listener;
}
@Override
protected Bitmap doInBackground(String... urls) {
Bitmap bm = null;
try {
InputStream in = new java.net.URL(imageUrl).openStream();
bm = BitmapFactory.decodeStream(in);
} catch (Exception e) {
e.printStackTrace();
}
return bm;
}
protected void onPostExecute(Bitmap bm) {
mListener.onCompletedImageDownload(bm);
}
}
Если у вас возникли проблемы с добавлением общедоступного interface
в файл Java «DownloadImageTask», просто создайте отдельное имя файла Java «DownloadImageListener»"и вставьте туда код interface
.
Установите код для запроса AsyncTask
.
Измените код Adapter
внутри вашего getView()
с этого:
try {
Bitmap bm = new DownloadImageTask().execute(dataModel.getSpriteUrl()).get();
viewHolder.sprite.setImageBitmap(bm);
} catch (Exception e) {
e.printStackTrace();
}
на это:
try {
DownloadImageListener listener = new DownloadImageListener() {
@Override
public void onCompletedImageDownload(Bitmap bm) {
if(bm != null){
viewHolder.sprite.setImageBitmap(bm);
}
}
};
String imageUrl = dataModel.getSpriteUrl();
DownloadImageTask downloadImageTask = new DownloadImageTask(imageUrl, listener);
downloadImageTask.execute();
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
Это позволяетAsyncTask
для выполнения, и когда возвращается Bitmap
, слушатель запускается в методе onPostExecute()
, отправляя Bitmap
вашему ListView
в методе обратного вызова onCompletedImageDownload()
.
Дополнительная информация:
Для дальнейшего повышения производительности вы можете создать модель кэширования для сохранения и извлечения изображений с устройства, если вы уже загружали их в прошлом.Но для этого требуются некоторые действительно продвинутые методы - и становится действительно сложно, когда изображения, которые вы хотите загрузить, могут время от времени меняться.