Как установить изображение из Url с помощью AsyncTask?

Я программист новичков, я делаю программу андроида, которая отображает изображение на ImageView с заданного URL-адреса. Моя проблема заключается в том, как вы используете это в AsyncTask?

Эти коды работают на min SDK 2.2, но я переключился на min SDK 3.0, поэтому он должен запускаться на AsyncTask. Спасибо за помощь! 🙂

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); satellite(); //satellite's image from main menu } //******satellite url private void satellite() { // TODO Auto-generated method stub ImageView imgView =(ImageView)findViewById(R.id.satellite); Drawable drawable = LoadImageFromWeb("http://www.pagasa.dost.gov.ph/wb/sat_images/satellite.gif"); imgView.setImageDrawable(drawable); } private Drawable LoadImageFromWeb(String url){ try{ InputStream is = (InputStream) new URL(url).getContent(); Drawable d = Drawable.createFromStream(is, "src name"); return d; }catch (Exception e) { System.out.println("Exc="+e); return null; } } 

Ну, я не знаю, почему SDK для Android не поддерживает его (пока). Я расширил класс ImageView классом UrlImageView с поддержкой асинхронной загрузки и кэширования. Я помещаю код моего класса ниже, который подключается и воспроизводится. Тело класса находится в конце моего поста, теперь я пишу две строки, как использовать его удобным способом.

В настоящее время поддерживаются еще два метода:

 setImageUrl(URL url) // sets the bitmap by its URL cancelLoading(); // tell this view to cancel pending load 

Как использовать Java-код:

 // [somewhere in your activity] UrlImageView urlImg = new UrlImageView(this).setImageUrl("http://abc.png"); ... urlImg.setImageUrl("http://abc2.png"); // works like expected 

Как связать в ваших макетах:

 <!-- thumbnail --> <com.gplushub.android.view.UrlImageView android:id="@+id/thumbnail" android:layout_width="64dp" android:layout_height="64dp" android:layout_gravity="center_vertical" android:layout_marginRight="2dp" android:scaleType="fitXY" /> 

.. и снова в вашей активности java-код:

 ((UrlImageView)findViewById(R.id.thumbnail)).setImageUrl("http://foo.bar.png"); 

