Android:在getView()中执行异步操作的最佳实践

请不要关闭这个,恕我直言这是体面的,可能有用的编程问题.

请我阅读很多东西,因为我读了不同的意见和不同的方法,我感到很困惑.

问题如下:

在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;
}

请问做这样事情的最佳做法是什么?

请注意,我不是在寻找在getView()中执行网络请求的解决方案,而是如何根据异步调用的结果更新视图.

解决方法

有几个appraoches为此.
虽然你在做什么真的不合适.

> AsyncTask

>此处的线程池是在内部完成的,因此您无需为此烦恼
>它可以更清晰地解决您的问题而不是产生单个线程.
>如果您的用户在API通话期间更改了屏幕,您也可以使用cancel the call.
>您必须启用notifyDatasetChanged()
>您需要覆盖很少的函数来实现所需的功能.

> AsyncTaskLoader

>它为您提供了更多控制权,但您却失去了几个隐式定义的函数
>你需要更多的知识来使用它,并且应该精通像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以再次自动化您的要求.

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...