android 主线程死循环,Looper.loop()方法跑的是死循环, 为什么我们的Activity生命周期方法还能在主线程中运行?...

参考: https://www.jianshu.com/p/733b1cc9b457

ActivityThread就是我们常说的主线程或UI线程,ActivityThread的main方法是整个APP的入口

MainLooper在它的main方法中被创建。

//ActivityThread的main方法

public static void main(String[] args) {

......

Looper.prepareMainLooper(); //创建MainLooper

ActivityThread thread = new ActivityThread();

//在attach方法中会完成Application对象的初始化,然后调用Application的onCreate()方法

thread.attach(false);

if (sMainThreadHandler == null) {

sMainThreadHandler = thread.getHandler();

}

......

Looper.loop(); //开启循环

throw new RuntimeException("Main thread loop unexpectedly exited");

}

Looper.loop()方法跑的是死循环, 为什么我们的Activity生命周期方法还能在主线程中运行?

看下面代码

framworks\base\core\java\android\os\Looper.java

Looper.loop()

public static final void loop() {

Looper me = myLooper();

MessageQueue queue = me.mQueue;

Binder.clearCallingIdentity();

final long ident = Binder.clearCallingIdentity();

//开启死循环

while (true) {

//该方法是阻塞只到有新的消息到来

Message msg = queue.next(); // might block

if (msg != null) {

if (msg.target == null) {

return;

}

if (me.mLogging!= null) me.mLogging.println(

">>>>> Dispatching to " + msg.target + " "

+ msg.callback + ": " + msg.what

);

// 分发处理消息, target是一个Handler类

msg.target.dispatchMessage(msg);

if (me.mLogging!= null) me.mLogging.println( "<<<<< Finished to " + msg.target + " " + msg.callback);

final long newIdent = Binder.clearCallingIdentity();

if (ident != newIdent) {

Log.wtf("Looper", "Thread identity changed from 0x" + Long.toHexString(ident) + " to 0x" + Long.toHexString(newIdent) + " while dispatching to "

+ msg.target.getClass().getName() + " "

+ msg.callback + " what=" + msg.what);

}

msg.recycle();

}

}

}

Message msg = queue.next(); // might block

这句没有消息来的时候确实是阻塞的

但是这里不仅仅接收我们自己发送的消息, 还会接收系统发送过来的消息, 比如生命周期发生变化的消息.

当收到消息后就会执行下面这句:

msg.target.dispatchMessage(msg); //target是一个Handler类

这个target就是我们自己或者系统传过来的Handler, 他们不是同一个Handler,

所以会各自执行自己覆盖的handleMessage(msg)方法

framworks\base\core\java\android\os\Handler.java

handler.dispatchMessage()

public void dispatchMessage(Message msg) {

if (msg.callback != null) {

handleCallback(msg);

} else {

if (mCallback != null) {

if (mCallback.handleMessage(msg)) {

return;

}

}

handleMessage(msg);

}

}

Activity的生命周期是怎么实现在死循环体外能够执行起来的?

ActivityThread的内部类H继承于Handler,通过handler消息机制,简单说Handler机制用于同一个进程的线程间通信。

Activity的生命周期都是依靠主线程的Looper.loop,当收到不同Message时则采用相应措施:

在H.handleMessage(msg)方法中,根据接收到不同的msg,执行相应的生命周期。

比如收到msg=H.LAUNCH_ACTIVITY,则调用ActivityThread.handleLaunchActivity()方法,最终会通过反射机制,创建Activity实例,然后再执行Activity.onCreate()等方法;

再比如收到msg=H.PAUSE_ACTIVITY,则调用ActivityThread.handlePauseActivity()方法,最终会执行Activity.onPause()等方法。 上述过程,我只挑核心逻辑讲,真正该过程远比这复杂。

我们可以断点调试验证一下,是不是上面所说那样?

点击一个button发生一条自定义消息

public class MainActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

Handler handler = new Handler(){

@Override

public void handleMessage(@NonNull Message msg) {

}

};

public void click(View view) {

Message message = Message.obtain();

message.what = 100;

message.obj = "我是自定义的消息";

handler.sendMessage(message);

}

}

在类Handler的handleMessage()方法中设置断点

点击按钮, 会收到自己定义的message

9d7bc1ad3768110e057c71e342dbc999.png

当我按下手机Home键, 我会收到一条包含 target=android.app.ActivityThread$H 的消息

cb9f71c8ba0fae2bc874c533da402b0b.png

frameworks\base\core\java\android\app\ActivityThread.java

H类是一个ActivityThread的内部类,继承Handler

private final class H extends Handler {

public static final int LAUNCH_ACTIVITY = 100;

public static final int PAUSE_ACTIVITY = 101;

.......

String codeToString(int code) {

if (DEBUG_MESSAGES) {

switch (code) {

case LAUNCH_ACTIVITY: return "LAUNCH_ACTIVITY";

case PAUSE_ACTIVITY: return "PAUSE_ACTIVITY";

......

}

}

return "(unknown)";

}

public void handleMessage(Message msg) {

if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + msg.what);

switch (msg.what) {

case LAUNCH_ACTIVITY: {

ActivityClientRecord r = (ActivityClientRecord)msg.obj;

r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo);

handleLaunchActivity(r, null);

} break;

case PAUSE_ACTIVITY:

handlePauseActivity((IBinder)msg.obj, false, msg.arg1 != 0, msg.arg2);

maybeSnapshot();

break;

......

}

if (DEBUG_MESSAGES) Slog.v(TAG, "<<< done: " + msg.what);

}

}

本文地址:https://blog.csdn.net/csdm_admin/article/details/107164741

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值