安卓中线程之间的通信方式(如何避免ANR)
(1). AsyncTask,其中doInBackground()和onPostExecute(Result)两个方法非常重要
doInBackground() 这个方法运行在后台线程中,主要负责执行那些很耗时的操作,如访问网络。该方法必须重写。(其实这个方法就是在子线程中做耗时操作,通过handler发送到onPostExecute)
onPostExecute(Result) 这个方法运行于UI主线程,在doInBackground(Params…)方法执行后调用,该方法用于接收后台任务执行后返回的结果,刷新UI显示。
(2.)子线程 + handler
在子线程中执行完耗时操作需要刷新UI时,通过handler.sendMessage()发消息给主线程, 然后在主线程Handler中的handleMessage()方法中执行刷新UI操作
在安卓中有4大组件:activity,service,contentprovider,broadcastreceiver,这4大组件都运行在主线,谷歌官方规定,安卓不能再主线程做耗时操作,负责会造成ANR,为了避免这种情况的出现,必须开线程处理耗时操作,但是安卓规定,子线程不能更新UI,所以安卓引入了Handler机制,
(因为安卓中的UI控件不是线程安全的,如果在多线程中,并发访问可能会导致UI控件处于不可预期的状态,(为啥系统不对UI控件的访问加锁机制,缺点有两个1:加上锁机制会让UI访问的逻辑变的复杂,其次锁机制会降低UI访问的效率,因为锁机制会阻塞某些线程的执行,最简单最高效就是采用单线程来处理,对于我们来说也不是很麻烦,只需要通过Handler切换一下UI访问的执行线程即可))
Handler主要用于线程间的通信。
一个Handler允许发送和处理Message和Runable对象,UI主线程会自动分配一个Looper(消息轮询器),每个Looper中封装着MessageQueue(消息队列),遵循先进先出原则。Looper负责不断的从自己的消息队列里取出队头的任务或消息执行。一般是在子线程执行完耗时操作之后,通过Handler的sendMessage或post方法将Message和Runable对象传递给MessageQueue,而且在这些对象离开MessageQueue时,Handler负责执行他们(用到handleMessage方法,主要执行刷新UI的代码)。
其中Message类就是定义了一个信息,这个信息中包含一个描述符和任意的数据对象,这个信息被用来传递给Handler.Message对象提供额外的两个int域和一个Object域。
字面以外加上关联点。