You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义Looper线程中Looper.myLooper与主线程Looper等同的原因及疑问

Android Looper与Handler消息处理疑问解答

场景说明

我正在学习使用Looper和Handler进行消息处理。在主Activity中,点击Start按钮时,创建消息并尝试发送给自定义MyLooperThread的Looper对象。

代码实现

主Activity代码

package com.example.asynctaskdemo

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Looper
import android.os.Message
import android.util.Log
import com.example.asynctaskdemo.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private lateinit var binding:ActivityMainBinding

    private lateinit var myLooperThread: MyLooperThread
    private var myLooperThreadsLooper: Looper ?= null

    private var count = 0

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)

        Log.d("MainThread","Main thread ${Thread.currentThread().id}")

        myLooperThread = MyLooperThread()
        myLooperThread.start()

        val view = binding.root
        setContentView(view)

        binding.textView.text = "0"

        binding.btnStart.setOnClickListener{
            Log.d("MainAct","Main thread ${mainLooper.thread.id}")
            val msg = Message()
            msg.obj = 2
            myLooperThread.handler!!.handleMessage(msg)
        }
        binding.btnStop.setOnClickListener{
            Log.d("MainAct","Main thread ${mainLooper.thread.id}")
            val msg = Message()
            msg.obj = 1
            myLooperThread.handler!!.handleMessage(msg)
        }
    }
}

自定义MyLooperThread类代码

package com.example.asynctaskdemo

import android.os.Handler
import android.os.Looper
import android.os.Message
import android.util.Log

class MyLooperThread : Thread() {
    var handler: Handler ?= null

    override fun run() {
        Looper.prepare()

        handler = object : Handler(Looper.myLooper()!!) {
            override fun handleMessage(msg: Message) {
                // process incoming messages here
                Log.d("MyLooperThread","Looper Thread ID: ${Thread.currentThread().id}, message: ${msg.obj}")
                Log.d("MyLooperThread","Looper Thread ID: ${looper.thread.id}, message: ${msg.obj}")
                Log.d("MyLooperThread","Looper Thread is current: ${looper.isCurrentThread}, message: ${msg.obj}")
                if(Looper.myLooper() == Looper.getMainLooper())
                    Log.d("MyLooperThread","we are in main thread")
                else
                    Log.d("MyLooperThread","we are in looper thread")
            }
        }

        Looper.loop()
        //Looper prepare() and loop() ensure that the thread doesnt die after running
        // run() just once. run () runs
        //indefinitely unless explicitly specified because of these functions
    }
}

运行输出

D/MainAct: Main thread 2
D/MyLooperThread: Looper Thread ID: 2, message: 2
D/MyLooperThread: Looper Thread ID: 497, message: 2
D/MyLooperThread: Looper Thread is current: false, message: 2
D/MyLooperThread: we are in main thread

疑问解答

1. 为何输出显示处于主线程?即为何在MyLooperThread中声明Handler时,Looper.myLooper()与Looper.getMainLooper()相等?

问题出在消息发送的方式上:你没有通过Handler.sendMessage()将消息投递到子线程Looper的消息队列,而是直接在主线程的点击事件里同步调用了handler!!.handleMessage(msg)。这会让handleMessage方法直接在主线程执行,此时Looper.myLooper()获取的就是主线程的Looper,自然和Looper.getMainLooper()相等。

正确做法是调用handler!!.sendMessage(msg),让消息进入子线程Looper的消息队列,由Looper在子线程中取出并触发handleMessage。

2. looper.thread.id返回497,而Thread.currentThread().id返回2,二者有何区别?

  • looper.thread.id是自定义MyLooperThread的线程ID(497),因为这个Handler绑定的是该子线程的Looper。
  • Thread.currentThread().id是当前执行handleMessage方法的线程ID,由于你直接在主线程调用handleMessage,所以这里返回主线程ID(2)。

如果改用sendMessage发送消息,Thread.currentThread().id就会和looper.thread.id一致,都是497。

3. 为何looper.isCurrentThread()返回false?

looper.isCurrentThread()用来判断当前执行代码的线程是否是Looper所属的线程。你的Handler绑定的是子线程(497)的Looper,但handleMessage是在主线程(2)执行的,当前线程和Looper所属线程不一致,所以返回false。

当你用sendMessage发送消息后,Looper会在子线程中处理消息,此时looper.isCurrentThread()就会返回true。


内容的提问来源于stack exchange,提问作者Parag

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 20:35:15