简体   繁体   中英

How do I avoid BroadcastReceiver leakage

I'm building a library, which has the following structure:

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

   public static void performAction(){};
}

The intended usage is: users of my library call init() in the first Activity they create. The problem is that I don't unregister BroadcastReceiver and it leaks when app is closed. I could create a method called deinit() and ask the users of lib to call it when leaving Activity , but is there a more reliable way for me to free resources?

Why do I need receiver?

If there is no Internet connection and performAction() cannot send data, I register receiver to detect connectivity state change.

If you declare the broadcast receiver in manifest android will take care of the handling of register.

Register your receiver inside the application tag like this

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

Why not only register the receiver if performAction() needs to defer the action? That will limit the receiver to only being in place if there's actually something waiting to be done. Once the receiver successfully flushes its queue of actions, it could unregister the receiver itself.

You could unregister the receiver once the onReceive method finishes(at the end of it).

But i dont know if this is suitable for you, it depends on what your receivers do.

It worked for me when registering SMSsent/delivered receivers..

Have you thought of extending android.app.Application and implements these methods:

void onCreate() 

void onLowMemory()

You can register all the BroadcastReceivers you need inside onCreate and unregister 'em inside onLowMemory.

To retrieve a reference of this class you can call context.getApplicationContext() and cast it to your Application subclass.

Finally, to get your app use this solution, you have to put these informations inside the tag inside your AndroidManifest.xml like that:

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

If you need the receiver in all the Activities you should create a Service which registers the receiver, here you can see how to create a Service.

To unregister the receiver you could detect when the user finishes the app knowing the package name which is currently in the foreground. You are unregistering the receiver when you don't need it anymore, it won't leak when user exit the app because it is now created and attached to the Service, not to the Application or Activity.

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

Anyway, I think you should create something like a stop() method and let the user call it to finalize everything you want when they know the are exiting the app and the library is no required anymore.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM