2012-09-18 97 views
2

我正在探索Android开发人员网站并阅读一些文章。目前使用的AsyncTask列表视图defering图像加载的一种方式:制作ListView滚动平滑

// Using an AsyncTask to load the slow images in a background thread 
new AsyncTask<ViewHolder, Void, Bitmap>() { 
    private ViewHolder v; 

    @Override 
    protected Bitmap doInBackground(ViewHolder... params) { 
     v = params[0]; 
     return mFakeImageLoader.getImage(); 
    } 

    @Override 
    protected void onPostExecute(Bitmap result) { 
     super.onPostExecute(result); 
     if (v.position == position) { 
      // If this item hasn't been recycled already, hide the 
      // progress and set and show the image 
      v.progress.setVisibility(View.GONE); 
      v.icon.setVisibility(View.VISIBLE); 
      v.icon.setImageBitmap(result); 
     } 
    } 
}.execute(holder); 

但是,对我来说,似乎有与该代码有点问题。假设我们从互联网加载图像,并且每个图像都需要几秒钟才能加载。

作为一个用户,如果我们滚动列表然后切换到另一个活动,会有一些AsyncTasks在后台运行,并占用一些带宽,而我们可能需要它在我们的新前台活动中。

你通常如何使用他们的方法来处理这种情况?回收视图时,你是否杀掉了与持有人相关的AsyncTask?你是否跟踪哪些AsyncTasks仍在运行的适配器,并在活动停止时将其全部取消?还有其他的方式吗?

我的问题主要是关于architecturing清洗件来解决这个问题(没有这么多的实现)

回答

2

我要说的是,大多数时间下载不采取足够的时间让这成为一个问题,但如果它应该杀死它们。同样在他们的实现中,他们下载一个图像并检查视图是否被重用。如果你有很长时间的延迟,你应该在重新使用时取消任务。请注意,Android版本的任务执行顺序不同。从docs

第一次引入时,AsyncTasks在单个后台线程上被串行执行。从DONUT开始,将其更改为允许多个任务并行操作的线程池。从HONEYCOMB开始,任务在单个线程上执行,以避免并行执行导致的常见应用程序错误。

如果您真的想要并行执行,可以使用THREAD_POOL_EXECUTOR调用executeOnExecutor(java.util.concurrent.Executor,Object [])。

+0

单独采取,下载可能需要一秒钟,但如果您获得了100个项目的列表或网格......您是否只在项目显示时才下载?如果你在扔东西呢? –

+0

根据要求可以有各种各样的变化。您应该看一个有趣的示例是:http://androidxref.com/4.1.1/xref/development/samples/ApiDemos/src/com/example/android/apis/view/List13.java如果没有加载滚动时完成。您当然也可以将数据缓存在后台线程(可能包含在服务中),无论是闪存还是RAM。还有一些LruCache(http://developer.android.com/reference/android/support/v4/util/LruCache.html)可能会对这些问题感兴趣。 –