android线程小结

线程

线程是操作系统调度的最小单元,在android中,主线程又称为UI线程,执行的是与界面渲染等操作,
而工作线程一般承担耗时多的操作。

Android中线程的实现方式有以下几种:

1.AsyncTask 线程池
2.IntentService 线程
3.HandlerThread 线程


AsyncTask

android 1.6 前串行
1.6-3.0 并行
3.0后串行,引入excuteOnExecutor可以进行并行操作

实例化与execute都是只能在主线程进行的
1)execute操作会调用onPreExecute操作
2)静态成员会在加载类时进行初始化,否则同一进程中的AsyncTask都将无法正常工作

工作原理:

asyncTask中有两个主要的线程池,分别是
THREAD_POOL_EXECUTOR
这个线程池抓哟是跟具体的任务执行相关,其实例是ThreadPoolExecutor
SERIAL_EXECUTOR
充当串行任务排队的作用,如果是自己调用excuteOnExecutor,则调度方式由自己传入的线程池决定

mWorker (WorkerRunnable) 用于执行相关的任务
mFuture (FutrueTask) 用于完成结果回调使用,发送相关的信息,告知handler结束
sHandler (InternalHandler) 实现的关键角色,创建于主线程中,且负责接受相关的回调信息并处理

private static class InternalHandler extends Handler {
public InternalHandler() {
//注意这里是主线程中的,保证处理信息的时候是在主线程中进行
super(Looper.getMainLooper());
}

@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override
public void handleMessage(Message msg) {
        AsyncTaskResult<?> result = (AsyncTaskResult<?>) msg.obj;
        switch (msg.what) {
                 case MESSAGE_POST_RESULT:
                    // There is only one result
                    result.mTask.finish(result.mData[0]);
                    break;
                case MESSAGE_POST_PROGRESS:
                    result.mTask.onProgressUpdate(result.mData);
                    break;
        }
    }
}

1.实例化时,会准备好mWorker 和 mFuture,这两个相当于回调函数

2.调用excute函数会调用到excuteOnExecutor,此时会调用onPreExecute(),并会交给调度的线程池去调度任务,提取到的任务再交给指定的线程池去执行任务,默认采用THREAD_POOL_EXECUTOR,串行线程池,此时传入了(mFuture),而mFutrue已传入mWorker的参数,能够回调mWorker的 call方法

mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);

Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
Result result = doInBackground(mParams);
Binder.flushPendingCommands();
        return postResult(result);
}
};

mFuture = new FutureTask<Result>(mWorker) {
@Override
protected void done() {
try {
            postResultIfNotInvoked(get());
} catch (InterruptedException e) {
            android.util.Log.w(LOG_TAG, e);
} catch (ExecutionException e) {
throw new RuntimeException("An error occurred while executing doInBackground()",
e.getCause());
} catch (CancellationException e) {
            postResultIfNotInvoked(null);
}
    }
};

3.在call方法中会调用doInBackground方法,此时,其实此方法其实已经在已开辟的线程池中执行了。
4.执行完,通过postResult让信息发送给sHandler,再回调onPostExecute 完成整个过程。

总之,巧妙使用了线程池的回调runnable,再通过handler,message实现主,工作线程的消息传递。
这里的handler是主线程下的handler,这主要是保证回调能够直接操纵UI元素。


HandlerThread

是继承自Thread的类,自动帮我们创建好looper,这样创建handler就不用手动Looper初始化了
ps:可以理解为,集合了looper的thread

@Override
public void run() {
mTid = Process.myTid();
Looper.prepare();
    synchronized (this) {
mLooper = Looper.myLooper();
notifyAll();
}
    Process.setThreadPriority(mPriority);
onLooperPrepared();
Looper.loop();
mTid = -1;
}

其调用主要实现如下:

mHandlerThread = new HandlerThread("MyHandler");
mHandlerThread.start();

mHandler = new Handler(mHandlerThread.getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {

        return false;
}
});

mHandler.post(new Runnable() {
public void run() {
//任务1
        mHandler.sendMessage();
//任务2
}
});

这样,就能够直接在run中执行相关任务。
需要注意的是,初始化后该Thread是无限循环的,需要手动终止线程执行,即调用quitSafely或者quit


IntentService

继承于Service的一个自带工作线程的Service=。=优先级还是蛮高的呢
其实现主要依靠handlerThread进行的,onCreate中实例化handlerThread,onStart中发送消息,
然后在handlerMessage过程中调用onHandlerIntent,完成工作线程的任务,完成后直接结束=。=
值得注意的是,退出调用的是stopSelf(int startId); 这会检查是否有新的消息入列,这对于多次派发任务是有帮助的,不至于那么快结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值