2010-06-22 50 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