Android异步处理技术(一)

异步处理技术(一)

写在前面

本文章为《Android高级进阶》的读书笔记,看过的朋友可以出门转去别的更深度的文章了,没看过的可以当作知识点来看一下,欢迎给意见进行知识交流。表达能力有限,不喜勿喷。

安卓定义的三种线程:

  • 主线程:

    主线程就是我们熟悉的UI线程,谨记只有UI线程才成操作控件更新空间。想子线程任务完成更新界面的方法现在很多了,传统的使用handler,高大上的就是用rxJava等异步操作库。
  • Binder线程:

    Binder线程可能很多人用的不多,它是用于不同的进程之间的通信,其实每一个进程都会有一个线程池来用出来别的进程发送过来的消息,比如:系统服务,Intents,ContentProviders,Service等,典型的用例就是应用使用Binder线程提供一个service给其他进程通过AIDL接口进行绑定。
  • 后台线程:

    这个你要是不知道什么意思就过分了,它其实就是我们一直说的子线程,创建出来内容时空的,需要我们自己添加任务后start。不过其实要是上升到Linux层面主线程跟子线程是一样的东西,只是Android框架里面添加了主线程跟后台线程的概念,限制了后台线程能力,确保UI是线程安全的。

HandlerThread

HandlerThread是一个自带Looper跟MessageQueue的线程,也就是说这个线程是一个能够实现异步操作的子线程。而且它会一直等待消息进行处理。下面它的基本用法:

HandlerThread handlerThread = new HandlerThread("HandlerThread");
handlerThread.start();

mHandler = new Handler(handlerThread.getLooper()){
    @Override 
    public void handlerMessage(Message msg){
        super.handlerMessage(msg);
        //处理收到的消息
    }
};

也是因为HandlerThread自带Looper,所以HandlerThread里面的任务是按顺序执行的,吞吐量也会受到一定的影响,不会这个是我认为实现异步的比较好理解的一种方式了。

AsyncQueryHandler

AsyncQueryHandler主要用在ContnetProvider里面,用于执行Create,Read,Update,delete操作的工具类,AsyncQueryHandler主要封装了ContentResolver,HandlerThread,Handler等实现了对ContentProvider的异步操作,原理如图所示:

AsyncQueryHandler.png

(图片不好找,自己照着画了一个)

通常使用AsyncQueryHandler会跟着ContentProvider一起使用,AsyncQueryHandler封装了如下四种方法来操作ContentProvider:

final void startDelete(...);
final void startInsert(...);
final void startQuery(...);
final void startUpdate(...);

相对的AsyncQueryHandler有相应的回调函数,可以得到上面四个方法的返回结果:

@Override
protected void onDeleteComplete(...){...}
@Override
protected void onUpdateComplete(...){...}
@Override
protected void onInsertComplete(...){...}
@Override
protected void onQueryComplete(...){...}

IntentService

service我们熟悉的生命周期函数都是运行在主线程中的,本身并不是一个异步处理的技术。为了service里面可以使用子线程处理耗时任务,Android引入了IntentService,service的一个子类,具有跟service一样的生命周期,同时也提供着后台线程异步处理任务的机制,这一点跟上面讲到的HandlerThread十分的相似,IntentService会后台顺序执行所有任务,与我们遇到的一些后台下载场景十分的契合。

我们可以使用一个Intent类型的参数启动IntentService的异步执行,如果IntentService已经启动了,新的Intent将会进入队列进行等待,如果没有运行将会启动一个新的IntentService。当IntentService运行完所有的后台任务后,会自动结束自己的生命周期,不需要开发者手动结束,这是我觉得比较好的地方。
IntentService本身是一个抽象类,因此继承它需要实现它的抽象方法onHandleIntent来处理后台的业务逻辑,同时需要在构造方法中调用super(String name)传入子类的名字,示例代码如下:

public class SimpleIntentService extends IntentService{
    public SimpleIntentService(){
        super(SimpleIntentService.class.getName());
        setIntentRedelivery(true);
    }

    @Override
    protected void onHandleIntent(Intent intent){
        //此处写后台逻辑
    }
}

上面的setIntentRedelivery方法如果设置为true,那么IntentService的onStartCommand方法将会返回START_REDELIVER_INTENT。这时要是onHandleIntent调用之前进程死掉了,那么进程将会重新启动,intent也会重新投递。
使用IntentService最重要的一点就是,大家记得在AndroidManifest.xml文件里注册声明。
其实大家如果有兴趣的话可以查看下IntentService的源码,里面其实是通过HandlerThread来实现的,套了一层service的马甲,源码有点多,就贴几句:

    public abstract class IntentService extends Service {
        ...
        private final class ServiceHandler extends Handler{
            ...
            @Override
            public void handleMessage(Message msg){
                onHandleIntent((Intent)msg.obj);
                stopSelf(msg.arg1);
            }
        }

        @Override
        public void onCreate(){
            ...
            HandlerThread thread  = new HandlerThread("IntentService["++"mName"]");
            thread.start();
            mServiceLooper = thread.getLooper();
            mServiceHandler = new ServiceHandler(mServiceLooper);
        }

        @Override
        public void onStart(Intent intent,int startId){
            Message msg = mServiceHandler.obtainMessage();
            msg.arg1 = startId;
            msg.obj = intent;
            mServiceHandler.sendMessage(msg);
        }
        ...
    }

总结

本文先总结了Android里面三种异步处理的技术,这只是其一,后面还会总结书中提到的另外三种技术:Loader,AsyncTask,Executor Framework。如开头提到的文中都是些看《Android高级进阶》一本的知识点总结,写的都是自己比较浅显的理解,书中有更详细的篇幅介绍,感兴趣的朋友可以找来看看,里面全是干货。最后欢迎大家交流共同进步。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容