码迷,mamicode.com
首页 > 移动开发 > 详细

Android中的多线程编程(二)Handler的原理(附源码)

时间:2015-07-26 17:23:07      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:

Android中Handler的原理

一.Handler的原理:

1.Handler、Looper、MessageQueue之间的关系。

(1).Handler类:向MessageQueue消息队列中发送消息,接收Looper返回来的消息并处理。

(2).Looper类: 存储消息队列的容器。负责接收Handler发送的消息,并直接把消息回传给Handler自己。

(3).MessageQueue类:存储消息。

2.关系:

(1).创建Handler对象的时候,它就会绑定到默认的线程(UI线程)中,这个线程中就会有一个消息队列。

private Handler mHandler = new Handler() {
    public void handleMessage(android.os.Message msg) {
        Log.d(TAG, "主线程 Thread UI:" + Thread.currentThread().getId());
        mView.setText("111");
    };
}; 

(2).如果是新开启一个子线程,在该线程中操作Handler的时候,就要自己创建一个Looper对象,从而找到相应的消息队列。也就是说Handle和Looper是相互关联的。

package com.chengdong.su.handlerdemo;

import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.os.Build;

/**
 * 
 * @author scd
 * 
 */
public class ThridActivity extends Activity {
    private String TAG = getClass().getSimpleName();
    private TextView mView;
    private MyThread mThread;
    /**
     * 创建一个默认的Handler
     */
    private Handler mHandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            Log.d(TAG, "-------UI Thread:" + Thread.currentThread().getId());
            mView.setText("你好");
        };

    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
        mThread = new MyThread();
        mThread.start();
        try {
            mThread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        // 子线程
        mThread.myHandler.sendEmptyMessage(0);
        // 主线程
        mHandler.sendEmptyMessage(1);
    }

    private void init() {
        mView = (TextView) findViewById(R.id.textView1);
    }

    /**
     * 自定义的Thread
     * 
     * @author scd
     * 
     */
    public class MyThread extends Thread {
        public Handler myHandler;

        @Override
        public void run() {
            Looper.prepare();
            myHandler = new Handler() {
                @Override
                public void handleMessage(Message msg) {
                    super.handleMessage(msg);
                    Log.d(TAG, "------>Thread:"
                            + Thread.currentThread().getId());
                    System.out.println("---子线程----");

                }
            };
            // 循环处理消息
            Looper.loop();

        }

    }

}

但是使用以上的方式会出现多线程并发导致的空指针问题,为了避免这个问题,谷歌给我们封装了一个很好用的类:HandlerThread类。

3.HandlerThread类:

(1).解决多线程并发导致的空指针问题。
HandlerThread的使用代码如下:

package com.chengdong.su.handlerdemo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;

/**
 * 
 * @author scd
 * 
 */
public class FourActivity extends Activity {
    private String TAG = getClass().getSimpleName();
    private String mName = "HandlerThread";
    private HandlerThread mThread;
    private Handler mHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 封装类
        mThread = new HandlerThread(mName);
        // 开启线程
        mThread.start();
        // 方式一:Handler是在子线程
        mHandler = new Handler(mThread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                Log.d(TAG, "---子线程----HandlerThread :"
                        + Thread.currentThread().getId());

            }
        };
        // 方式二:Handler是在主线程
        mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                Log.d(TAG, "---主线程 UI----HandlerThread :"
                        + Thread.currentThread().getId());

            }
        };
        mHandler.sendEmptyMessage(0);
        Log.d(TAG, "---主线程----UIThread :" + Thread.currentThread().getId());

    }
}       

注:方式一中的mHandler是运行在子线程中的,可以在该Handler中处理耗时的异步任务,发送消息,处理消息等。

(2).Android中主线程和子线程之间的通信:

A:子线程发送给主线程消息:让主线程更新UI界面
B:主线程发送给子线程消息:让子线程做相应的逻辑处理。
代码如下:

package com.chengdong.su.handlerdemo;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

/**
 * 主线程和子线程之间进行互相的发送消息,进行通信
 * 
 * @author scd
 * 
 */
public class FiveActivity extends Activity implements OnClickListener {
    private String TAG = getClass().getSimpleName();
    private String mName = "HandlerThread";
    // 初始化主线程的Handler
    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            Message message = new Message();
            // 主线程发送给子线程消息
            mThreadHandler.sendMessageDelayed(message, 1000);
            Log.d(TAG, "-------->主线程发送给子线程消息");

        };
    };
    // 子线程对象
    private HandlerThread mThread;
    // 子线程的Handler
    private Handler mThreadHandler;

    private Button mButton1;
    private Button mButton2;

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

    /**
     * init the View
     */
    private void init() {
        mButton1 = (Button) findViewById(R.id.button1);
        mButton2 = (Button) findViewById(R.id.button2);
        mButton1.setOnClickListener(this);
        mButton2.setOnClickListener(this);
        // 初始化子线程的Handler
        mThread = new HandlerThread(mName);
        mThread.start();
        // 初始化子线程中的Handler
        mThreadHandler = new Handler(mThread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                Message message = new Message();
                mHandler.sendMessageDelayed(message, 1000);
                Log.d(TAG, "-------->子线程发送给主线程消息");

            }
        };
        Log.d(TAG, "------->init主线程");

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.button1: {
            // 主线程发送消息
            mHandler.sendEmptyMessage(0);

            break;
        }
        case R.id.button2: {
            // 取消消息
            mHandler.removeMessages(0);

            break;
        }

        default:
            break;
        }

    }

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

Android中的多线程编程(二)Handler的原理(附源码)

标签:

原文地址:http://blog.csdn.net/u014225510/article/details/47069481

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!