消息给死线程中的处理程序

时间:2014-10-08 17:45:41

标签: android warnings intentservice

我有一个由警报每30秒触发一次的IntentService ... 第一个警报由用户设置。当广播收到第一个警报时,它会调用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 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)

这是我的IntentService:

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);
    }

}

1 个答案:

答案 0 :(得分:0)

这里有几点需要考虑,可以帮助您摆脱错误并获得更清晰的代码:

  • 应使用AlarmManager
  • 安排闹钟
  • ServiceGps可以由WakefulBroadcastReceiver启动,因此您不必自己处理唤醒锁。
  • 如果目标低于19,您可以从AlarmManager中使用 setRepeating ... 方法中受益。

**不要忘记Manifest中的权限。

希望它有所帮助。