Android: загрузка изображения из Интернета с помощью Asynctask - PullRequest
36 голосов
/ 22 июня 2010

Как заменить следующие строки кода на Asynctask? Как «вернуть» растровое изображение из Asynctask? Спасибо.

ImageView mChart = (ImageView) findViewById(R.id.Chart);
String URL = "http://www...anything ...";

mChart.setImageBitmap(download_Image(URL));

public static Bitmap download_Image(String url) {

        //---------------------------------------------------
        Bitmap bm = null;
        try {
            URL aURL = new URL(url);
            URLConnection conn = aURL.openConnection();
            conn.connect();
            InputStream is = conn.getInputStream();
            BufferedInputStream bis = new BufferedInputStream(is);
            bm = BitmapFactory.decodeStream(bis);
            bis.close();
            is.close();
        } catch (IOException e) {
            Log.e("Hub","Error getting the image from server : " + e.getMessage().toString());
        } 
        return bm;
        //---------------------------------------------------

    }

Я думал о чем-то вроде этого:

заменить:

mChart.setImageBitmap(download_Image(graph_URL));

чем-то вроде:

mChart.setImageBitmap(new DownloadImagesTask().execute(graph_URL));

и

public class DownloadImagesTask extends AsyncTask<String, Void, Bitmap> {

@Override
protected Bitmap doInBackground(String... urls) {
    return download_Image(urls[0]);
}

@Override
protected void onPostExecute(Bitmap result) {
    mChart.setImageBitmap(result);              // how do I pass a reference to mChart here ?
}


private Bitmap download_Image(String url) {
    //---------------------------------------------------
    Bitmap bm = null;
    try {
        URL aURL = new URL(url);
        URLConnection conn = aURL.openConnection();
        conn.connect();
        InputStream is = conn.getInputStream();
        BufferedInputStream bis = new BufferedInputStream(is);
        bm = BitmapFactory.decodeStream(bis);
        bis.close();
        is.close();
    } catch (IOException e) {
        Log.e("Hub","Error getting the image from server : " + e.getMessage().toString());
    } 
    return bm;
    //---------------------------------------------------
}


}

но как передать ссылку на mChart в onPostExecute (результат растрового изображения) ??? Нужно ли передавать его с помощью URL-адреса каким-либо образом? Я хотел бы заменить все мои строки кода:

mChart1.setImageBitmap(download_Image(URL_1));
mChart2.setImageBitmap(download_Image(URL_2));

с чем-то похожим ... но по-асинхронно!

mChart1.setImageBitmap(new DownloadImagesTask().execute(graph_URL_1));
mChart2.setImageBitmap(new DownloadImagesTask().execute(graph_URL_2));

Есть ли простое решение для этого? Я что-то здесь не так понимаю?

Ответы [ 4 ]

74 голосов
/ 22 июня 2010

Если нет веских причин для самостоятельной загрузки изображения, я бы рекомендовал использовать Picasso .

Picasso избавит вас от всех проблем с загрузкой, настройкой и кэшированием изображений. Весь код, необходимый для простого примера:

Picasso.with(context).load(url).into(imageView);

Если вы действительно хотите все сделать сами, используйте мой старый ответ ниже.


Если изображение не такое большое, вы можете просто использовать анонимный класс для асинхронной задачи. Это было бы так:

ImageView mChart = (ImageView) findViewById(R.id.imageview);
String URL = "http://www...anything ...";

mChart.setTag(URL);
new DownloadImageTask.execute(mChart);

Класс задачи:

