一般而言,Android的子线程中如果要显示UI相关,需要在显示的前后添加Looper.prepare和Looper.loop.但是实践中发现点问题,代码如下,并且把问题标志出来了。在第一个子线程MyThread2开头可以显示对话框,但是后面的对话框以及MyThread3中用同样方法却显示不了。
网上说应该只有一个Looper处理消息循环,但是我的多个子线程中均要在多处显示对话框该怎么办。而且我通过handmessage在UI现场中处理消息并显示对话框,也没显示出来。不知道是怎么回事?package com.example.testusb;import java.nio.ByteBuffer;
import java.util.HashMap;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbRequest;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import android.os.*;public class TestUSB extends Activity { private Button button,button2;
private UsbManager usbManager;
private UsbDevice usbDevice;
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private PendingIntent pendingIntent;
Intent intent;
StringBuffer sb = new StringBuffer();
private TextView info;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case 3:
createAlert("TestUSB","33333333333333333");----------------------------------------这两个地方均没有显示出对话框或者toast
Toast.makeText(TestUSB.this, "33333333333333333", 1000).show();
break;
case 4:
createAlert("TestUSB","44444444444444444");
Toast.makeText(TestUSB.this, "44444444444444444", 1000).show();
break; }
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_l);
button = (Button) findViewById(R.id.button);
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new MyThread2().start();
}
});
}
class MyThread2 extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
Looper.prepare();
createAlert("Waring","MyThread2 start");----------------------------------------------这个地方的对话框可以显示出来
Looper.loop();
try {
HashMap<String, UsbDevice> map = usbManager.getDeviceList();
if (map.isEmpty()) {
Looper.prepare();
createAlert("Waring","Empty devicelist");------------------------这个地方和以下所有调用createAlert的地方对话框均显示不出来
Looper.loop();
}
else
{
for(UsbDevice device : map.values()){
Log.e("device", "vid:"+device.getVendorId()+" pid:"+device.getProductId()+" "+device.getDeviceName());
if(5334 == device.getVendorId())
{
usbDevice = device;
}
createAlert("Warning","vid:"+device.getVendorId()+" pid:"+device.getProductId()+" "+device.getDeviceName());
}
if(usbManager.hasPermission(usbDevice)){
handler.sendEmptyMessage(3);
Looper.prepare();
createAlert("Waring","MyThread3 start");
Looper.loop();
new MyThread3().start();
}else{
handler.sendEmptyMessage(4);
Looper.prepare();
createAlert("Waring","requestPermission");
Looper.loop();
usbManager.requestPermission(usbDevice, pendingIntent);
}
}
/* for(UsbDevice device : map.values()){
sb.append( "vid:"+device.getVendorId()+" pid:"+device.getProductId()+" "+device.getDeviceName());
sb.append("\n");
info.setText(sb);
Log.e("device", "vid:"+device.getVendorId()+" pid:"+device.getProductId()+" "+device.getDeviceName());
//VendorID 鍜?ProductID 鍗佽繘鍒?
// if(5334 == device.getVendorId() && 12290 == device.getProductId())
if(5334 == device.getVendorId())
{
usbDevice = device;
}
createAlert("Warning","vid:"+device.getVendorId()+" pid:"+device.getProductId()+" "+device.getDeviceName());
}
if(usbManager.hasPermission(usbDevice)){
handler.sendEmptyMessage(3);
sb.append("MyThread3 start");
sb.append("\n");
info.setText(sb);
Looper.prepare();
createAlert("Waring","MyThread3 start");
Looper.loop();
new MyThread3().start();
}else{
handler.sendEmptyMessage(4);
sb.append("requestPermission");
sb.append("\n");
info.setText(sb);
Looper.prepare();
createAlert("Waring","requestPermission");
Looper.loop();
usbManager.requestPermission(usbDevice, pendingIntent);
}*/
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class MyThread3 extends Thread{
@Override
public void run() {
Looper.prepare();
createAlert("Warning","My thread3 receive data");
Looper.loop();
}
private void createAlert(String strTitle, String strMsg) {
Dialog alertDialog = new AlertDialog.Builder(TestUSB.this)
.setTitle(strTitle).setMessage(strMsg)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// TODO Auto-generated method stub
setResult(RESULT_OK, intent);
//finish();
}
}).create(); alertDialog.show();
}
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.e( "action", action);
sb.append("action start");
sb.append("\n");
info.setText(sb);
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
usbDevice = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
handler.sendEmptyMessage(1);
if(usbDevice != null){
sb.append("BroadcastReceiver MyThread3 start");
sb.append("\n");
info.setText(sb);
new MyThread3().start();
}
}
else {
sb.append("permission denied for device"+usbDevice.toString());
sb.append("\n");
info.setText(sb);
Log.d("denied", "permission denied for device " + usbDevice);
}
}
}
}
};}
网上说应该只有一个Looper处理消息循环,但是我的多个子线程中均要在多处显示对话框该怎么办。而且我通过handmessage在UI现场中处理消息并显示对话框,也没显示出来。不知道是怎么回事?package com.example.testusb;import java.nio.ByteBuffer;
import java.util.HashMap;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbRequest;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import android.os.*;public class TestUSB extends Activity { private Button button,button2;
private UsbManager usbManager;
private UsbDevice usbDevice;
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private PendingIntent pendingIntent;
Intent intent;
StringBuffer sb = new StringBuffer();
private TextView info;
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case 3:
createAlert("TestUSB","33333333333333333");----------------------------------------这两个地方均没有显示出对话框或者toast
Toast.makeText(TestUSB.this, "33333333333333333", 1000).show();
break;
case 4:
createAlert("TestUSB","44444444444444444");
Toast.makeText(TestUSB.this, "44444444444444444", 1000).show();
break; }
}
};
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_l);
button = (Button) findViewById(R.id.button);
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
new MyThread2().start();
}
});
}
class MyThread2 extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
Looper.prepare();
createAlert("Waring","MyThread2 start");----------------------------------------------这个地方的对话框可以显示出来
Looper.loop();
try {
HashMap<String, UsbDevice> map = usbManager.getDeviceList();
if (map.isEmpty()) {
Looper.prepare();
createAlert("Waring","Empty devicelist");------------------------这个地方和以下所有调用createAlert的地方对话框均显示不出来
Looper.loop();
}
else
{
for(UsbDevice device : map.values()){
Log.e("device", "vid:"+device.getVendorId()+" pid:"+device.getProductId()+" "+device.getDeviceName());
if(5334 == device.getVendorId())
{
usbDevice = device;
}
createAlert("Warning","vid:"+device.getVendorId()+" pid:"+device.getProductId()+" "+device.getDeviceName());
}
if(usbManager.hasPermission(usbDevice)){
handler.sendEmptyMessage(3);
Looper.prepare();
createAlert("Waring","MyThread3 start");
Looper.loop();
new MyThread3().start();
}else{
handler.sendEmptyMessage(4);
Looper.prepare();
createAlert("Waring","requestPermission");
Looper.loop();
usbManager.requestPermission(usbDevice, pendingIntent);
}
}
/* for(UsbDevice device : map.values()){
sb.append( "vid:"+device.getVendorId()+" pid:"+device.getProductId()+" "+device.getDeviceName());
sb.append("\n");
info.setText(sb);
Log.e("device", "vid:"+device.getVendorId()+" pid:"+device.getProductId()+" "+device.getDeviceName());
//VendorID 鍜?ProductID 鍗佽繘鍒?
// if(5334 == device.getVendorId() && 12290 == device.getProductId())
if(5334 == device.getVendorId())
{
usbDevice = device;
}
createAlert("Warning","vid:"+device.getVendorId()+" pid:"+device.getProductId()+" "+device.getDeviceName());
}
if(usbManager.hasPermission(usbDevice)){
handler.sendEmptyMessage(3);
sb.append("MyThread3 start");
sb.append("\n");
info.setText(sb);
Looper.prepare();
createAlert("Waring","MyThread3 start");
Looper.loop();
new MyThread3().start();
}else{
handler.sendEmptyMessage(4);
sb.append("requestPermission");
sb.append("\n");
info.setText(sb);
Looper.prepare();
createAlert("Waring","requestPermission");
Looper.loop();
usbManager.requestPermission(usbDevice, pendingIntent);
}*/
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class MyThread3 extends Thread{
@Override
public void run() {
Looper.prepare();
createAlert("Warning","My thread3 receive data");
Looper.loop();
}
private void createAlert(String strTitle, String strMsg) {
Dialog alertDialog = new AlertDialog.Builder(TestUSB.this)
.setTitle(strTitle).setMessage(strMsg)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// TODO Auto-generated method stub
setResult(RESULT_OK, intent);
//finish();
}
}).create(); alertDialog.show();
}
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.e( "action", action);
sb.append("action start");
sb.append("\n");
info.setText(sb);
if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
usbDevice = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
handler.sendEmptyMessage(1);
if(usbDevice != null){
sb.append("BroadcastReceiver MyThread3 start");
sb.append("\n");
info.setText(sb);
new MyThread3().start();
}
}
else {
sb.append("permission denied for device"+usbDevice.toString());
sb.append("\n");
info.setText(sb);
Log.d("denied", "permission denied for device " + usbDevice);
}
}
}
}
};}
你把Loop相关的代码都去掉,都改成handler.sendEmptyMessage(×××),然后统一在handler里面处理吧,显示Toast或者Dialog都随您便。
但是你不应该在一个线程里先后显示几个Dialog,这样后面的Dialog直接覆盖显示在前面的Dialog上,你点击确定,前面的Dialog显示了以后,后面的才会显示。
建议你不要用这么多Dialog和Toast,没什么意义,用Log跟踪一下流程好一点。
package package com.example.testusb;import java.nio.ByteBuffer;
import java.util.HashMap;import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbManager;
import android.hardware.usb.UsbRequest;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import android.os.*;public class TestUSB extends Activity { private Button button, button2;
private UsbManager usbManager;
private UsbDevice usbDevice;
private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
private PendingIntent pendingIntent; Intent intent;
StringBuffer sb = new StringBuffer();
private TextView info; private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
//这里增加对case 1和2的处理
case 3:
// createAlert("TestUSB", "33333333333333333");// ----------------------------------------这两个地方均没有显示出对话框或者toast
Toast.makeText(TestUSB.this, "33333333333333333", 1000).show();
break;
case 4:
// createAlert("TestUSB", "44444444444444444");
Toast.makeText(TestUSB.this, "44444444444444444", 1000).show();
break; }
}
}; protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main); button = (Button) findViewById(R.id.button);
usbManager = (UsbManager) getSystemService(Context.USB_SERVICE); pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter); button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
new MyThread2().start();
}
}); } private void createAlert(String strTitle, String strMsg) {
Dialog alertDialog = new AlertDialog.Builder(TestUSB.this)
.setTitle(strTitle).setMessage(strMsg)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// TODO Auto-generated method stub
setResult(RESULT_OK, intent);
// finish(); }
}).create(); alertDialog.show();
} class MyThread2 extends Thread { @Override
public void run() {
// TODO Auto-generated method stub
super.run();
Looper.prepare();
// Log.v("test", String.valueOf(getLineNumber(new Exception())));
// createAlert("Waring", "MyThread2 start");// ----------------------------------------------这个地方的对话框可以显示出来
// Looper.loop();
handler.sendEmptyMessage(1);
try { HashMap<String, UsbDevice> map = usbManager.getDeviceList();
if (map.isEmpty()) {
// Looper.prepare();
// createAlert("Waring", "Empty devicelist");// ------------------------这个地方和以下所有调用createAlert的地方对话框均显示不出来
// Looper.loop();
handler.sendEmptyMessage(2); }
else
{
for (UsbDevice device : map.values()) { Log.e("device",
"vid:" + device.getVendorId() + " pid:" + device.getProductId()
+ " " + device.getDeviceName()); if (5334 == device.getVendorId())
{
usbDevice = device;
}
//这里也不要用Dialog
createAlert("Warning",
"vid:" + device.getVendorId() + " pid:" + device.getProductId()
+ " " + device.getDeviceName());
} if (usbManager.hasPermission(usbDevice)) {
handler.sendEmptyMessage(3);// Looper.prepare();
// Log.v("test", String.valueOf(getLineNumber(new Exception())));
// createAlert("Waring", "MyThread3 start");
// Looper.loop(); new MyThread3().start();
} else { handler.sendEmptyMessage(4);// Looper.prepare();
// Log.v("test", String.valueOf(getLineNumber(new Exception())));
// createAlert("Waring", "requestPermission");
// Looper.loop(); usbManager.requestPermission(usbDevice, pendingIntent);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
} class MyThread3 extends Thread {
@Override
public void run() { Looper.prepare();
createAlert("Warning", "My thread3 receive data");
Looper.loop(); } private void createAlert(String strTitle, String strMsg) {
Dialog alertDialog = new AlertDialog.Builder(TestUSB.this)
.setTitle(strTitle).setMessage(strMsg)
.setPositiveButton("确定", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
setResult(RESULT_OK, intent);
// finish(); }
}).create(); alertDialog.show();
} private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() { public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.e("action", action);
sb.append("action start");
sb.append("\n");
info.setText(sb); if (ACTION_USB_PERMISSION.equals(action)) {
synchronized (this) {
usbDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
handler.sendEmptyMessage(1);
if (usbDevice != null) {
sb.append("BroadcastReceiver MyThread3 start");
sb.append("\n");
info.setText(sb);
new MyThread3().start();
}
}
else {
sb.append("permission denied for device" + usbDevice.toString());
sb.append("\n");
info.setText(sb);
Log.d("denied", "permission denied for device " + usbDevice);
}
}
}
}
};
}
}帮你把代码大概的改了一下。细节需要你按上面说的来完善。
1.由于 MyThread3()里面调用了AlertDialog,而且出现了,那么 MyThread3()这个分支肯定被执行了。而在此之前执行了handler.sendEmptyMessage(1);我把handleMessage改为如下,但是这些toast都没有出现。
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case 1:
Toast.makeText(TestUSB.this, "111111111111", 1000).show();
break;
case 2:
Toast.makeText(TestUSB.this, "22222222222", 1000).show();
break;
case 3:
Toast.makeText(TestUSB.this, "33333333333333333", 1000).show();
break;
case 4:
Toast.makeText(TestUSB.this, "44444444444444444", 10000).show();
break; }
}
};
2.我前面说我调用了looper.quit(),但是后面没有被执行,我能否在一个函数里面这样做,比如,这两个alert都能显示吗?
void fun1()
{
Looper.prepare();
createAlert("Warning", "111");
Looper.loop;
Looper.myLooper().quit();
Looper.prepare();
createAlert("Warning", "222");
Looper.loop;
Looper.myLooper().quit();}