2010-06-22 49 views
31

如何更換的代碼用的AsyncTask以下行? 你如何從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; 
    //--------------------------------------------------- 
} 


} 

,但我如何通過在onPostExecute(位圖結果)mChart參考??? 我需要以某種方式將URL傳遞給URL嗎? 我想取代我的所有代碼行:

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

有類似的東西...但在這樣的AsyncTask!

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

有沒有簡單的解決方案呢? 我在這裏遇到什麼問題嗎?

+0

很基本的問題,但將是有益的許多beginers像我一樣,我認爲...請發佈一些代碼,如果你有。 – Hubert 2010-06-22 06:13:01

+0

相關:[ImageDownloader示例](http://developer.android.com/resources/samples/XmlAdapters/src/com/example/android/xmladapters/ImageDownloader.html) – idbrii 2011-07-14 21:23:27

+0

@Hubert可以提及私人位圖download_Image( String url){ ... }這段代碼? – Erum 2015-03-27 12:48:38

回答

65

如果沒有很好的理由來下載自己,那麼我會建議使用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中的標籤是有點棘手,但如果你有很多imageviews的,它看起來在調用的類更好的是你想填補這一點。如果您在ListView中使用ImageView並且想要知道在下載圖像期間ImageView是否被回收,它也會有所幫助。

我寫的,如果你的圖片是不是大,因爲這將導致其造成的垃圾收集,直到任務完成,以保留在內存中的整個活動一個隱含的指針,底層活動的任務。如果用戶在下載位圖時移動到應用程序的另一個屏幕,則無法釋放內存,並且可能會讓您的應用程序和整個系統變得更慢。

+0

我的圖像是類似於45.2 Ko(46,384個八位字節)gif類型,如果這有什麼區別? – Hubert 2010-06-22 07:07:13

+0

它只是一個問題,如果它需要更長的時間,那麼我猜20秒下載圖像,你的活動是沉重的系統內存。 – Janusz 2010-06-22 10:25:12

+0

謝謝Janusz,我用一些附加的東西編輯了我的問題。你怎麼看 ?事實上,我想在不同的ImageViews上使用這個AsyncTask。如何將正確的引用傳遞給onPostExecute中的ImageView?非常感謝您的幫助。 – Hubert 2010-06-22 10:40:20

0

這將讓你任意大小的圖片... 如果您不希望進度對話框只是評論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 
} 
+1

謝謝你的提議Umesh。也許的確我也應該添加一個ProgressDialog,以防萬一!但是,如何將上下文(FileExplorer.this)傳遞給AsyncTask呢?我希望我的DownloadImagesTask()可以從我的應用程序的任何活動中訪問......我爲它創建了一個單獨的類。 – Hubert 2010-06-22 12:07:22

1

你可以創建一個類say..BkgProcess,它包含一個擴展AsyncTask的內部類。而實例化BkgProcess會在BkgProcess構造函數中傳遞Activity類的上下文。對於如:

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(); 
18

試試這個代碼:

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; 
    } 
} 
+0

'return download_Image((String)imageView.getTag());'給出錯誤。 'getTag必須從UI線程調用' – XoXo 2017-09-06 06:46:56