概述:

Handler 是Android Sdk封装好的一个线程间消息处理(通信)的一个类。在android中比较典型的应用就是异步加载数据,主线程更新ui(这种模式是由android操作系统所决定),虽然说在android开发中利用hanlder更新ui比较常用,但其本质上解决的还是线程间通信问题,我们完全也可以通过Hanlder实先多线程间协同工作问题。

例子1:主线程更新ui
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.widget.TextView;

public class HandlerActivity extends AppCompatActivity {

    private TextView tvContent;
    private  Handler mHandler ;
    private boolean isEnd = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        //实例化TextView和mHanlder
        tvContent =  (TextView) findViewById(R.id.tv_content);
        mHandler= new Handler(){
                @Override
                public void handleMessage(Message msg) {
                    //主线程处理ui
                    tvContent.setText((String)msg.obj);
                }

        };

    }

    public void startThreadWork(){
        //开启子线程模拟耗时操作
        new Thread(){
            @Override
            public void run() {
                int count =0;
                while(!isEnd){
                    try {
                        //线程休眠,模拟耗时操作
                        sleep(1000);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    Message message = Message.obtain();
                    message.obj ="您好"+count;
                    mHandler.sendMessage(message);
                    count++;
                }

            }
        }.start();

    }

  @Override
    protected void onDestroy() {
        mHandler.removeCallbacksAndMessages(null);
        isEnd = true;
        super.onDestroy();
    }
}

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.weiwei.testjni.HandlerActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    
    <TextView
        android:textSize="28sp"
        android:id="@+id/tv_content"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"
        android:padding="16dp"

        />

</android.support.design.widget.CoordinatorLayout>

运行结果:

android holder设定对象造成数据滚乱 android holder的使用_android

除了通过调用Hanlder.sendMessage()方法外,也可以通过调用Hanlder.post方法传递更新消息,列子如下。

import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.widget.TextView;

public class HandlerActivity extends AppCompatActivity {

    private TextView tvContent;
    private  Handler mHandler ;
    private boolean isEnd = false;
@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        //实例化TextView和mHanlder
        tvContent =  (TextView) findViewById(R.id.tv_content);
        mHandler = new Handler();
        //开启子线程模拟耗时操作
        startThreadWork();

    }
    int count =0;
    public void startThreadWork(){
        //开启子线程模拟耗时操作
        new Thread(){
            @Override
            public void run() {

                while(!isEnd){
                    try {
                        //线程休眠,模拟耗时操作
                        sleep(1000);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            tvContent.setText("您好"+count);
                        }
                    });
                    count++;
                }

            }
        }.start();

    }

    @Override
    protected void onDestroy() {
        mHandler.removeCallbacksAndMessages(null);
        isEnd = true;
        super.onDestroy();
    }
}



说明:当在主线程实例化一个Handler后,会自动将主线程Looper绑定到Handler上(主线程looper是在应用启动的时候生成),当调用发送message的方法时,便会将messager添加到Looper维护的一个消息队列上,而主线程的Looper.looper方法则会遍历将message取出来,并调用message的分发处理方法。也就是在主线程实例化Handler的HandlerMessager方法。

例子2:三个子线程模拟生产者消费者
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.widget.TextView;

public class HandlerActivity extends AppCompatActivity {


    private Handler mHanlder1;
    private Handler mHanlder2;
    private static final String TAG = "HandlerActivity";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        //开启两个消费子线程
        startThreadWork1();
        startThreadWork2();
        //开启一个生成子线程
        startThreadWork();

    }

    public void startThreadWork1(){
        new Thread("ConsumThread1"){
            @Override
            public void run() {
                Looper.prepare();
                mHanlder1 = new Handler(){

                    @Override
                    public void handleMessage(Message msg) {
                        try {
                            //线程休眠,模拟消费时间
                            sleep(500);
                        }catch (InterruptedException e){
                            e.printStackTrace();
                        }
                        Log.d(TAG, "------------------------------------------");
                        Log.d(TAG, "消费线程名称: "+Thread.currentThread().getName());
                        Log.d(TAG, "handleMessage: 消费"+(String)msg.obj);

                    }
                };
                Looper.loop();

            }
        }.start();


    }

    public void startThreadWork2(){
        new Thread("ConsumThread2"){
            @Override
            public void run() {
                Looper.prepare();
                mHanlder2 = new Handler(){

                    @Override
                    public void handleMessage(Message msg) {
                        try {
                            //线程休眠,模拟消费时间
                            sleep(800);
                        }catch (InterruptedException e){
                            e.printStackTrace();
                        }
                        Log.d(TAG, "------------------------------------------");
                        Log.d(TAG, "消费线程名称: "+Thread.currentThread().getName());
                        Log.d(TAG, "handleMessage: 消费"+(String)msg.obj);
                    }
                };
                Looper.loop();

            }
        }.start();

    }



    int count =0;
    public void startThreadWork(){
        //开启子线程模拟耗时操作
        new Thread("ProuceThread"){
            @Override
            public void run() {

                while(!isEnd){
                    try {
                        //线程休眠,模拟生产时间
                        sleep(500);
                    }catch (InterruptedException e){
                        e.printStackTrace();
                    }
                    Message message = Message.obtain();
                    message.obj="生成内容"+count;
                    Log.d(TAG, "------------------------------------------");
                    Log.d(TAG, "生产线程名称: "+Thread.currentThread().getName());
                    Log.d(TAG, "生产内容: "+message.obj);
                    if(count%2!=0){
                        mHanlder1.sendMessage(message);

                    }else{
                        mHanlder2.sendMessage(message);

                    }
                    count++;
                }

            }
        }.start();

    }

  }

运行结果:

android holder设定对象造成数据滚乱 android holder的使用_ide_02

说明:例子2为多线程间通过hanlder传递消息的代码逻辑。但有一点需要说明,这样使用hanlder有可能出现内存泄漏,解决hanlder内存泄漏问题可以参考Hanlder内存泄漏解决。

本文只是描述一下hanlder的基本使用,希望对您有所帮助。