我的代码如下:
activitymain.xml:
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"
tools:context=".MainActivity"
android:orientation="vertical">
android:id="@+id/t1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点击这里进行消息传递"/>
android:id="@+id/t2"
android:layout_width="192dp"
android:layout_height="49dp" />
MainActivity.java
package com.example.test3;
import android.os.Bundle;
import android.widget.TextView;
import android.app.Activity;
import android.view.Menu;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.widget.Button;
import android.view.View;
import android.view.View.OnClickListener;
public class MainActivity extends Activity {
Button but=null;
TextView textview=null;
Handler handler1,handler2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
but=(Button)super.findViewById(R.id.t1);
textview=(TextView)super.findViewById(R.id.t2);
Print p=new Print();
p.start();
handler1=new Handler()
{
public void HandleMessage(Message msg)
{
if(msg.what==101)
MainActivity.this.textview.setText(msg.getData().getString("toMain").toString());
}
};
but.setOnClickListener(new OnClickListenerimpl());
}
@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;
}
class Print extends Thread
{
public void run()
{
final Message msgReply=handler1.obtainMessage();
Looper.prepare();
handler2=new Handler(){
public void handleMessage(Message msg)
{
if(msg.what==100)
System.out.println("接收到了来自主线程的消息");
msgReply.what=101;
Bundle bundle=new Bundle();
bundle.putString("toMain", "返回的消息");
msgReply.setData(bundle);
handler1.sendMessage(msgReply);
}
};
Looper.loop();
}
}
class OnClickListenerimpl implements OnClickListener
{
public void onClick(View v)
{
if(MainActivity.this.handler2 != null)
{Message msg=handler2.obtainMessage();
msg.what=100;
handler2.sendMessage(msg);
}
}
}
}
然后,如下是logcat:
运行程序后,当按下一次按钮后,logcat里只会出现”接收到了来自主线程的消息“,如图中的第一行。但是等待一段时间该程序仍不会显示”返回的消息“,然后再按下一次按钮,一下子logcat就会弹出图中除第一行外的提示信息(图中最高两行是”接收到了来自主线程的消息“,第一个是第一次按按钮弹出的,第二个及以下的是第二次按下按钮弹出的”)。同时程序会强制退出,并提示“抱歉,已强行关闭”。
希望大家能帮我看看是怎么回事?
试着把final Message msgReply放到handler2的handleMessage里,每次收到主线程消息之后再获得一个Message对象用来回复,而不是在run里定义一个然后一直用
handler1=new Handler()
{
public void HandleMessage(Message msg)
{
if(msg.what==101)
MainActivity.this.textview.setText(msg.getData().getString("toMain").toString());
}
};
handler2=new Handler(){
public void handleMessage(Message msg)
{
if(msg.what==100)
System.out.println("接收到了来自主线程的消息");
msgReply.what=101;
Bundle bundle=new Bundle();
bundle.putString("toMain", "返回的消息");
msgReply.setData(bundle);
handler1.sendMessage(msgReply);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
//............省略
}
把创建的代码放在外面试试。
handler1 = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
if (msg.what == 101)
MainActivity.this.textview.setText(msg.getData().getString("toMain").toString());
}
};
1、你对比下,你会发现你handler1 里面的 public void HandleMessage(Message msg) 写错了(你仔细看下),并没有覆盖父类的 handleMessage(Message msg)
2、final Message msgReply=handler1.obtainMessage(); 这句话是有问题的。 会报消息复用的异常
写到全局: Message msgReply;
写到 handler2 中的handleMessage(Message msg)方法中
msgReply = handler1.obtainMessage();
msgReply.what = 101;
public class MainActivity extends ActionBarActivity {
Button but = null;
TextView textview = null;
Handler handler1, handler2;
Message msgReply;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
but = (Button) super.findViewById(R.id.t1);
textview = (TextView) super.findViewById(R.id.t2);
Print p = new Print();
= new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
if (msg.what == 101)
MainActivity.this.textview.setText(msg.getData().getString("toMain").toString());
}
};
p.start();
but.setOnClickListener(new OnClickListenerimpl());
}
class Print extends Thread {
public void run() {
Looper.prepare();
handler2 = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 100)
System.out.println("接收到了来自主线程的消息");
msgReply = handler1.obtainMessage();
msgReply.what = 101;
Bundle bundle = new Bundle();
bundle.putString("toMain", "返回的消息");
msgReply.setData(bundle);
handler1.sendMessage(msgReply);
}
};
Looper.loop();
}
}
class OnClickListenerimpl implements OnClickListener {
public void onClick(View v) {
if (MainActivity.this.handler2 != null) {
Message msg = handler2.obtainMessage();
msg.what = 100;
handler2.sendMessage(msg);
}
}
}
@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;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
package com.example.threadtest;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
Button button=null;
TextView textView=null;
Handler handler1,handler2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button=(Button)findViewById(R.id.t1);
textView=(TextView)findViewById(R.id.t2);
button.setOnClickListener(new OnClickListenerImpl());
handler1=new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what==101){
textView.setText(msg.getData().getString("toMain").toString());
}
super.handleMessage(msg);
}
};
Print print=new Print();
print.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;
}
class Print extends Thread{
@Override
public void run() {
super.run();
Looper.prepare();
handler2=new Handler(){
@Override
public void handleMessage(Message msg) {
if(msg.what==100)
System.out.println("接收到来自主线程的消息");
Message msgReply=handler1.obtainMessage();
msgReply.what=101;
Bundle bundle=new Bundle();
bundle.putString("toMain", "返回的消息");
msgReply.setData(bundle);
handler1.sendMessage(msgReply);
super.handleMessage(msg);
}
};
Looper.loop();
}
}
class OnClickListenerImpl implements OnClickListener{
@Override
public void onClick(View v) {
if(MainActivity.this.handler2!=null){
Message msg=handler2.obtainMessage();
msg.what=100;
handler2.sendMessage(msg);
}
}
}
}
结果: