Утечка намерений и AlarmManager

1

Я пытаюсь создать систему аутентификации, которая выведет окно входа в систему, если устройство выключено (SCREEN_OFF) больше, чем INTERVAL.

Я зарегистрировал BroadcastReceiver для прослушивания событий SCREEN_ON/OFF в onCreate() запускаемой активности:

/* Listen to Screen On & Off events */
  IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
  filter.addAction(Intent.ACTION_SCREEN_OFF);
  BroadcastReceiver screenOnOff = new ScreenOnOff();
  registerReceiver(screenOnOff, filter);

ScreenOnOff - это BroadcastReceiver, который среди прочего:

@Override
 public void onReceive(Context context, Intent intent) {


mAuthenticationIntent = PendingIntent.getActivity(context, 0,
    new Intent(context, AuthenticationActivity.class), 0);

String action = intent.getAction();

if (action.equals(Intent.ACTION_SCREEN_OFF)) {
   AlarmManager mAlarmManager = (AlarmManager) context
     .getSystemService(context.ALARM_SERVICE);
   mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, System
     .currentTimeMillis()
     + interval, mAuthenticationIntent);

   Log.d(LOG_TAG, "Alarm Set!");
  }

Когда будильник погаснет, программа выйдет из строя:

08-27 19:18:02.207: ERROR/ActivityThread(3165): Activity com.artoo.ArtooSlateActivity has leaked IntentReceiver com.artoo.authentication.ScreenOnOff@4495bca0 that was originally registered here. Are you missing a call to unregisterReceiver()?
08-27 19:18:02.207: ERROR/ActivityThread(3165): android.app.IntentReceiverLeaked: Activity com.artoo.ArtooSlateActivity has leaked IntentReceiver com.artoo.authentication.ScreenOnOff@4495bca0 that was originally registered here. Are you missing a call to unregisterReceiver()?
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at android.app.ActivityThread$PackageInfo$ReceiverDispatcher.<init>(ActivityThread.java:939)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at android.app.ActivityThread$PackageInfo.getReceiverDispatcher(ActivityThread.java:734)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:791)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at android.app.ContextImpl.registerReceiver(ContextImpl.java:778)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at android.app.ContextImpl.registerReceiver(ContextImpl.java:772)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:318)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at com.artoo.ArtooSlateActivity.onCreate(ArtooSlateActivity.java:50)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3815)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at android.app.ActivityThread.access$2400(ActivityThread.java:125)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2037)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at android.os.Handler.dispatchMessage(Handler.java:99)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at android.os.Looper.loop(Looper.java:123)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at android.app.ActivityThread.main(ActivityThread.java:4627)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at java.lang.reflect.Method.invokeNative(Native Method)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at java.lang.reflect.Method.invoke(Method.java:521)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
08-27 19:18:02.207: ERROR/ActivityThread(3165):     at dalvik.system.NativeStart.main(Native Method)

Любая помощь будет оценена по достоинству.

Спасибо, Sameer

Теги:
alarmmanager

1 ответ

1

Поскольку вы регистрируете ресивер динамически, система знает, что вы пропускаете память, потому что вы никогда не вызываете unregister. Очевидно, что вы не хотите отменить регистрацию, потому что вам нужно прослушивать события SCREEN_ON/OFF.

Решение состоит в том, чтобы зарегистрировать приемник в Manifest.xml

Базовый класс для кода, который будет получать намерения, отправленные sendBroadcast(). Вы можете динамически регистрировать экземпляр этого класса с помощью Context.registerReceiver() или статически публиковать реализацию через тег в вашем AndroidManifest.xml. Примечание. Если вы регистрируете ресивер в своей реализации Activity.onResume(), его следует отменить в Activity.onPause(). (Вы не будете получать намерения при приостановке, и это сократит ненужные системные издержки). Не отмените регистрацию в Activity.onSaveInstanceState(), потому что это не будет вызываться, если пользователь вернется в стек истории

  • 0
    Я согласен, за исключением того, что ACTION_SCREEN_OFF и, возможно, ACTION_SCREEN_ON не могут использоваться зарегистрированными в манифесте BroadcastReceivers : code.google.com/p/android/issues/detail?id=10735
  • 0
    Именно так, что мне делать и как мне реализовать мой код?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню