Handler机制学习

  • handler的由来
    当程序第一次启动时,Android会同时启动一条主线程(Main Thread)来负责处理与UI相关的事件,我们也将其称为“UI线程”。处于性能优化考虑,Android的UI操作并不是线程安全的,意味着如果多个线程并发操作UI线程,可能导致线程安全问题。
    为了解决多线程问题——Android平台只允许UI线程修改Activity里的UI组件,就会导致新启动的线程无法改变界面组建的属性值。而如果我们把所有工作都放在主线程里,则会抛出ANR异常。
    所以,Handler机制应运而生。其设计思路为:
    把一些比较长的消息,放在一个单独的线程里面处理,把处理以后的结果,返回给主线程运行,通过Handler来进行二者间的通信。
  • Handler的作用
  1. 在新启动的线程中发送消息。使用Handler对象的sendMessage()方法或者sendEmptyMessage方法发送消息。
  2. 在主线程中获取处理消息。重写Handler类中处理消息的方法(void handlerMessage(Message msg)),当新启动的线程发送消息时,消息发送到与之关联的MessageQueue。而Handler不断地从MessageQueue中获取并处理消息。
  • Handler的使用与运作流程
  1. 首先需要进行Handler声明,覆写handleMessage方法(放在主线程中)
  2. 子线程发送Message给UI线程表示自己任务已经执行完成,主线程可以做相应的操作。
  3. 运作流程:
  • Handler三大角色
  • Handler:处理者,负责发送和处理消息
    发送消息,把消息发送给Looper管理的MessageQueue
    处理消息,负责处理Looper分发给它的消息
  • MessageQueue和Message:消息的载体,Handler接收和处理的消息对象。
  • Looper:每个线程只有一个Looper,它负责管理对应的MessageQueue,会不断地从MessageQueue中取出消息,并将消息分发给对应的Handler处理。
  • 基于Handler Post()方法的小Demo
  • activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.example.wangli.handlerdemo.MainActivity">

    <ProgressBar
        android:id="@+id/progressBar1"
        android:max="100"
        android:progress="0"
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="当前进度为:0"/>

    <Button
        android:id="@+id/button_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Start"/>

</LinearLayout>
  • MainActivity.java
package com.example.wangli.handlerdemo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class MainActivity extends Activity {

    ProgressBar pb;
    TextView tv;
    Handler handler = new Handler();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        pb = (ProgressBar) findViewById(R.id.progressBar1);
        tv = (TextView)findViewById(R.id.textView);
        Button btn = (Button) findViewById(R.id.button_start);



        btn.setOnClickListener(new View.OnClickListener(){
            int i = 0;
            @Override
            public void onClick(View v){
                //开启一个新线程
                new Thread(){
                    public void run(){

                        while (i < 100){
                            //将线程添加到消息队列
                            handler.post(new Runnable(){
                                public void run(){
                                    //更新UI
                                    pb.setProgress(i++);
                                    tv.setText("当前进度:"+ i);
                                }
                            });
                            //线程睡眠
                            try{
                                Thread.sleep(200);
                            }catch (InterruptedException e){
                                e.printStackTrace();
                            }
                        }

                    }
                }.start();
            }

        });

    }
}
  • 运行效果图

android bindthread 上限 android handlerthread机制_android

android bindthread 上限 android handlerthread机制_主线程_02

  • 基于Handler sendMessage()
package com.example.wangli.handlerdemo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class MainActivity extends Activity {

    ProgressBar pb;
    TextView tv;
    Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            int progress = msg.what;
            pb.setProgress(progress);
            tv.setText("当前进度为:"+progress);
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        pb = (ProgressBar) findViewById(R.id.progressBar1);
        tv = (TextView)findViewById(R.id.textView);
        Button btn = (Button) findViewById(R.id.button_start);



        btn.setOnClickListener(new View.OnClickListener(){
            int i = 0;
            @Override
            public void onClick(View v){
                //开启一个新线程
                new Thread(){
                    public void run(){

                        while (i < 100){

                            Message msg = Message.obtain();
                            msg.what = i++;
                            handler.sendMessage(msg);

                            //线程睡眠
                            try{
                                Thread.sleep(200);
                            }catch (InterruptedException e){
                                e.printStackTrace();
                            }
                        }

                    }
                }.start();
            }

        });

    }
}