Android 发送给死线程中处理程序的消息
我有一个IntentService,它每30秒就会被一个警报触发一次。。。 第一个警报由用户设置。当广播接收到第一个警报时,它会调用IntentService,IntentService会启动另一个警报,该警报将在30秒内触发。 但在logcat中它总是给我很多这样的信息:Android 发送给死线程中处理程序的消息,android,warnings,intentservice,Android,Warnings,Intentservice,我有一个IntentService,它每30秒就会被一个警报触发一次。。。 第一个警报由用户设置。当广播接收到第一个警报时,它会调用IntentService,IntentService会启动另一个警报,该警报将在30秒内触发。 但在logcat中它总是给我很多这样的信息: 10-08 14:32:43.433: W/MessageQueue(23819): Handler{40568030} sending message to a Handler on a dead thread 10-08
10-08 14:32:43.433: W/MessageQueue(23819): Handler{40568030} sending message to a Handler on a dead thread
10-08 14:32:43.433: W/MessageQueue(23819): java.lang.RuntimeException: Handler{40568030} sending message to a Handler on a dead thread
10-08 14:32:43.433: W/MessageQueue(23819): at android.os.MessageQueue.enqueueMessage(MessageQueue.java:196)
10-08 14:32:43.433: W/MessageQueue(23819): at android.os.Handler.sendMessageAtTime(Handler.java:457)
10-08 14:32:43.433: W/MessageQueue(23819): at android.os.Handler.sendMessageDelayed(Handler.java:430)
10-08 14:32:43.433: W/MessageQueue(23819): at android.os.Handler.sendMessage(Handler.java:367)
10-08 14:32:43.433: W/MessageQueue(23819): at android.location.LocationManager$ListenerTransport.onLocationChanged(LocationManager.java:193)
10-08 14:32:43.433: W/MessageQueue(23819): at android.location.ILocationListener$Stub.onTransact(ILocationListener.java:58)
10-08 14:32:43.433: W/MessageQueue(23819): at android.os.Binder.execTransact(Binder.java:336)
10-08 14:32:43.433: W/MessageQueue(23819): at dalvik.system.NativeStart.run(Native Method)
这是我的意向服务:
public class ServiceGPS extends IntentService{
static String APP = "ACORDENOPONTO";
private static volatile PowerManager.WakeLock lockStatic=null;
synchronized private static PowerManager.WakeLock getLock(Context context) {
if (lockStatic == null) {
PowerManager mgr=
(PowerManager)context.getSystemService(Context.POWER_SERVICE);
lockStatic=mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, APP);
lockStatic.setReferenceCounted(true);
}
return(lockStatic);
}
public ServiceGPS() {
super("ServiceGPS");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
PowerManager.WakeLock lock=getLock(this.getApplicationContext());
if (!lock.isHeld() || (flags & START_FLAG_REDELIVERY) != 0){
lock.acquire();
}
super.onStartCommand(intent, flags, startId);
return(START_REDELIVER_INTENT);
}
@Override
protected void onHandleIntent(Intent intent) {
params.getCharSequence("tickerText")
NotificationManager.criaNotification(this, params.getCharSequence("tickerText")
, params.getCharSequence("title")
, params.getCharSequence("message")
, params.getInt("id")
, (30));
}
PowerManager.WakeLock lock=getLock(this.getApplicationContext());
if(lock.isHeld()){
lock.release();
}
MonitoraGPS.completeWakefulIntent(intent);
}
public void tocaAlarmeVibraTudo(Context context){
Intent intent = new Intent(context, TelaDespertou.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
添加NotificationManager代码:
public class NotificationManager{
static AlarmManager alarme;
public static void criaNotification(Context context, CharSequence tickerText, CharSequence title,
CharSequence message, int id, float segundos){
alarme = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent abreMonitora = new Intent("MONITORAR");
Bundle params = new Bundle();
params.putCharSequence("tickerText", tickerText);
params.putCharSequence("title", title);
params.putCharSequence("message", message);
params.putInt("id", id);
abreMonitora.putExtras(params);
PendingIntent vaiFazer = PendingIntent.getBroadcast(context, id, abreMonitora,
PendingIntent.FLAG_CANCEL_CURRENT);
long minute = minuteToMilli(segundos);
alarme.set( AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + minute,
vaiFazer);
Log.d("setou", "alarme" + segundos);
NotificationUtil.criaNotification(context, tickerText, title, message, id, intent);
}
public static long minuteToMilli(float minute){
long quaseMilli = (long) (minute * 1000);
return quaseMilli;
}
public static void cancelaAlarme(Context context, int id){
alarme = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
PendingIntent operation = PendingIntent.getBroadcast(context, id,
new Intent("MONITORAR"),
PendingIntent.FLAG_CANCEL_CURRENT);
alarme.cancel(operation);
}
}
这里有几件事需要考虑,它可以帮助你摆脱错误,得到更干净的代码:
- 应使用AlarmManager计划报警
- 服务GPS可以由WakeFulBroadcasting接收器启动,因此您不必自己处理WakeLock
- 如果目标值低于19,则可以使用setRepeating。。。方法在AlarmManager中
希望有帮助。重复的内容并不总是一样的。。。那里的“NotificationManager”只是类的名称,因为它处理报警并向用户发送通知。。。是的,我是从WakefulBroadcastReceiver启动的…我假设您的NotificationManager是因为方法调用而定制的。你能发布那个代码吗?你使用的是没有被注销的GPS监听器吗?也许。。。我正在接收机中获取GPS当前坐标,获取坐标后是否必须使用
removeUpdates(this)
?接收机工作完成后(可能在完成onReceive(…)后)将被销毁。在那里注册位置更新不是一个好的做法。你可以在那里创建一个服务并注册一个接收者,这样你就可以随时获得位置更新。您可以通过首选项、意图或绑定到您的服务来共享这些数据(我推荐第一个)。