在后台线程中获取位图流

时间:2015-04-09 05:24:51

标签: android multithreading bitmap runnable

我有ListView显示从服务器下载的图像。我需要执行的步骤是:

  1. 调用api获取流。
  2. 从该流中获取bytes []。
  3. 将这些字节保存在File对象中(在SD卡内)。
  4. 从该文件路径/位置获取位图。
  5. 在ImageView中显示位图。
  6. 前4个步骤需要在后台线程中执行,以保持主线程未被占用,以便用户可以在后台下载图像时平滑地滚动列表。需要在UI线程上执行第5步。

    我在后台执行这些步骤时遇到了麻烦。

    这是我在从图像下载api获得成功响应后尝试在后台执行上述4个步骤的方法。

    Thread thread = new Thread(new Runnable() {
                    public void run() {
                        try {
                            // Get bytes from Response
                            byte[] bytes = getBytesFromStream(response.getBody().in());
                            // Save bytes in phone sd card
                            saveBytesToFile(bytes, photoPath);
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            // Get bitmap from path
                            Bitmap webBitmap = getBitmap(photoPath);
                            // Show bitmap
                            showBitmap(webBitmap);
                        }
                    }
                });
    
                thread.start();
    
    
    private void showBitmap(Bitmap bitmap) {
        BitmapDisplayer bd = new BitmapDisplayer(bitmap, photoToLoad);
        Activity a = (Activity) photoToLoad.imageView.getContext();
        a.runOnUiThread(bd);
    }
    

    getBytesFromStream()方法从流中提取字节并返回它们。 saveBytesToFile()方法将这些字节保存在File对象(SD卡)中。 getBitmap()方法从特定路径获取位图。 showBitmap()方法在ImageView上显示位图。

    现在我的问题是:

    1. 我做得对吗?

    2. 在Android中后台线程中执行某些操作的最佳方法是什么?

    3. 我认为上面的代码仍然阻塞主线程,因此我无法顺利滚动列表。如何正确执行这些步骤?

    4. 请帮帮我。

2 个答案:

答案 0 :(得分:0)

请改用Picasso。在listview的适配器中执行以下操作:

@Override 
public void getView(int position, View convertView, ViewGroup parent) {
      //
      // Other codes
      //

      Picasso.with(context).load(string_url).into(imageview);
    }

答案 1 :(得分:0)

  1. 理论上,你的5个步骤是正确的。
  2. 基本上,简单的方法是AsyncTask,使用Thread是可以的,但是当您需要经常进行后台工作时,您可能需要尝试一些线程策略,例如Executor来重用线程。
  3. 至于有效地获取加载图像,并不像你的5个步骤那么简单,你应该考虑更多的事情,比如在第一次下载后在磁盘上缓存图像,在内存中缓存一些最近加载的位图并管理它们。和滚动一样。尝试在用户滚动列表时加载图像并始终加载“右”(避免加载已经滚动和不可见的图像)ImageView也非常重要。
  4. 最后,smootheuniversal image loader是关于图像异步加载的好库。您可以参考它们并制定自己的政策。