Android多线程机制
来源:互联网 发布:各个国家顶级域名 编辑:程序博客网 时间:2024/05/18 02:26
问题
1)为何需要多线程?
在android中,在主线程中如果耗时太长会出现ANR(android not
Responding),也就是看起来很卡;
一些下载图片,下载数据等耗时操作需要在其他线程执行。
一句话:避免应用太卡,需要使用多线程。
2)多线程如何实现?
多线程实现方式两种方式:
implements Runnable 或 extends Thread
3)多线程机制的核心是啥?
也可以理解为:线程之间的消息传递
一句话:handler机制
3.1 创建一个Handler时一定要关联一个Looper实例,默认构造方法Handler(),它是关联当前Thread的Looper。
我们在UI Thread中创建一个Handler,那么此时就关联了UI Thread的Looper!
public Handler() { mLooper = Looper.myLooper();}//当前线程的Looper,在Activity创建时,UI线程已经创建了Looper对象//在Handler中机制中Looper是最为核心的,它一直处于循环读MessageQueue,有//要处理的Message就将Message发送给当前的Handler实例来处理
3.2 在创建一个Handler的时候也可以指定Looper,此时的Looper对象,可以是当前线程的也可以是其它线程的!
Handler只是处理它所关联的Looper中的MessageQueue中的Message,至于它哪个线程的Looper,Handler并不是很关心!
我们可以在UI线程中创建一个Handler同时传入Worker的Looper???????
3.3 可Handler到底干了啥呢?简要说明如下:
Activity所在的UI线程在创建的时候,就关联了Looper和MessageQueue,那么我们又在UI线程里创建了自己的Handler,那么Handler是属于UI线程的,从而它是可以和UI线程交互的!UI线程的Looper一直在进行Loop操作MessageQueue读取符合要求的Message给属于它的target即Handler来处理!所 以啊,我们只要在Worker线程中将最新的数据放到Handler所关联的Looper的MessageQueue中,然而Looper一直在loop 操作,一旦有符合要求的Message,就第一时间将Message交给该Message的target即Handler来处理!所以啊,我们在创建 Message的时候就应该指定它的target即Handler!
3.4 消息发送有哪几种方法?
但我们也可以,new Message() -- > mHandler.sendMessage(msg) ;这是特例!如果我们通过obtainMessage()方法获取Message对象,此时Handler就会自动设置Message的target。可以看源码!
简单一点说就是:
UI线程或Worker线程提供MessageQueue,Handler向其中填Message,Looper从其中读Message,然后交由 Message自己的target即Handler来处理!!最终被从属于UI线程的Handler的handlMessag(Message msg)方法被调用!!
这就是Android多线程异步处理最为核心的地方!!
3.5 注意点:
(1)在UI线程中创建Handler[一般继承HandleMessage(Message msg)]
(2)Looper可以属于UI线程或Worker线程
(3)从属于Looper的MessgeQueue,Looper一直在loop()操作,在loop()中执行msg.target.dispatchMessage(msg);调用Handler的handleMessage(Message msg)
在创建一个Looper时,就创建了从属于该Looper的MessageQueueprivate Looper() {mQueue = new MessageQueue();mRun = true;mThread = Thread.currentThread();}
(4)在 Worker线程中获取Message,然后通过Handler传入MessageQueue
(5)handler处理消息。
4)到底有多少种实现方式?
4.1 在异步线程操作UI控件
利用handler
handler.sendMessage(message)-----------handleMessage方法回调
4.2 控件自己本身操作
textview.post(Runnable action)textview.postDelay(Runnable action , long miliseconds)
4.3 activity的调用方法
runOnUiThread(Runnable action)
public final void runOnUiThread(Runnable action) {if (Thread.currentThread() != mUiThread) {//如果当前线程不是UI线程mHandler.post(action);} else {action.run();}}其中:mUiThread = Thread.currentThread() ;mHandler = new Handler()
4.4 AsyncTask(在UI线程中、只能实例化一次的)
onPreExecute() --在UI线程中执行,作一些初始化操作doInBackground(Params... params) --在Worker线程中执行,进行耗时的后台处理,在该方法中可以调用publishProgress(Progress progress) 进行进度处理onProgressUpdate(Progress progress) --在UI线程中执行,进行进度实时处理onPostExecute(Result result) --在UI线程中执行, 在doInBackground(Params ... params)返回后调用onCancelled() --在UI线程中执行,在AsyncTask实例调用cancle(true)方法后执行,作一些清理操作
注意点
AsyncTask必须在UI线程中创建,asyncTask.execute(Params... params) ;在UI线程中执行,且只能执行一次要想再次调用execute(Params... params),必须重新创建AsyncTask对象
遗留问题
- handler从消息队列轮询处理消息,当消息处理完了会怎样?
- AsyncTask优缺点有哪些?
优点是解决了多线程处理问题
缺点是每处理一个任务需要一个新的实例来执行 - 当同一时间有很多耗时操作时,需要new thread很多实例,任务执行完成后,会被虚拟机垃圾回收gc,降低程序性能。
原理:当频繁创建销毁某个类型的对象实例时,会产生很多临时对象,当失去引用的临时对象较多时,就会gc。
如何自定义线程池来处理这一个问题? - 我们可以在UI线程中创建一个Handler同时传入Worker的Looper,那么handler处理消息是来自UI线程还是worker线程,还是两个都处理?
- 用一张图来阐述handler原理?
- Android中的多线程机制
- Android多线程机制
- Android多线程机制解析
- Android多线程机制
- android多线程机制
- Android多线程通信机制
- android多线程机制
- android中的多线程机制
- android多线程机制
- Android多线程机制
- Android多线程机制之Handler
- Android多线程机制详细解析
- Android消息机制和多线程
- Android多线程及Handler机制
- android消息机制,异步和多线程
- android消息机制,异步和多线程
- android消息机制,异步和多线程
- [转]android消息机制,异步和多线程
- 正确使用日志的技巧
- Selenium中被误用的XPath
- 在CENTOS7上玩转Ethereum区块链(1):虚机架设篇
- DB2函数大全
- 中科院分词系统(NLPIR)JAVA简易教程(转载)
- Android多线程机制
- win7_不主动发送智能卡命令
- js计算出现多位小数-Javascript 浮点运算问题分析与解决
- Runtime浅析
- 性能优化系列之fragment的懒加载
- HDU 6201 树形DP 或 最长路
- Linux基础命令
- GoF:(Gang of Four,GOF设计模式)---四人组
- 区块链架构与应用(区块链入门篇)