Как избежать утечки BroadcastReceiver

Я создаю библиотеку, которая имеет следующую структуру:

MySDK{ public static void init(Context context){ registerReceivers(); // Register connectivity BroadcastReceiver here } public static void performAction(){}; } 

Предполагаемое использование: пользователи моей библиотеки call init () в первом созданном ими действии. Проблема в том, что я не отменяю регистрацию BroadcastReceiver, и она течет, когда приложение закрыто. Я мог бы создать метод, называемый deinit (), и попросить пользователей lib вызвать его при выходе из Activity , но есть ли более надежный способ для меня освободить ресурсы?

Зачем мне нужен приемник?

Если интернет-соединение отсутствует, а функция performAction () не может отправлять данные, я регистрирую приемник для обнаружения изменения состояния соединения.

Если вы заявляете, что приемник вещания в манифесте андроида будет следить за обработкой регистра.

Зарегистрируйте свой приемник внутри тега приложения, как это

 <receiver android:name="class name with package"> <intent-filter> <action android:name=" corresponding broadcast name" /> </intent-filter> </receiver> 

Почему не только регистрировать приемник, если performAction () должен отложить действие? Это ограничит приемник только на месте, если на самом деле что-то ждет. Как только получатель успешно сбросит свою очередь действий, он может отменить регистрацию самого получателя.

Вы можете отменить регистрацию получателя после завершения метода onReceive (в конце его).

Но я не знаю, подходит ли это для вас, это зависит от того, что делают ваши приемники.

Это работало для меня при регистрации SMS-отправителей / получателей.

Думали ли вы о распространении android.app.Application и реализуете эти методы:

 void onCreate() void onLowMemory() 

Вы можете зарегистрировать все необходимые вам BroadcastReceivers внутри. Создайте и отмените регистрацию внутри onLowMemory.

Чтобы получить ссылку этого класса, вы можете вызвать context.getApplicationContext () и передать его в подкласс приложения.

Наконец, чтобы ваше приложение использовало это решение, вам необходимо разместить эту информацию внутри тега внутри вашего AndroidManifest.xml следующим образом:

 <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:name="[fully qualified name of your Application subclass]" > ... </application> 

Если вам нужен приемник во всех видах деятельности, вы должны создать Службу, которая регистрирует приемник, здесь вы можете увидеть, как создать Сервис.

Чтобы отменить регистрацию получателя, вы можете обнаружить, когда пользователь заканчивает приложение, зная имя пакета, которое в настоящее время находится на переднем плане. Вы не регистрируете получателя, когда он вам больше не нужен, он не будет течь, когда пользователь выйдет из приложения, потому что он теперь создан и привязан к Сервису, а не к приложению или активности.

 public String getForegroundApp() throws NameNotFoundException{ RunningTaskInfo info = null; ActivityManager am; am = (ActivityManager)mContext.getSystemService(ACTIVITY_SERVICE); List<RunningTaskInfo> l = am.getRunningTasks(1000); System.out.println(l); Iterator <RunningTaskInfo> i = l.iterator(); String packName = new String(); String appName = new String(); ApplicationInfo appInfo = new ApplicationInfo(); while(i.hasNext()){ info = i.next(); packName = info.topActivity.getPackageName(); if(!packName.equals("com.htc.launcher") && !packName.equals("com.android.launcher")){ //this could be what is causing the problem. not sure. packName = info.topActivity.getPackageName(); break; } info = i.next(); packName= info.topActivity.getPackageName(); break; } return packName; } в public String getForegroundApp() throws NameNotFoundException{ RunningTaskInfo info = null; ActivityManager am; am = (ActivityManager)mContext.getSystemService(ACTIVITY_SERVICE); List<RunningTaskInfo> l = am.getRunningTasks(1000); System.out.println(l); Iterator <RunningTaskInfo> i = l.iterator(); String packName = new String(); String appName = new String(); ApplicationInfo appInfo = new ApplicationInfo(); while(i.hasNext()){ info = i.next(); packName = info.topActivity.getPackageName(); if(!packName.equals("com.htc.launcher") && !packName.equals("com.android.launcher")){ //this could be what is causing the problem. not sure. packName = info.topActivity.getPackageName(); break; } info = i.next(); packName= info.topActivity.getPackageName(); break; } return packName; } 

В любом случае, я думаю, вы должны создать что-то вроде метода stop() и позволить пользователю вызвать его, чтобы завершить все, что вам нужно, когда они узнают, что они покидают приложение, и библиотека больше не требуется.