Android Loaders(一)概述

来源:互联网 发布:销售报表数据分析 编辑:程序博客网 时间:2024/06/10 04:59

Android Loaders(一)概述

转载请注明:http://blog.csdn.net/liaoqianchuan00/article/details/24094575

参考翻译自:https://docs.google.com/presentation/d/1_5puFz6kUK1cSYvTmJbvQFYpgj8LXZECBrn65w62UKk/edit#slide=id.p

 

从Thread到Loader

Thread

final Handler handler = new Handler(newHandler.Callback() {
      
       @Override
       public booleanhandleMessage(Message msg) {
              switch(msg.what) {
                     case RESULT_WHAT:
                            handleResult((Result)msg.obj);
                            return true;
              }
              return false;
       }
});

Thread thread = new Thread(new Runnable() {

       @Override
       public void run() {
              Result result = doStuff();
              if (isResumed()) {
                     handler.sendMessage(handler.obtainMessage(RESULT_WHAT,result));
              }
       }    
});
thread.start();

 

不方便:

1.       需要你自己将结果postUI线程。

2.       必须自己手动处理Cancellation

3.       想要用线程池?你需要自己去实现。

 

AsyncTask

1.       帮你处理了线程间的切换(即将结果post到主线程,你只需要实现他得回调)。

2.       帮你处理了cancellation:如果你调用的cancel(),那么onPostExecute不会执行(当还没有到这一步的时候就不会执行了)。

3.       可以更新进度条

 

final Handler handler = new Handler(newHandler.Callback() {
      
       @Override
       public booleanhandleMessage(Message msg) {
              switch(msg.what) {
                     case RESULT_WHAT:
                            handleResult((Result)msg.obj);
                            return true;
              }
              return false;
       }
});

Thread thread = new Thread(new Runnable() {

       @Override
       public void run() {
              Result result = doStuff();
              if (isResumed()) {
                     handler.sendMessage(handler.obtainMessage(RESULT_WHAT,result));
              }
       }    
});
thread.start();

 

问题:

1.       你需要保持一个对Activity的引用,然后再你的Activity的被销毁的时候来cancel这个任务。

2.       内存泄露:只要AsyncTask在运行,他就保持了一个对外部Activity的引用,虽然这个时候Activity已经销毁了(我们之前介绍过可以用静态内部类和WeakReference来解决,还可以用一个没有界面的Fragment来作AsyncTask的事情)。

3.       Activity已经被重新创建后(比如旋转屏幕),之前AsyncTask取得的数据已经不在了。

 

需要知道的重点:

1.       1.6之前,所有的AsyncTask在一个单独的线程中有序的执行。

2.       1.62.3,这些AsyncTask在一个线程池中执行,但是有上限。

3.       3.0开始,又使用最早的方案!他们在一个单独的线程中有序的执行,除非你调用executeOnExecutor,并且传入一个ThreadPoolExecutor

解决方法:

publicclass ConcurrentAsyncTask {   

  public static void execute(AsyncTask as) {

         if (Build.VERSION.SDK_INT <Build.VERSION_CODES.HONEYCOMB) {

                as.execute();

         } else {

                as.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);

         }

  }

}

 

Loader

                              

特性:

1.       允许一个Activity或者Fragment连接到Activity或者Loader被重新创建之前的Loader,并且重新取出里面的result

2.       如果resultLoaderActivity/Fragmentdisconnected之后才得到,那么它会被保存在cache中,并且在Activity/Fragemtneon被重新创建之后传送回来。

3.       Loader可以监控他得数据源,在数据源数据变化后将新的数据deliver出来。

4.       Loader处理了result相关的资源的allocation/disallocation(比如Cursors)。

 

如果你想在一个Activity或者Fragment里面进行异步数据的加载,不要再使用AsyncTask了。

也不要认为Loader只是用来做数据库相关的事情(CursorLoaders),他可以做很多事情。

0 0
原创粉丝点击