请我阅读很多东西,因为我读了不同的意见和不同的方法,我感到很困惑.
问题如下:
在AdapterI的getView()中,需要执行一些异步操作,比如检查Web上的格式,并基于此更新视图.
我使用了以下方法:
每次调用getView()时我都会启动一个Thread
但我的做法为我赢得了很多批评:
https://stackoverflow.com/a/28484345/1815311
https://stackoverflow.com/a/28484335/1815311
https://stackoverflow.com/a/28484351/1815311
public View getView(int position,View convertView,ViewGroup parent) { ViewHolder holder; if (convertView == null) { //... } else { //... } Thread th= new Thread(new Runnable() { @Override public void run() { mActivity.runOnUiThread(new Runnable() { @Override public void run() { CheckSomeInfoOverTheInternet(url,new myCallback { @Override public void onSuccess() { holder.textview.setText("OK"); } @Override public void onFailre() { holder.textview.setText("NOT OK!!!!"); } }); } }); } }); th.start(); return convertView; }
请问做这样事情的最佳做法是什么?
解决方法
虽然你在做什么真的不合适.
>此处的线程池是在内部完成的,因此您无需为此烦恼
>它可以更清晰地解决您的问题而不是产生单个线程.
>如果您的用户在API通话期间更改了屏幕,您也可以使用cancel the call.
>您必须启用notifyDatasetChanged()
>您需要覆盖很少的函数来实现所需的功能.
>它为您提供了更多控制权,但您却失去了几个隐式定义的函数
>你需要更多的知识来使用它,并且应该精通像LoaderManager,Loader这样的类.
>改变就是自我改变
假设您要更改基础数据集,更改将自动触发并提供对UI的更改.
> Handlers和线程
>这比你当前的appraoch高出一个但是提供了更多的好处
>您可以抽象线程创建并提供处理所有id的调用的处理程序.
>您可以对线程和传递的消息进行排队.
>如果屏幕改变,你可以remove callbacks and messages.
总之,您当前方法的主要缺点是:
– 需要进行更改时丢失上下文.
– 显式创建多个线程
虽然后者是一个主要问题,但首先是“用户更明显”的问题.
基于您需要的控件以及您在Android回调和线程管理方面的专业知识,可能还有其他几种方法.但这三种方法(据我所知)最合适.
PS:所有这些方法的共同点是,
public View getView(int position,ViewGroup parent) { ViewHolder holder; if (convertView == null) { //... } else { //... } //execute a task for your given id where task could be: //1. AsyncTask //2. AsyncTaskLoader //3. Handlers and thread //call notifyDataSetChanged() in all the cases,return convertView; } @Override public void notifyDataSetChanged() { super.notifyDataSetChanged(); //do any tasks which you feel are required }
PPS:您还可以查看DataSetObserver以再次自动化您的要求.