一、子线程向子线程通信
package com. study. yang. handlercodedemo
import android. support. v7. app. AppCompatActivity
import android. os. Bundle
import android. os. Handler
import android. os. Looper
import android. os. Message
import android. util. Log
import android. view. View
import kotlinx. android. synthetic. main. activity_child_to_child. *
class ChildToChildActivity : AppCompatActivity ( ) {
var handler: Handler? = null
var content: String = ""
override fun onCreate ( savedInstanceState: Bundle? ) {
super . onCreate ( savedInstanceState)
setContentView ( R. layout. activity_child_to_child)
object : Thread ( ) {
override fun run ( ) {
super . run ( )
Looper. prepare ( )
handler = object : Handler ( ) {
override fun handleMessage ( msg: Message? ) {
super . handleMessage ( msg)
msg? . apply {
if ( obj is String) {
Log. e ( "thread::" , "111message::$this" )
content = obj as String
runOnUiThread {
tv_thread1. text = content
}
}
}
}
}
Looper. loop ( )
}
} . start ( )
}
fun sendMsg ( view: View) {
object : Thread ( ) {
override fun run ( ) {
super . run ( )
handler? . apply {
val message = obtainMessage ( )
message? . obj = "子线程2"
sendMessage ( message)
}
}
} . start ( )
}
}
二、子线程向主线程通信
package com. study. yang. handlercodedemo
import android. support. v7. app. AppCompatActivity
import android. os. Bundle
import android. os. Handler
import android. os. Message
import kotlinx. android. synthetic. main. activity_child_to_main. *
class ChildToMainActivity : AppCompatActivity ( ) {
var handler = object : Handler ( ) {
override fun handleMessage ( msg: Message? ) {
super . handleMessage ( msg)
msg? . apply {
val text = obj as String
tv. text = text
}
}
}
override fun onCreate ( savedInstanceState: Bundle? ) {
super . onCreate ( savedInstanceState)
setContentView ( R. layout. activity_child_to_main)
object : Thread ( ) {
override fun run ( ) {
super . run ( )
val message = Message. obtain ( )
message. obj = "品兰"
handler. sendMessage ( message)
}
} . start ( )
}
}
三、主线程向子线程通信
package com. study. yang. handlercodedemo
import android. support. v7. app. AppCompatActivity
import android. os. Bundle
import android. os. Handler
import android. os. Looper
import android. os. Message
import android. util. Log
import android. view. View
class MainToChildActivity : AppCompatActivity ( ) {
var handler: Handler? = null
override fun onCreate ( savedInstanceState: Bundle? ) {
super . onCreate ( savedInstanceState)
setContentView ( R. layout. activity_main_to_child)
object : Thread ( ) {
override fun run ( ) {
super . run ( )
Looper. prepare ( )
handler = object : Handler ( ) {
override fun handleMessage ( msg: Message? ) {
super . handleMessage ( msg)
msg? . apply {
if ( obj is String) {
Log. e ( "thread::" , "111message::$this" )
}
}
}
}
Looper. loop ( )
}
} . start ( )
}
fun sendMsg ( view: View) {
handler? . apply {
val message = obtainMessage ( )
message. obj= "我在主线程向子线程发送消息"
sendMessage ( message)
}
}
}
四、Handler源码解析
4.1 为什在主线程中创建Handler的时候不用调用Looper.prepare()和Looper.loop()
此处创建的Handler,默认就是在主线程中。
ActivityThread中的main方法
public static void main( String[ ] args) {
.. .
Looper.prepareMainLooper( ) ;
.. .
Looper.loop( ) ;
}
4.2 子线程中创建Handler注意事项
子线程中创建Handler,这段示例代码可以在Looper源码中找到
class LooperThread extends Thread {
public Handler mHandler;
public void run( ) {
Looper.prepare( ) ;
mHandler = new Handler( ) {
public void handleMessage( Message msg) {
// process incoming messages here
}
} ;
Looper.loop( ) ;
}
}
4.3 Handler是如何做到线程隔离的
Looper中的static final ThreadLocal< Looper> sThreadLocal = new ThreadLocal < Looper> ( ) ; 说明虚拟机中只会存在ThreadLocal唯一对象
每个线程的Thread成为Handler线程时,都需要Looper. perpar ( ) 方法,都会创建新的Looper。
每个线程都有新的Looper, 每个线程都有新得ThreadLocalMap,每个ThreadLocalMap的key值都是虚拟机中ThreadLocal唯一对象, 对应值为当前Looper对象。
Message- > Handler- > Activity,假设存在延迟消息,那么将会导致持有的Activity的引用与Message的生命周期不一致,从而导致内存泄漏。
Message. obtain方法产生Message,享元模式减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结构的方式
主线程与子线程如何实现通信
Handler、MessageQuene以及Looper若在主线程,子线程使用Handler对象发送消息到消息队列时,Looper轮询时将会在主线程中取出消息并处理消息,实现通信。
利用ThreadLocal实现线程隔离,ThreadLocal内部维护了一个ThreadLocalMap对象。它的存储数据结构是
以Key- Value的形式进行的,其中Key就是当前ThreadLocal的对象,Value是Looper对象。
4.4 Handler源码
创建Handler的过程中走的流程如下,调用Looper类中的Looper.prepare( ) 方法
public static void prepare( ) {
prepare( true) ;
}
private static void prepare( boolean quitAllowed) {
if ( sThreadLocal.get( ) != null) {
throw new RuntimeException( "Only one Looper may be created per thread" ) ;
}
//将创建的Looper保存到ThreadLocal中
sThreadLocal.set( new Looper( quitAllowed)) ;
}
//Looper类中创建Looper的同时创建该Handler的消息队列
private Looper( boolean quitAllowed) {
mQueue = new MessageQueue( quitAllowed) ;
mThread = Thread.currentThread( ) ;
}
调用Handler类中的构造方法创建Handler,具体如下:
public Handler( Callback callback, boolean async) {
.. .
//从ThreadLocal中取出之前保存的Looper
mLooper = Looper.myLooper( ) ;
if ( mLooper == null) {
throw new RuntimeException(
"Can't create handler inside thread that has not called Looper.prepare()" ) ;
}
//该Looper中的消息队列
mQueue = mLooper.mQueue;
.. ..
}
//调用Handler类中的sendMessage方法发送消息,最终调用
enqueueMessage( MessageQueue queue, Message msg, long uptimeMillis) 进行消息队列的排序。
//调用MessageQueue类的enqueueMessage方法进行消息排列
按照消息执行时间进行排序,此处用的是优先队列算法
if ( p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
needWake = mBlocked && p.target == null && msg.isAsynchronous( ) ;
Message prev;
for ( ; ; ) {
prev = p;
p = p.next;
if ( p == null || when < p.when) {
break ;
}
if ( needWake && p.isAsynchronous( )) {
needWake = false ;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
最后调用Looper.loop( ) 开启消息队列轮询,具体方法如下:
public static void loop( ) {
//找到当前线程的Looper
final Looper me = myLooper( ) ;
if ( me == null) {
throw new RuntimeException( "No Looper; Looper.prepare() wasn't called on this thread." ) ;
}
//找到相应的消息队列
final MessageQueue queue = me.mQueue;
.. ..
for ( ; ; ) {
//开始轮询消息
Message msg = queue.next( ) ; // might block
if ( msg == null) {
// No message indicates that the message queue is quitting.
return ;
}
.. ..
}
}