1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 多线程 主线程与子线程的通信Handler Message sendmessage与handlemessage obtainmessage

多线程 主线程与子线程的通信Handler Message sendmessage与handlemessage obtainmessage

时间:2021-09-15 05:29:42

相关推荐

多线程 主线程与子线程的通信Handler Message sendmessage与handlemessage obtainmessage

android是单线程的,在子线程中是不能修改UI线程的任何操作,所以要用一种方式让子线程中的信息返回到主线程中再做修改。这就要让主线程与子线程通信。

那如何让它们之间进行通信呢?我们用Handler这个类。Handler操作的是Message。在主线程中,消息队列是在程序启动时就自动生成的,而子线程要自己手动建立消息队列 ,Looper是用来管理消息队列的。

那么什么才是关键呢?首先,要明白Handler都是在主线程中的,也就是说,Handler类就都在主线程中运行,通俗的说就是“绑定”在主线程中。第二,Handler的触发是通过SendMessage()这个方法驱动的,注意,sendMessage 和 handleMessage这一对,一个负责发一个负责收。是哪个Handler发出的,就由哪个Handler去接收。这样msg 就不会混乱了。第三,开启一个线程唯一的方式就是执行start()方法。而只执行run()方法的,线程还是运行在主线程中。如图:

而我们要的是这样的,如图:

要让主线程与子线程通信,则用Handler 操作Message.如图:

好了看下代码吧,分享下:

MainActivity:

package com.bivin;

import android.app.Activity;

import android.os.Bundle;

import android.os.Handler;

import android.os.Looper;

import android.os.Message;

import android.util.Log;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.TextView;

public class MainActivity extends Activity {

private Handler mMainHandler, mChildHandler;

private TextView tv;

private Button b;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

tv = (TextView) findViewById(R.id.tv);

b = (Button) findViewById(R.id.btn);

Log.i("tag",Thread.currentThread().getName());

mMainHandler= new Handler() {

@Override

public void handleMessage(Message msg) {

Log.i("tag",Thread.currentThread().getName());

//Log.i("TAG", "Got an incoming message from the child thread - "

//+ (String) msg.obj);

tv.setText((String) msg.obj);

super.handleMessage(msg);

}

};

newChildThread().start();

b.setOnClickListener(new View.OnClickListener() {

public void onClick(View v) {

if (mChildHandler != null) {

Log.i("tag",Thread.currentThread().getName());

Message childmsg = mChildHandler.obtainMessage();

childmsg.obj = mMainHandler.getLooper().getThread()

.getName()

+ " hello!,This is mainactivity";

mChildHandler.sendMessage(childmsg);

Log.i("TAG", "Send a message to the child thread - "

+ (String) childmsg.obj);

}

}

});

}

@Override

protected void onDestroy() {

Log.i("TAG", "Stop looping the child thread's message queue");

mChildHandler.getLooper().quit();

super.onDestroy();

}

private class ChildThread extends Thread {

@Override

public void run() {

this.setName("childthread");

Looper.prepare();

mChildHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

Log.i("TAG",

"Got an incoming message from the main thread - "

+ (String) msg.obj);

try {

sleep(10000);

Message toMain = mMainHandler.obtainMessage();

toMain.obj = "this is"

+ this.getLooper().getThread().getName()

+ ". do you send me" + (String) msg.obj + "?";

mMainHandler.sendMessage(toMain);

Log.i("TAG", "Send a message to the main thread - "

+ (String) toMain.obj);

} catch (InterruptedException e) {

e.printStackTrace();

}

super.handleMessage(msg);

}

};

Log.i("TAG", "Child handler is bound to - "

+ mChildHandler.getLooper().getThread().getName());

Looper.loop();

}

}

}

andriod提供了 Handler 和 Looper

* 来满足线程间的通信。例如一个子线程从网络上下载了一副图片,当它下载完成后会发送消息给主线程,这个消息是通过绑定在主线程的Handler来传递的。

* 在Android

* ,这里的线程分为有消息循环的线程和没有消息循环的线程,有消息循环的线程一般都会有一个Looper,这个是android的新概念。我们的主线程

* (UI线程)就是一个消息循环的线程

* 。针对这种消息循环的机制,我们引入一个新的机制Handler,我们有消息循环,就要往消息循环里面发送相应的消息,自定义消息一般都会有自己对应的处理

* ,消息的发送和清除,把这些都封装在Handler里面,注意Handler只是针对那

* 些有Looper的线程,不管是UI线程还是子线程,只要你有Looper,我就可以往你的消息队列里面添加东西,并做相应的处理。

* 但是这里还有一点,就是只要是关于UI相关的东西,就不能放在子线程中,因为子线程是不能操作UI的,只能进行数据、系统等其他非UI的操作。

*

* 一个Handler的创建它就会被绑定到这个线程的消息队列中,如果是在主线程创建的,那就不需要写代码来创建消息队列了,默认的消息队列会在主线程被创建。

* 但是如果是在子线程的话,就必须在创建Handler之前先初始化线程的消息队列。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。