public class DownloadImagesTask extends AsyncTask<ImageView, Void, Bitmap> {

ImageView imageView = null;

@Override
protected Bitmap doInBackground(ImageView... imageViews) {
    this.imageView = imageViews[0];
    return download_Image((String)imageView.getTag());
}

@Override
protected void onPostExecute(Bitmap result) {
    imageView.setImageBitmap(result);
}


private Bitmap download_Image(String url) {
   ...
}

Скрывать URL-адрес в теге немного сложно, но в вызывающем классе это выглядит лучше, если у вас есть много изображений, которые вы хотите заполнить таким образом. Это также помогает, если вы используете ImageView внутри ListView и хотите знать, был ли ImageView переработан во время загрузки изображения.

Я написал, если ваш образ не такой большой, потому что это приведет к тому, что у задачи будет неявный указатель на основное действие, в результате чего сборщик мусора сохранит все действие в памяти, пока задача не будет завершена. Если пользователь переходит на другой экран вашего приложения во время загрузки растрового изображения, память не может быть освобождена, и это может замедлить работу вашего приложения и всей системы.

22 голосов
/ 27 февраля 2013

Попробуйте этот код:

ImageView myFirstImage = (ImageView) findViewById(R.id.myFirstImage);
ImageView mySecondImage = (ImageView) findViewById(R.id.mySecondImage);
ImageView myThirdImage = (ImageView) findViewById(R.id.myThirdImage);

String URL1 = "http://www.google.com/logos/2013/estonia_independence_day_2013-1057005.3-hp.jpg";
String URL2 = "http://www.google.com/logos/2013/park_su-geuns_birthday-1055005-hp.jpg";
String URL3 = "http://www.google.com/logos/2013/anne_cath_vestlys_93rd_birthday-1035005-hp.jpg";


myFirstImage.setTag(URL1);
mySecondImage.setTag(URL2);
myThirdImage.setTag(URL3);


new DownloadImageTask.execute(myFirstImage);
new DownloadImageTask.execute(mySecondImage);
new DownloadImageTask.execute(myThirdImage);



public class DownloadImagesTask extends AsyncTask<ImageView, Void, Bitmap> {

    ImageView imageView = null;

    @Override
    protected Bitmap doInBackground(ImageView... imageViews) {
        this.imageView = imageViews[0];
        return download_Image((String)imageView.getTag());
    }

    @Override
    protected void onPostExecute(Bitmap result) {
        imageView.setImageBitmap(result);
    }

    private Bitmap download_Image(String url) {

        Bitmap bmp =null;
        try{
            URL ulrn = new URL(url);
            HttpURLConnection con = (HttpURLConnection)ulrn.openConnection();
            InputStream is = con.getInputStream();
            bmp = BitmapFactory.decodeStream(is);
            if (null != bmp)
                return bmp;

            }catch(Exception e){}
        return bmp;
    }
}
2 голосов
/ 22 июня 2010

вы можете создать класс say..BkgProcess, который содержит внутренний класс, расширяющий AsyncTask.при создании экземпляра BkgProcess передайте контекст вашего класса Activity в конструктор BkgProcess.например:

public class BkgProcess {

 String path;   
 Context _context;

public Download(Downloader downloader, String path2){

 this.path = path2;
    _context = downloader;

}

public void callProgressDialog(){

new BkgProcess().execute((Void)null);
}
class Downloads extends AsyncTask<Void, Void, Boolean> {
    private ProgressDialog dialog = new ProgressDialog(_context);
    protected void onPreExecute(){
        dialog.setMessage("Downloading image..");
        dialog.show();
    }

    protected void onPostExecute(Boolean success) {
        dialog.dismiss();
        if(success)
            Toast.makeText(_context, "Download complete", Toast.LENGTH_SHORT).show();
    }

@Override
protected Boolean doInBackground(Void... params) {
    return(startDownload(path));

    }


public boolean startDownload(String img_url) {

// download img..

      return true;
}
}
}

из вашего класса активности ..

BkgProcess dwn = new BkgProcess (Your_Activity_class.this, img_path);

dwn.callProgressDialog();
1 голос
/ 22 июня 2010

Это даст вам изображения любого размера ... если вы не хотите, чтобы диалоги прогресса просто комментировали коды в onPreExecute ();

for(int i = 0 ; i < no_of_files ; i++ )
 new FetchFilesTask().execute(image_url[i]);


private class FetchFilesTask extends AsyncTask<String, Void, Bitmap> {

    private ProgressDialog dialog = new ProgressDialog(FileExplorer.this);
    Bitmap bitmap[];
    protected void onPreExecute(){
        dialog.setMessage("fetching image from the server");
        dialog.show();
    }

     protected Bitmap doInBackground(String... args) {

             bitmap = getBitmapImageFromServer();
         return bitmap;
     }

     protected void onPostExecute(Bitmap m_bitmap) {
         dialog.dismiss();
         if(m_bitmap != null)
             //store the images in an array or do something else with all the images.   
     }
 }

public Bitmap getBitmapImageFromServer(){

    // fetch image form the url using the URL and URLConnection class
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...