Скачивая много изображений с помощью AsyncTask и отправляйте их в ImageView

Я сижу и пытаюсь сделать некоторые упражнения с Android. Сегодня я хочу сделать простое приложение, которое будет загружать данные (изображения из URL-адресов) и показывать их в элементе управления ImageView в макете. Я видел несколько примеров в Интернете и сделал свое приложение. Кажется, все в порядке, но когда я нажимаю кнопку, я запускаю свою работу, но потом не отображается ошибка: NULL POINTER 9error read file). Вот мой код:

package com.example.htmlcontent; import java.io.BufferedInputStream; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Bundle; import android.widget.Button; import android.widget.ImageView; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; public class MainActivity extends Activity { private ImageView mImageView; private ImageView mImageView2; public Button button; public static ArrayList<Drawable> drawable; public static String[] URLs = {"http://zitterman.com/wp-content/uploads/2013/07/19194927_1371972212.jpg","http://i.imgur.com/CQzlM.jpg"}; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mImageView = (ImageView) findViewById(R.id.test_image); mImageView2 = (ImageView) findViewById(R.id.test_image2); button = (Button) findViewById(R.id.download1); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { new DownloadImage().execute(); } }); } /** * Simple functin to set a Drawable to the image View * @param drawable */ @SuppressWarnings("deprecation") private void setImage() { if(drawable.get(0) == null) { System.out.println("DRAWABLE JEST NULL"); } mImageView.setBackgroundDrawable(drawable.get(0)); mImageView2.setBackgroundDrawable(drawable.get(1)); } public class DownloadImage extends AsyncTask<Void, Void, Void> { /** * Called after the image has been downloaded * -> this calls a function on the main thread again */ protected void onPostExecute(Drawable image) { setImage(); } protected void onPreExecute() { Log.i("333333", "Uruchamiam WATEK SCIAGANIA ASYNCTASKIEM PLIKU Z NETA"); } @Override protected Void doInBackground(Void... params) { downloadImage(); return null; } /** * Actually download the Image from the _url * @param _url * @return */ @SuppressWarnings("deprecation") private void downloadImage() { //Prepare to download image URL url; InputStream in; BufferedInputStream buf; //BufferedInputStream buf; for(int i = 0; i<URLs.length; i++) { try { url = new URL(URLs[i]); in = url.openStream(); // Read the inputstream buf = new BufferedInputStream(in); // Convert the BufferedInputStream to a Bitmap Bitmap bMap = BitmapFactory.decodeStream(buf); if (in != null) { in.close(); } if (buf != null) { buf.close(); } drawable.add(new BitmapDrawable(bMap)); } catch (Exception e) { Log.e("Error reading file", e.toString()); } } } } } 

И мой макет XML-файла:

 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <Button android:id="@+id/download1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" /> <TextView android:layout_width="102dp" android:layout_height="wrap_content" android:text="hello" /> <ImageView android:id="@+id/test_image" android:layout_width="match_parent" android:layout_height="200dp" android:background="@drawable/ic_launcher" /> <ImageView android:id="@+id/test_image2" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/ic_launcher" /> </LinearLayout> 

Я сделал, как вы видите в коде ArrayList, который является списком Drawable. Ошибка в коде. Только это NULL POINTERs.

Измените асинхронную задачу как

  public class DownloadImage extends AsyncTask<Void, Void, ArrayList<Drawable>> { /** * Called after the image has been downloaded * -> this calls a function on the main thread again */ protected void onPostExecute( ArrayList<Drawable> drawable) { setImage(drawable); } protected void onPreExecute() { Log.i("333333", "Uruchamiam WATEK SCIAGANIA ASYNCTASKIEM PLIKU Z NETA"); } @Override protected ArrayList<Drawable> doInBackground(Void... params) { downloadImage(); return drawable; } private void setImage(ArrayList<Drawable> drawable) { if(drawable.get(0) == null) { System.out.println("DRAWABLE JEST NULL"); } mImageView.setBackgroundDrawable(drawable.get(0)); mImageView2.setBackgroundDrawable(drawable.get(1)); } 

Я думаю, что это потому, что вы забыли инициализировать извлечение. Изменить на:

 public static ArrayList<Drawable> drawable = new ArrayList<Drawable>(); 

Далее, поскольку ваша AsyncTask <Void, Void, Void> . Ваш пост должен быть следующим:

  @Override protected void onPostExecute(Void aVoid) { setImage(); } 

Общие типы <A,B,C> соответствуют параметрам и возвращаемым типам differnt-методов. Подробнее об этом читайте здесь: https://stackoverflow.com/a/6053673/827110

(Для полной полноты) вам также потребуется разрешение на использование в вашем AndroidManifest.xml add (прямо перед <application.. ):

 <uses-permission android:name="android.permission.INTERNET" /> 

Хорошо, я исправлю это, как вы сказали. Да, я забыл инициализировать этого arraylist в начале, но вы были быстрее меня;) Итак

 public class MainActivity extends Activity { private ImageView mImageView; private ImageView mImageView2; public Button button; public static ArrayList<Drawable> drawable = new ArrayList<Drawable>(); public static String[] URLs = {"http://zitterman.com/wp-content/uploads/2013/07/19194927_1371972212.jpg","http://i.imgur.com/CQzlM.jpg"}; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mImageView = (ImageView) findViewById(R.id.test_image); mImageView2 = (ImageView) findViewById(R.id.test_image2); button = (Button) findViewById(R.id.download1); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { new DownloadImage().execute(); } }); } /** * Simple functin to set a Drawable to the image View * @param drawable */ @SuppressWarnings("deprecation") private void setImage( ArrayList<Drawable> drawable) { if(drawable.get(0) == null) { System.out.println("DRAWABLE JEST NULL"); } mImageView.setBackgroundDrawable(drawable.get(0)); mImageView2.setBackgroundDrawable(drawable.get(1)); } public class DownloadImage extends AsyncTask<Void, Void, ArrayList<Drawable>> { /** * Called after the image has been downloaded * -> this calls a function on the main thread again */ protected void onPostExecute( ArrayList<Drawable> drawable) { setImage(drawable); } protected void onPreExecute() { Log.i("333333", "Uruchamiam WATEK SCIAGANIA ASYNCTASKIEM PLIKU Z NETA"); } @Override protected ArrayList<Drawable> doInBackground(Void... params) { downloadImage(); return null; } /** * Actually download the Image from the _url * @param _url * @return */ @SuppressWarnings("deprecation") private void downloadImage() { //Prepare to download image URL url; InputStream in; BufferedInputStream buf; //BufferedInputStream buf; for(int i = 0; i<URLs.length; i++) { try { url = new URL(URLs[i]); in = url.openStream(); // Read the inputstream buf = new BufferedInputStream(in); // Convert the BufferedInputStream to a Bitmap Bitmap bMap = BitmapFactory.decodeStream(buf); if (in != null) { in.close(); } if (buf != null) { buf.close(); } drawable.add(new BitmapDrawable(bMap)); } catch (Exception e) { Log.e("Error reading file", e.toString()); } } } } } 

Теперь он падает при попытке загрузки изображений. Я не понимаю, почему я должен поставить ArrayList в качестве третьего параметра …? Почему, если я объявляю статический массив, где храню свои изображения? OnPostExecute он должен вызывать только функцию, которая сделает остальную работу.