5

我正在构建一个库,它具有以下结构:

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

   public static void performAction(){};
}

预期用途是:我的库的用户在他们创建的第一个活动中调用init() 。问题是我没有取消注册BroadcastReceiver并且在应用程序关闭时它会泄漏。我可以创建一个名为deinit()的方法,并要求 lib 的用户在离开Activity时调用它,但是有没有更可靠的方法让我释放资源?

为什么需要接收器?

如果没有 Internet 连接并且performAction()无法发送数据,我注册接收器以检测连接状态变化。

4

5 回答 5

3

如果您在清单中声明广播接收器,android 将负责注册的处理。

像这样在应用程序标签中注册您的接收器

<receiver android:name="class name with package">  
        <intent-filter>
            <action android:name=" corresponding broadcast name" />
        </intent-filter>
</receiver>
于 2013-09-03T12:44:58.593 回答
2

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.

于 2013-08-29T12:53:39.250 回答
0

如果您在所有活动中都需要接收器,您应该创建一个注册接收器的服务,在这里您可以看到如何创建一个服务。

要取消注册接收器,您可以检测用户何时完成应用程序,知道当前在前台的包名称。当您不再需要接收器时,您正在注销它,当用户退出应用程序时它不会泄漏,因为它现在已创建并附加到服务,而不是应用程序或活动。

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()方法的东西,并让用户在他们知道正在退出应用程序并且不再需要该库时调用它以完成您想要的一切。

于 2013-09-03T14:32:50.453 回答
0

一旦 onReceive 方法完成(在它的末尾),您就可以取消注册接收器。

但我不知道这是否适合你,这取决于你的接收器做什么。

在注册 SMSsent/delivered 接收器时它对我有用..

于 2013-08-26T20:42:23.870 回答
0

你有没有想过扩展 android.app.Application 并实现这些方法:

void onCreate() 

void onLowMemory()

您可以在 onCreate 中注册您需要的所有 BroadcastReceiver,并在 onLowMemory 中取消注册它们。

要检索此类的引用,您可以调用 context.getApplicationContext() 并将其转换为您的 Application 子类。

最后,要让您的应用程序使用此解决方案,您必须将这些信息放入 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>
于 2013-09-02T11:34:55.063 回答