Android异步处理之AsyncTaskLoader简单使用
2015-09-21 10:53
507 查看
简介
不管是在Android应用开发还是Android平台开发中,异步处理通常是最基本的coding要求。如果你还在主线程中写一些数据库,网络请求,读写本地文件等操作的话那说明你还不是一个合格的Android程序员。通常情况下我们使用的最多的Android异步处理方法是
AsyncTask和
Handler,但今天要给大家带来的是大家不常使用的
AsyncTaskLoader的使用方法。
AsyncTaskLoader从名字看出来它似乎和
AsyncTask有关系,看一下Google官方是怎么给
AsyncTaskLoader下定义的:
Abstract Loader that provides an AsyncTask to do the work
果然是样,
AsyncTaskLoader是使用一个
AsyncTask来进行异步处理的。那么问题来了,既然都有了
AsyncTask了为什么还要搞出来一个
AsyncTaskLoader呢?
其实
AsyncTaskLoader远没有大家想的那么简单。说的通俗一点,如果把
AsyncTask比作一台烤面包机的话,那么
AsyncTaskLoader就是操作烤面包机的面包师。
AsyncTask如同烤面包机接受命令完成面包的烤制任务,一旦任务完成它就停止了工作。然而
AsyncTaskLoader如同面包师一样要根据顾客的需求来使用烤面包机。顾客会不停的光顾,那么面包师就会不停的使用烤面包机烤面包。
具体事例
下面我们就通过烤面包机和面包师的例子来演示一下AsyncTaskLoader的使用方法。
首先肯定少不了面包师(Baker):
package com.example.asyncloaderdemo; import java.util.ArrayList; import java.util.List; import android.content.AsyncTaskLoader; import android.content.Context; public class Baker extends AsyncTaskLoader<List<Bread>> { // 用于查询当前需要多少个面包 BakeryCallback mCallback; //面包房回调,用于获得当面面包需求量 interface BakeryCallback { int getNeededBreads(); } public Baker(Context context, f42e BakeryCallback callback) { super(context); mCallback = callback; } @Override public List<Bread> loadInBackground() { List<Bread> breads = new ArrayList<Bread>(); //获得当前需要做的面包 int needs = mCallback.getNeededBreads(); for (int i = 0; i < needs; i++) { //制作面包,耗时操作 breads.add(new Bread()); } //面包制作完成 return breads; } @Override public void deliverResult(List<Bread> data) { super.deliverResult(data); } @Override protected void onStartLoading() { forceLoad(); } @Override protected void onStopLoading() { cancelLoad(); } @Override protected void onReset() { super.onReset(); } }
面包师有了,面包房(Bakery)也不能少
package com.example.asyncloaderdemo; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; public class Bakery extends BroadcastReceiver { final Baker mBaker; public static String CUSTOMER_ACTION = "com.example.asyncloaderdemo.new_customer" ; public Bakery(Baker baker) { mBaker = baker; IntentFilter filter = new IntentFilter(CUSTOMER_ACTION); baker.getContext().registerReceiver(this, filter); } @Override public void onReceive(Context context, Intent intent) { //通知面包师来客人了,要做面包了。 mBaker.onContentChanged(); } }
面包房和面包师都有了,还缺一个场景(MainActivity)
package com.example.asyncloaderdemo; import java.util.ArrayList; import java.util.List; import java.util.Random; import com.example.asyncloaderdemo.Baker.BakeryCallback; import android.support.v7.app.ActionBarActivity; import android.app.LoaderManager.LoaderCallbacks; import android.content.Intent; import android.content.Loader; import android.os.Bundle; import android.util.Log; public class MainActivity extends ActionBarActivity { private LoaderCallbacks<List<Bread>> mCallbacks; //面包房 private Bakery mBakery; //面包师 private Baker mBaker; //面包需求量 private int mNeededBreads; //唯一标识 private final int mLoaderId = 42; private BakeryCallback mBreadCallback = new BakeryCallback() { @Override public int getNeededBreads() { return mNeededBreads; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mNeededBreads = 0; mBaker = new Baker(this, mBreadCallback); mBakery = new Bakery(mBaker); mCallbacks = new LoaderCallbacks<List<Bread>>() { @Override public Loader<List<Bread>> onCreateLoader(int id, Bundle args) { if (mBaker == null) { mBaker = new Baker(MainActivity.this, mBreadCallback); } return mBaker; } @Override public void onLoadFinished(Loader<List<Bread>> loader, List<Bread> data) { mNeededBreads = 0 ; //面包师完成面包烤制 Log.d("scott", "sell " + data.size() + " breads") ; } @Override public void onLoaderReset(Loader<List<Bread>> loader) { } }; //面包师开始工作 getLoaderManager().restartLoader(mLoaderId, null, mCallbacks); //顾客开始上门 mockCustomer(); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(mBakery); } //模拟源源不断的顾客需求 private void mockCustomer(){ new Thread(new Runnable() { @Override public void run() { while(true){ try { Thread.sleep(3000); Random random = new Random(); mNeededBreads =random.nextInt(10); Intent intent = new Intent(Bakery.CUSTOMER_ACTION); sendBroadcast(intent); } catch (InterruptedException e) { e.printStackTrace(); } } } }).start(); } }
接下来我们来看一下程序运行结果:
通过上图并结合代码可以看出来每隔三秒就会有新的顾客上门,顾客上门后面包房通知面包师需要做面吧哦了,接着面包师就会在后台不停的开始使用面包机(AsyncTask)做面包。
总结
说到这里可能有些同学有疑问了,我怎么从头到尾都没有开到AsyncTask的影子呢?你当然看不到,这就是
AsyncTaskLoader设计精妙之处,它做到了让你唯一需要考虑的就是烤面包(异步处理)这个事物逻辑,而不需要考虑异步处理本身的实现上。同时这也充分体现了设计模式中的
单一职责和
最少知道原则。
使用场景
AsyncTaskLoader一般使用在数据源处于不断更新并且请求刷新数据源是个耗时操作的情况下还需要UI去同步更新相关数据的场景(这句话怎么这么拗口)。
相关文章推荐
- [Android Pro] 横竖屏切换时,禁止activity重新创建,android:configChanges="keyboardHidden|orientation" 不起作用
- Android开发中的正在加载动画效果
- android系统自动升级-otacert.zip
- No resource identifier found for attribute 'showAsAction' in package 'android'
- android对数据库的增删改查操作
- Android工具类之Gson封装类
- android Imageview去除边框
- Android Serializable介绍
- android 环境搭建
- 关于dd指令镜像分区的一些使用体会
- Android开机启动Activity或者Service方法
- 读取SIM卡中的EF文件流程
- Android自定义View(一)
- Android开发之利用MQTT协议实现消息的即时推送
- Android中Bitmap和Drawable
- android学习——控制硬加速 hardwareAccelerated 在3.0才有的。
- android 自定义百度地图放大缩小
- Android异步处理之AsyncTaskLoader简单使用
- android 百度最新地图sdk包怎么去除 放大缩小按钮
- android弹出下拉选择菜单,单选,多选