我这里有一个service是这样,开启后,每一分钟做一次弹窗提醒(闹钟app的铺垫,每天一次弹窗提醒)。
然而,我的这个dialog有一个PositiveButton,但是这要点击这个 button 就会报错.
错误如下:
Handler (com.android.internal.app.AlertController$ButtonHandler) {385957f} sending message to a Handler on a dead thread
java.lang.IllegalStateException: Handler (com.android.internal.app.AlertController$ButtonHandler) {385957f} sending message to a Handler on a dead thread
at android.os.MessageQueue.enqueueMessage(MessageQueue.java:555)
at android.os.Handler.enqueueMessage(Handler.java:707)
at android.os.Handler.sendMessageAtTime(Handler.java:609)
at android.os.Handler.sendMessageDelayed(Handler.java:579)
at android.os.Handler.sendMessage(Handler.java:516)
at android.os.Message.sendToTarget(Message.java:429)
at com.android.internal.app.AlertController$1.onClick(AlertController.java:146)
at android.view.View.performClick(View.java:5265)
at android.view.View$PerformClick.run(View.java:21534)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:207)
at android.app.ActivityThread.main(ActivityThread.java:5728)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:679)
我的代码是这样的:
public class ClockService extends IntentService {
private static final String TAG = "ClockService";
private Vibrator vibrator;
private MediaPlayer mMediaPlayer = null;
private Context mContext ;
AlertDialog dialog;;
private static final int TIME = 1000*20;
public static Intent newIntent(Context context){
return new Intent(context,ClockService.class);
}
public ClockService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
LogUtil.d(TAG,"service intent ");
System.out.println("我是闹钟,我要叫醒你...");
dismissHandler= new Handler(getMainLooper());
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("闹钟");
builder.setMessage("测试");
builder.setPositiveButton("知道了", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
//我这里啥都没有,但是只要点击 知道了 就会报错
}
});
dialog = builder.create();
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
mHandler =new Handler(Looper.getMainLooper());
new Thread(){
@Override
public void run() {
super.run();
mHandler.post(new Runnable() {
@Override
public void run() {
dialog.show();
}
});
}
}.start();
// dialog.show();
}
Handler mHandler,dismissHandler ;
public static void setServiceAlarm(Context context,boolean isON){
Intent i = ClockService.newIntent(context);
PendingIntent pi = PendingIntent.getService(context,0,i,0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (isON){
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(),TIME,pi);
}else{
alarmManager.cancel(pi);
pi.cancel();
}
}
}
onHandleIntent() は子スレッドで実行されます。このメソッドが実行された後、IntentService はすぐに stopSelf() を呼び出して自身を停止し、子スレッドの Looper は破棄されます。
。 リーリーonHandleIntent() で作成された Dialog の内部 ButtonHandler は、子スレッドのメッセージ キューにバインドされます。ボタン クリック イベントが発生すると、子スレッドは破棄されてメッセージ ループから抜け出し、ButtonHandler も次のようになります。無効。したがって、デッドスレッドのハンドラーにメッセージを送信すると、Logcat で例外がスローされます。この例外は android.os.MessageQueue.enqueueMessage() メソッドでスローされます。
サンプル コードは次のとおりです
ダイアログの作成はメインスレッドで操作する必要があります。 IntentService ではなく通常の Service を開始し、onStartCommand() メソッドでダイアログを作成することをお勧めします。