Я использую его в списках с более чем 100 записями – бросается очень хорошо. Здесь тело класса, вы можете использовать его, модифицировать, расширять, что угодно:

 package com.gplushub.android.view; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.net.URLConnection; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.AsyncTask; import android.util.AttributeSet; import android.util.Log; import android.widget.ImageView; /** * an {@link ImageView} supporting asynchronous loading from URL. Additional * APIs: {@link #setImageURL(URL)}, {@link #cancelLoading()}. * * @author ep@gplushub.com / Eugen Plischke * */ public class UrlImageView extends ImageView { private static class UrlLoadingTask extends AsyncTask<URL, Void, Bitmap> { private final ImageView updateView; private boolean isCancelled = false; private InputStream urlInputStream; private UrlLoadingTask(ImageView updateView) { this.updateView = updateView; } @Override protected Bitmap doInBackground(URL... params) { try { URLConnection con = params[0].openConnection(); // can use some more params, ie caching directory etc con.setUseCaches(true); this.urlInputStream = con.getInputStream(); return BitmapFactory.decodeStream(urlInputStream); } catch (IOException e) { Log.w(UrlImageView.class.getName(), "failed to load image from " + params[0], e); return null; } finally { if (this.urlInputStream != null) { try { this.urlInputStream.close(); } catch (IOException e) { ; // swallow } finally { this.urlInputStream = null; } } } } @Override protected void onPostExecute(Bitmap result) { if (!this.isCancelled) { // hope that call is thread-safe this.updateView.setImageBitmap(result); } } /* * just remember that we were cancelled, no synchronization necessary */ @Override protected void onCancelled() { this.isCancelled = true; try { if (this.urlInputStream != null) { try { this.urlInputStream.close(); } catch (IOException e) { ;// swallow } finally { this.urlInputStream = null; } } } finally { super.onCancelled(); } } } /* * track loading task to cancel it */ private AsyncTask<URL, Void, Bitmap> currentLoadingTask; /* * just for sync */ private Object loadingMonitor = new Object(); public UrlImageView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public UrlImageView(Context context, AttributeSet attrs) { super(context, attrs); } public UrlImageView(Context context) { super(context); } @Override public void setImageBitmap(Bitmap bm) { cancelLoading(); super.setImageBitmap(bm); } @Override public void setImageDrawable(Drawable drawable) { cancelLoading(); super.setImageDrawable(drawable); } @Override public void setImageResource(int resId) { cancelLoading(); super.setImageResource(resId); } @Override public void setImageURI(Uri uri) { cancelLoading(); super.setImageURI(uri); } /** * loads image from given url * * @param url */ public void setImageURL(URL url) { synchronized (loadingMonitor) { cancelLoading(); this.currentLoadingTask = new UrlLoadingTask(this).execute(url); } } /** * cancels pending image loading */ public void cancelLoading() { synchronized (loadingMonitor) { if (this.currentLoadingTask != null) { this.currentLoadingTask.cancel(true); this.currentLoadingTask = null; } } } } 

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

 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) { ... } 

Попробуйте этот код, сделайте свою гибкую переменную глобальной и измените свою спутниковую функцию следующим образом:

 private void satellite() { // TODO Auto-generated method stub ImageView imgView =(ImageView)findViewById(R.id.satellite); new yourTask().execute(); } 

Затем создайте класс asyncTask следующим образом:

 private class yourTask extends AsyncTask<Integer, Void, Integer> { @Override protected void onPreExecute() { super.onPreExecute(); //show a progress bar } @Override protected String doInBackground(Integer... params) { drawable = LoadImageFromWeb("http://www.pagasa.dost.gov.ph/wb/sat_images/satellite.gif"); return 0; } @Override protected void onPostExecute(Integer result) { super.onPostExecute(result); imgView.setImageDrawable(drawable); } } 

Вот код для реализации Aynctask. Сделайте свой вытачиваемый объект глобальным в классе Aynctask.

 Class MyDownloader extends AsyncTask<Void,Void,String>{ Drawable drawable; @Override public String doInBackground(Void... args){ drawable = LoadImageFromWeb("http://www.pagasa.dost.gov.ph/wb/sat_images/satellite.gif"); return null; // here you can pass any string on response as on error or on success } public void onPostExecute(String result){ if(drawable!=null){ imgView.setImageDrawable(drawable); } } } 

Теперь создаем объект этого класса и выполняем его

 private void satellite() { // TODO Auto-generated method stub ImageView imgView =(ImageView)findViewById(R.id.satellite); new MyDownloader.execute(); } 

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

https://github.com/novoda/ImageLoader

Вы правы, когда вы выполняете какую-либо операцию в сети позднее. Android 2.2(Froyo) Должен использовать Asynctask

Это лучший пример для понимания AsyncTask

Основанный на ответе от comeGetSome, я создал свою собственную реализацию, которая работает с обычным классом ImageView вместо создания нового класса UrlImageView, а также новые параметры, такие как: что делать, когда загрузка завершается или отменяется

Теперь загрузите изображение так, как хотите, например, из любого из трех методов loadImage

  UrlImageLoader urlImageLoader=new UrlImageLoader(); ImageView imageView=new ImageView(context); //load and set the image to ImageView urlImageLoader.loadImage(imageView, "http://www......com/.....jpg"); //for loading a image only - load image and do any thing with the bitmap urlImageLoader.loadImage("http://www......com/.....jpg", new UrlImageLoader.OnLoadingCompleteListener() { @Override public void onComplete(ImageView imageView, Bitmap bmp) { // do anything with the Bitmap // here imageView will be null } @Override public void onCancel(ImageView imageView) { } }); urlImageLoader.loadImage(imageView, "http://www......com/.....jpg", new UrlImageLoader.OnLoadingCompleteListener() { @Override public void onComplete(ImageView imageView, Bitmap bmp) { // do anything with the Bitmap // here imageView is not null imageView.setImageBitmap(bmp); } @Override public void onCancel(ImageView imageView) { } }); 

Создайте этот класс для загрузки UrlImageLoader

 /*special thanks to stackoverflow.com user comeGetSome for UrlImageLoadingTask code * question - http://stackoverflow.com/questions/14332296/how-to-set-image-from-url-using-asynctask/15797963 * comeGetSome - http://stackoverflow.com/users/1005652/comegetsome */ package com.GameG.SealTheBox; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.util.Log; import android.widget.ImageView; public class UrlImageLoader { public static interface OnLoadingCompleteListener { public void onComplete(ImageView imageView, Bitmap bmp); public void onCancel(ImageView imageView); } ArrayList<UrlImageLoadingTask> loadingList=new ArrayList<UrlImageLoadingTask>(); /** * Loads a image from url and calls onComplete() when finished<br> * @Note you should manually set the loaded image to ImageView in the onComplete() * @param imageView * @param url * @param onComplete */ public void loadImage(ImageView imageView, String url, OnLoadingCompleteListener onComplete){ try { URL url2=new URL(url); if(imageView!=null){ for(int i=0;i<loadingList.size();i++){ UrlImageLoadingTask tmptask=loadingList.get(i); if(tmptask.updateView!=null && tmptask.updateView.equals(imageView)){ tmptask.cancel(true); break; } } } UrlImageLoadingTask loadtask=new UrlImageLoadingTask(imageView,onComplete,url); loadtask.execute(url2); } catch (MalformedURLException e) { e.printStackTrace(); } } /** * Loads a image from url and calls onComplete() when finished * @param url * @param onComplete */ public void loadImage(String url, OnLoadingCompleteListener onComplete){ loadImage(null,url,onComplete); } /** * Loads a image from url and sets the loaded image to ImageView * @param imageView * @param url */ public void loadImage(ImageView imageView, String url){ loadImage(imageView,url,null); } /** * Cancel loading of a ImageView */ public void cancel(ImageView imageView){ for(int i=0;i<loadingList.size();i++){ UrlImageLoadingTask tmptask=loadingList.get(i); if(tmptask.updateView.equals(imageView)){ loadingList.remove(i); tmptask.cancel(true); break; } } } /** * Cancel loading of a Url */ public void cancel(String url){ for(int i=0;i<loadingList.size();i++){ UrlImageLoadingTask tmptask=loadingList.get(i); if(tmptask.url.equals(url)){ loadingList.remove(i); tmptask.cancel(true); break; } } } /** * Cancel all loading tasks */ public void cancelAll(){ while(loadingList.size()>0){ UrlImageLoadingTask tmptask=loadingList.get(0); loadingList.remove(tmptask); tmptask.cancel(true); } } private class UrlImageLoadingTask extends AsyncTask<URL, Void, Bitmap> { public ImageView updateView=null; public String url; private boolean isCancelled = false; private InputStream urlInputStream; private OnLoadingCompleteListener onComplete=null; private UrlImageLoadingTask(ImageView updateView, OnLoadingCompleteListener onComplete, String url) { this.updateView=updateView; this.onComplete=onComplete; this.url=url; } @Override protected Bitmap doInBackground(URL... params) { try { URLConnection con = params[0].openConnection(); // can use some more params, ie caching directory etc con.setUseCaches(true); this.urlInputStream = con.getInputStream(); return BitmapFactory.decodeStream(urlInputStream); } catch (IOException e) { Log.w(UrlImageView.class.getName(), "failed to load image from " + params[0], e); return null; } finally { if (this.urlInputStream != null) { try { this.urlInputStream.close(); } catch (IOException e) { ; // swallow } finally { this.urlInputStream = null; } } } } @Override protected void onPostExecute(Bitmap result) { if (!this.isCancelled) { // hope that call is thread-safe if(onComplete==null){ if(updateView!=null) this.updateView.setImageBitmap(result); }else{ onComplete.onComplete(updateView, result); } } loadingList.remove(this); } /* * just remember that we were cancelled, no synchronization necessary */ @Override protected void onCancelled() { this.isCancelled = true; try { if (this.urlInputStream != null) { try { this.urlInputStream.close(); } catch (IOException e) { ;// swallow } finally { this.urlInputStream = null; } } } finally { super.onCancelled(); if(onComplete!=null) onComplete.onCancel(updateView); loadingList.remove(this); } } } } в /*special thanks to stackoverflow.com user comeGetSome for UrlImageLoadingTask code * question - http://stackoverflow.com/questions/14332296/how-to-set-image-from-url-using-asynctask/15797963 * comeGetSome - http://stackoverflow.com/users/1005652/comegetsome */ package com.GameG.SealTheBox; import java.io.IOException; import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.ArrayList; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.AsyncTask; import android.util.Log; import android.widget.ImageView; public class UrlImageLoader { public static interface OnLoadingCompleteListener { public void onComplete(ImageView imageView, Bitmap bmp); public void onCancel(ImageView imageView); } ArrayList<UrlImageLoadingTask> loadingList=new ArrayList<UrlImageLoadingTask>(); /** * Loads a image from url and calls onComplete() when finished<br> * @Note you should manually set the loaded image to ImageView in the onComplete() * @param imageView * @param url * @param onComplete */ public void loadImage(ImageView imageView, String url, OnLoadingCompleteListener onComplete){ try { URL url2=new URL(url); if(imageView!=null){ for(int i=0;i<loadingList.size();i++){ UrlImageLoadingTask tmptask=loadingList.get(i); if(tmptask.updateView!=null && tmptask.updateView.equals(imageView)){ tmptask.cancel(true); break; } } } UrlImageLoadingTask loadtask=new UrlImageLoadingTask(imageView,onComplete,url); loadtask.execute(url2); } catch (MalformedURLException e) { e.printStackTrace(); } } /** * Loads a image from url and calls onComplete() when finished * @param url * @param onComplete */ public void loadImage(String url, OnLoadingCompleteListener onComplete){ loadImage(null,url,onComplete); } /** * Loads a image from url and sets the loaded image to ImageView * @param imageView * @param url */ public void loadImage(ImageView imageView, String url){ loadImage(imageView,url,null); } /** * Cancel loading of a ImageView */ public void cancel(ImageView imageView){ for(int i=0;i<loadingList.size();i++){ UrlImageLoadingTask tmptask=loadingList.get(i); if(tmptask.updateView.equals(imageView)){ loadingList.remove(i); tmptask.cancel(true); break; } } } /** * Cancel loading of a Url */ public void cancel(String url){ for(int i=0;i<loadingList.size();i++){ UrlImageLoadingTask tmptask=loadingList.get(i); if(tmptask.url.equals(url)){ loadingList.remove(i); tmptask.cancel(true); break; } } } /** * Cancel all loading tasks */ public void cancelAll(){ while(loadingList.size()>0){ UrlImageLoadingTask tmptask=loadingList.get(0); loadingList.remove(tmptask); tmptask.cancel(true); } } private class UrlImageLoadingTask extends AsyncTask<URL, Void, Bitmap> { public ImageView updateView=null; public String url; private boolean isCancelled = false; private InputStream urlInputStream; private OnLoadingCompleteListener onComplete=null; private UrlImageLoadingTask(ImageView updateView, OnLoadingCompleteListener onComplete, String url) { this.updateView=updateView; this.onComplete=onComplete; this.url=url; } @Override protected Bitmap doInBackground(URL... params) { try { URLConnection con = params[0].openConnection(); // can use some more params, ie caching directory etc con.setUseCaches(true); this.urlInputStream = con.getInputStream(); return BitmapFactory.decodeStream(urlInputStream); } catch (IOException e) { Log.w(UrlImageView.class.getName(), "failed to load image from " + params[0], e); return null; } finally { if (this.urlInputStream != null) { try { this.urlInputStream.close(); } catch (IOException e) { ; // swallow } finally { this.urlInputStream = null; } } } } @Override protected void onPostExecute(Bitmap result) { if (!this.isCancelled) { // hope that call is thread-safe if(onComplete==null){ if(updateView!=null) this.updateView.setImageBitmap(result); }else{ onComplete.onComplete(updateView, result); } } loadingList.remove(this); } /* * just remember that we were cancelled, no synchronization necessary */ @Override protected void onCancelled() { this.isCancelled = true; try { if (this.urlInputStream != null) { try { this.urlInputStream.close(); } catch (IOException e) { ;// swallow } finally { this.urlInputStream = null; } } } finally { super.onCancelled(); if(onComplete!=null) onComplete.onCancel(updateView); loadingList.remove(this); } } } } 

Просто создайте новый класс « DownloadImageTask », как и следующий, и поместите его в ту же папку, где у вас есть свое действие.

 import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.Log; import android.widget.ImageView; import android.os.AsyncTask; import java.io.*; public class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { ImageView bmImage; public DownloadImageTask(ImageView bmImage) { this.bmImage = bmImage; } protected Bitmap doInBackground(String... urls) { String urldisplay = urls[0]; Bitmap myImage = null; try { InputStream in = new java.net.URL(urldisplay).openStream(); myImage = BitmapFactory.decodeStream(in); } catch (Exception e) { Log.e("Error", e.getMessage()); e.printStackTrace(); } return myImage; } protected void onPostExecute(Bitmap result) { bmImage.setImageBitmap(result); } } 

После этого добавьте строку, чтобы отобразить этот класс в вашей деятельности .

 import android.graphics.Bitmap; import android.os.AsyncTask; import android.support.v7.app.ActionBarActivity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.util.Log; import android.widget.ImageView; public class HomeScreen extends ActionBarActivity { private final String TAG = "test1"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.d(TAG, "onCreate"); setContentView(R.layout.activity_home_screen); InitHomeScreen(); } protected void InitHomeScreen() { String imageUrl = "http://s20.postimg.org/4t9w2pdct/logo_android_png.png"; Log.d(TAG, "Get an Image"); // Get an Image try{ AsyncTask<String, Void, Bitmap> execute = new DownloadImageTask((ImageView) findViewById(R.id.imageView)) .execute(imageUrl); // R.id.imageView -> Here imageView is id of your ImageView } catch(Exception ex) { } } // Other code... 

Не забудьте разрешить доступ к Интернету в Android-приложение.

Проверьте файл манифеста.

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.dmitry.myapplication1" > <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".HomeScreen" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>