是否存在Android AsyncTaskQueue或类似内容?

时间:2010-06-12 18:28:59

标签: android

我在某处读过(并观察过)启动线程很慢。我总是假设AsyncTask创建并重用了一个线程,因为它需要在UI线程内启动。

从ListAdapter的getView方法调用以下(匿名)代码,以异步方式加载图像。它很有效,直到用户快速移动列表,然后变为“janky”。

final File imageFile = new File(getCacheDir().getPath() + "/img/" + p.image);
image.setVisibility(View.GONE);
view.findViewById(R.id.imageLoading).setVisibility(View.VISIBLE);
(new AsyncTask<Void, Void, Bitmap>() {
    @Override
    protected Bitmap doInBackground(Void... params) {
        try {
            Bitmap image;
            if (!imageFile.exists() || imageFile.length() == 0) {
                image = BitmapFactory.decodeStream(new URL(
                        "http://example.com/images/"
                                + p.image).openStream());
                image.compress(Bitmap.CompressFormat.JPEG, 85,
                        new FileOutputStream(imageFile));
                image.recycle();
            }
            image = BitmapFactory.decodeFile(imageFile.getPath(),
                bitmapOptions);
            return image;
        } catch (MalformedURLException ex) {
            // TODO Auto-generated catch block
            ex.printStackTrace();
            return null;
        } catch (IOException ex) {
            // TODO Auto-generated catch block
            ex.printStackTrace();
            return null;
        }
    }

    @Override
    protected void onPostExecute(Bitmap image) {
        if (view.getTag() != p) // The view was recycled.
            return;
            view.findViewById(R.id.imageLoading).setVisibility(
                View.GONE);
        view.findViewById(R.id.image)
                .setVisibility(View.VISIBLE);
        ((ImageView) view.findViewById(R.id.image))
                .setImageBitmap(image);
    }
}).execute();

我认为基于队列的方法会更好用,但我想知道是否有一个或者我是否应该尝试创建自己的实现。

2 个答案:

答案 0 :(得分:1)

示例List13.java

中说明了该密钥

基本上你必须跟踪listView的滚动状态并通知 当适配器准备好与刚刚可见时做一些缓慢的事情时 项目

另请注意,将图像保存到磁盘是一个非常缓慢的过程。用一个 基于内存的缓存策略可以提高你的性能 应用。

答案 1 :(得分:1)

  1. 我可以看到您解码图像并将其压缩回磁盘,之后再次对其进行解码。我认为不是很有效。您可以将流从网络保存到磁盘,然后解压缩。这只是一次解压缩而不是3次压缩/解压缩。将为您节省大量的CPU处理时间。

  2. 我认为AsyncTask会为多个图像创建多个线程。因此,几个图像同时被压缩/解压缩,几个线程争夺CPU时间,不是很好。据我所知,AsyncTask使用线程池,因此它不会为每个图像启动新线程。但无论如何,同时几个线程并不是那么好。我同意队列会更有效。实现并不是很难自己创建它。我使用自己的队列实现,我很满意。

  3. 如果你有自己的主题,我认为可以给它一个较低的优先级。这将使UI更具响应性。

  4. 您当然需要某种内存缓存,否则UI不够快。解压缩很慢。您不能存储所有图像,只能存储最常用的图像。您可以使用SoftReference进行缓存实现。您可以使用inSampleSize选项使您的位图更小并占用更少的内存Strange out of memory issue while loading an image to a Bitmap object

  5. 我做了一个完整的LazyList示例并发布了源代码,也可能有用Lazy load of images in ListView