【问题标题】:Android: best way to load images in backgroundAndroid:在后台加载图像的最佳方式
【发布时间】:2011-07-17 11:22:23
【问题描述】:

对于我的自定义列表视图,我使用 AsyncTask 进行 Web 服务调用,它工作正常。 我的列表视图有一个左侧图像、标题、描述。该服务将返回 (url, title, desc) 的列表。

在我的适配器中,我正在使用以下代码加载图像:

httpClient = new DefaultHttpClient(); HttpGet 请求 = 新的 HttpGet(url); 响应 = httpClient.execute(request); InputStream 是 = response.getEntity().getContent(); Drawable drawable = Drawable.createFromStream(is, "src"); imgView.setImageDrawable(drawable);

但是在加载所有图像之前我无法看到列表视图,我知道我正在阻塞 UI 线程,任何人都可以建议在没有 UI 阻塞的情况下执行此操作的最佳方法。

谢谢, 文卡特帕帕纳

【问题讨论】:

标签: android


【解决方案1】:

这是更好的方法,只是尝试.. 这是用于在 cardview 中加载图像

private class LoadImage extends AsyncTask<String, String, Bitmap> {
    Bitmap bitmap1 = null;
    CurrentVehicleStatus currentVehicleStatus;

    int i;
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        //Stuff on preexecute

        pDialog = new ProgressDialog(AdminActivity.this);
        pDialog.setTitle("Please wait");
        pDialog.setMessage("Loading data..");
        pDialog.show();

    }
    protected Bitmap doInBackground(String... args) {

           for(int i=0;i<arrayLength;i++) {
          //Your class reference that store your values for adapter
          yourClassReference = yourArrayList.get(i);

            try {
                bitmap = BitmapFactory.decodeStream((InputStream) new URL("Your URL"
                ).getContent());

            } catch (Exception e) {
                e.printStackTrace();
            }
    //this setImage method in data class
      yourArrayList.get(i).setImage(bitmap);

         }

        }


        return bitmap1;
    }

    protected void onPostExecute(Bitmap image) {

        pDialog.dismiss();
    //Notify adapter
        mAdapter.notifyDataSetChanged();

    }
}

有什么疑问可以评论我

【讨论】:

    【解决方案2】:

    使用AsyncTaskThreadHandler,就像上面的答案已经指出的那样。

    这是从 URL 获取图像资源的快速方法:

    BitmapDrawable bitmapDrawable = new BitmapDrawable(BitmapFactory.decodeStream(new URL("http://example.com/path/to/image/file.jpg").openStream()));
    

    创建 1 个AsyncTask,并在doInBackground 中循环遍历所有图像 URL,并将每个生成的可绘制对象添加到图标列表或其他内容中

    【讨论】:

      【解决方案3】:

      也使用AsyncTask 来加载图片。对于每个加载的图像,您可以从doInBackground() 调用publishResults(),然后让onProgressUpdate() 将图像放在正确的位置。

      【讨论】:

      • 谢谢 Heiko,但是当我浏览 AsyncTask 文档时,他们提到我们只能调用 AsyncTask 的执行一次;但在我的要求中,我需要多次调用 AsyncTask。我该怎么办?
      • 每次使用一个新的 AsyncTask for (int i = 0 ; i
      • 嗨 Heiko,我们如何在 onPostExecute() 方法中识别特定的 AsyncTask,例如,如果 (new MyAsyncTaks()).execute(5) 先完成执行,那么如何更新第 5 个列表项目的图像视图?
      • 您可以在 AsyncTask ( new MyAsyncTask(iv).execute() ) 的构造函数中传递相应的图像视图 - 或者当您想要处理多个图像时,在构造函数,然后在 AsyncTask 的 doInBackground 中迭代它们
      【解决方案4】:
      new Thread(new Runnable() {
      
                                 @Override
                                 public void run() {
      
                                             httpClient = new DefaultHttpClient(); 
                                             HttpGet request = new HttpGet(url);         
                                             response = httpClient.execute(request);
                                             InputStream is =  response.getEntity().getContent();
                                           msg.obj=is;
                                         mHandler.sendMessage(msg);
                                 }
                         }).start();
      

      你的手柄会是这样的

      mHandler = new Handler() { 
                    @Override public void handleMessage(Message msg) { 
                       InputStream is=(InputStream)msg.obj;
                       Drawable drawable = Drawable.createFromStream(is, "src");
                       imgView.setImageDrawable(drawable);
      
                    }
                };
      

      【讨论】:

      • 谢谢 Sunil,我需要在列表活动的数组适配器中创建这个新线程,所以我需要根据列表元素创建线程数,在这种情况下我怎么知道哪条消息与特定线程相关..?
      猜你喜欢
      • 2016-09-08
      • 2014-10-19
      • 2011-09-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-17
      相关资源
      最近更新 更多