消息队列处理模型

容器保存事件,队列

涉及到角色:

类 功能

MessageQueue 存放消息

Looper 轮循消息队列,从中取出消息

Thread 处理消息

Message 消息

Handler 在其他线程发消息给当前线程


1.looper的例子及说明

由Looper决定

Looper对象在哪个线程创建,

Handler的handleMessage方法就在哪个线程执行

public class MainActivity extends Activity
{
    private Handler mHandler;
    int what = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button1).setOnClickListener(new OnClickListener()
        {
                                                                                                                                                                                                                                                                                                                                               
            @Override
            public void onClick(View v)
            {
                mHandler.sendEmptyMessage(what ++);//主线程发送
                new Thread("aaa")
                {
                    public void run()
                    {
                        mHandler.sendEmptyMessage(what ++);//“aaa”子线程发送
                    }
                }.start();
            }
        });
        new Thread("自定义消息队列")
        {//单线程处理所有线程发过来的消息,会以队列的顺序排队执行
            public void run()
            {
                Looper.prepare();
                //查看prepare()里80行和189行,创建了messageQueue、looper
                mHandler = new Handler(Looper.myLooper())
                //Looper.myLooper()得到当前线程的looper
                {
                    //handler在哪个线程处理消息,取决于Looper在哪个线程创建
                    @Override
                    public void handleMessage(Message msg)
                    {
                        String content = "当前线程:" + Thread.currentThread().getName() + "msg:" + msg.what;
                        Toast.makeText(MainActivity.this, content, Toast.LENGTH_SHORT).show();
                    }
                };
                Looper.loop();//looper开始轮循队列
            }
        }.start();
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}



注意:

在子线程中直接new handle()会出现以下错误,是因为子线程中默认没有创建Looper对象,需要先调用Looper.prepare()方法启用Looper。主线程除外,主线程系统会自动为其创建Looper对象,开启消息循环。

E/AndroidRuntime( 6173): Uncaught handler: thread Thread-8 exiting due to uncaught exception
E/AndroidRuntime( 6173): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()


2. HandlerThread

封装了Thread和Looper、MessageQueue

public class MainActivity extends Activity
{
    private Handler mHandler;
    int what = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button1).setOnClickListener(new OnClickListener()
        {
                                                                                                                                                                                                                                                                                                           
            @Override
            public void onClick(View v)
            {
                mHandler.sendEmptyMessage(what ++);//主线程发送
                new Thread("aaa")
                {
                    public void run()
                    {
                        mHandler.sendEmptyMessage(what ++);//“aaa”子线程发送
                    }
                }.start();
            }
        });
//      因为HandlerThread()里面已经封装好了Looper.prepare()和Looper.loop();
        HandlerThread thread = new HandlerThread("自定义消息队列");
        thread.start();
        //thread.getLooper()如果换成Looper.myLooper()就是得到主线程的looper
        mHandler = new Handler(thread.getLooper())
        {
            //handler在哪个线程处理消息,取决于Looper在哪个线程创建
            @Override
            public void handleMessage(Message msg)
            {
                String content = "当前线程:" + Thread.currentThread().getName() + "msg:" + msg.what;
                Toast.makeText(MainActivity.this, content, Toast.LENGTH_SHORT).show();
            }
        };
                                                                                                                                                                                                                                                                                                       
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
}



3. IntentService

Thread、Looper、MessageQueue、Handler、Message


MainActivity中显式意图启动service

public class MainActivity extends Activity
{
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button1).setOnClickListener(new OnClickListener()
        {
                                                                                                                                                                                                                                                                                                 
            @Override
            public void onClick(View v)
            {//启动MyService,传值过去
                Intent service = new Intent(MainActivity.this,MyService.class);
                service.putExtra("msg", "aaa");
                startService(service );
            }
        });
    }
}


MyService继承了IntentService,接收到MainActivity传来的值

public class MyService extends IntentService
{
    //封装好了handleMessage();64行
//  写好了HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
//    thread.start();
    public MyService()
    {//IntentService有个有参的构造方法75行
        super("消息队列IntentService");
    }
    @Override
    public IBinder onBind(Intent intent)
    {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }
    @Override
    protected void onHandleIntent(Intent intent)
    {
        String extra = intent.getStringExtra("msg");
        String content = "当前线程:" + Thread.currentThread().getName() + "msg:" + extra;
        Log.e("onHandleIntent", content);
    }
}