不要将 Android 上下文 类 放在静态字段中;这是内存泄漏

Do not place Android context classes in static fields; this is a memory leak

我有一个服务 BeaconNotificationsManager,我想在我的 Activity 中访问这个 BeaconNotificationsManager。目前我的 BeaconNotificationsManagerstatic:

public class MyService extends Service { 
    public static BeaconNotificationsManager bnm;
}

我在我的 Activity 中访问它是这样的:

if(MyService.bnm != null){
     // do stuff
}

尽管 Android 告诉我这很糟糕。这样做的正确方法是什么?

关于静态问题: 假设您正在从另一个 class 引用您的服务 bnm 并且您的服务已被 OS 但静态对象 (bnm) 仍在被某些 activity 使用,因此这将保留垃圾收集的服务上下文,除非您将 activity 中的 bnm 引用设置为 null这将泄漏所有应用程序的资源

解决方案:

最佳选择是使用 BindService 这样您将通过服务对象更好地控制您的服务,在服务使用中 IBinder

class MyService..{
   public BeaconNotificationsManager bnm;
   public class LocalBinder extends Binder {
        LocalService getService() {
            // Return this instance of LocalService so clients can call public methods
            return LocalService.this;
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }

   // inside service class
    public boolean getStatus(){
     return bnm==null;
    }
}

所以当你绑定一个服务时,你会得到绑定对象,它可以进一步给你服务对象并使用你的函数来检查无效性

1.) 创建一个 ServiceConnection 对象

  private ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName className,
                IBinder service) {
            // We've bound to LocalService, cast the IBinder and get LocalService instance
            LocalBinder binder = (LocalBinder) service;
            mService = binder.getService();
            mBound = true;
            bnmNull= mService.getStatus(); // bnm status
        }

2.) 使用第一步创建的 ServiceConnection 对象绑定 Service

    Intent intent = new Intent(this, MyService.class);
    bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

,那么只需在 class 'getStatus' 中添加一个函数,并使用通过活页夹检索到的对象调用它,查看 link for code example