Android Thread /Process
1 为什么需要进程? 每个进程系统分配的资源有限,单进程会带来卡顿等情况。
单纯的耗时操作(比如推送的长连接服务)可以放到单独的进程
进程: android:process 指定运行在不同进程中。
每个进程都有自己的虚拟机实例,所以涉及到进程间通信,我们可以通过AIDL来处理(当然通过共享shared_pref /文件也可以实现)
需要注意,每个进程对应都会有自己的Application 不需要在每个进程中初始化的操作需要做过滤
if(!shouldInit()){LogUtils.d(TAG, "return for not main process");}
当前应用主进程可以干掉自己生成的其它进程,其它进程不能干掉主进程 killProcess()
2 为什么需要线程? 主线程不能做耗时操作,比如网络连接,文件IO。耗时处理会带来 ANR 异常
线程类型有
接口 Runnable
基类Thread (继承Runnable), 构造方法,new Thread(Runnable 对象)
1 new Runnable 只是实现该接口的匿名内部类, 并不是线程,需要 传入new Thread(Runnable)才是线程
同时,post(Runnable) 只是把Runnable 封装以后在消息队列中去执行方法,并没有开启线程
handler 中的post 方法,依赖其所绑定的looper , looper所在线程,就是Runnable执行的线程
线程run方法执行完以后,gc 自动回收。像while这种死循环线程,自己注意设置标志位,适当时候退出死循环
stop 已经被废弃,interrupt 中断自己捕获一下中断异常
有线程,就存在线程间通信与管理的问题:handler 消息队列 AsysncTask 异步任务 线程池 ThreadPoolExecutor提供了方案。
消息队列 异步任务,是Android 提供的两个多线程方案,均在 android.io
Handler 消息队列
Handler :发送和处理 sendMessage /handleMessage
Looper 一个线程唯一一个Looper 主线程Looper自动创建:子线程Looper手动创建
MessageQuene 一个Looper 一个消息队列
loop 中的loop 方法,死循环读取队列中的 Message 然后回调给Handler 处理
handler 处理过程中有强引用的问题,activity 结束了,handler 还有消息未处理
一个是改为弱引用的activity , 一个是使用handlerThread , 在结束的时候quitSafely 掉
HandlerThread 继承Thread,配合Handler 使用 new Handler(handlerThread.getLooper())
在线程基础上增加了一些方法,quitSafely()
AsyncTask 对Handler消息处理 进行了封装
Handler 还需要自己创建子线程,发送消息,处理回调
AsyncTask 直接继承,调用系统为你创建的线程管理,继承开始,与回掉的地方即可
需要继承 AsyncTask 实现 doInBackgroud 方法
new DownloadTask().execute(url); 来执行,如果直接调用方法,就不是子线程了
主要方法onPreExecute(异步处理前) doInBackgroud(异步处理中) onPostExecute(异步处理后)
ExecutorService 线程池 包含 List<Runnable> 对象 管理线程
Executors 提供了几个静态类,来创建不同的线程池,比如固定个数,单线程的
executorService = Executors.newFixedThreadPool(2);
executorService.execute(syncRunnable); sumbit(Runnable)有返回值
线程池管理线程更加安全,提交线程,和submit 返回的Future对象提供了cancel 线程的方法
Thread 任务完成自动回收,或者interrupt掉,注意捕获异常
ThreadPoolExecutor 线程池处理,或者自己在返回的Future 中cancel
TimerTask 执行Runnable 接口,也是一类线程
配合Timer 做定时任务,比如我们每隔一段时间,获取当前定位传给后台,可以在Timer+TimerTask 配合完成
主要做定时任务,在后面的章节回顾
案例:
主线程建立Handler 绑定主线程Looper: 基于主线程的 消息机制
绑定子线程的Looper , 基于子线程的消息机制
主线程 (Looper1 handler1)
子线程1 (Looper2 建立handler2) 使用handler1 消息机制,发送Message到主线程中去处理
子线程2 (Looper3) 使用handler2 的消息机制,发送Message 到子线程1 中去处理
一个Looper 可以被多个HandlerA1、A2、A3绑定,不同的handler发送,最后在一个Loop()循环中,再指定到对应的Target 来处理
———————————
IOS NSThread / GCD
IOS 同样主线程中不能做耗时操作,会导致阻塞
NSThread Thread
NSOperation AsyncTask
GCD Handler 派发队列
NSTimer Timer
NSThread *thread = [Thrad alloc] initWithTarget:self selector@selector(threadAction:) object@"test"];
[thread start];
设计思想非常相似, 后续补充