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

时间:2016-10-05 07:35:18

标签: java android

我的服务有BeaconNotificationsManager,我想在BeaconNotificationsManager中访问此Activity。目前我的BeaconNotificationsManagerstatic

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

我正在Activity这样访问此内容:

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

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

1 个答案:

答案 0 :(得分:3)

关于静态问题:我们只是说您从另一个类引用了您的服务bnm,并且您的服务已被操作系统销毁,但静态对象(bnm)仍在使用中通过某些活动,这将保留垃圾收集的服务上下文,除非您将活动中的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;
    }
}

因此,当您绑定服务时,您将获得binder对象,该对象可以进一步为您提供服务对象并使用您的函数来检查nullity

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.。)使用在第一步中创建的Service对象绑定ServiceConnection

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

,那么只需在你的类'getStatus'中有一个函数,然后用通过binder找到的对象调用它就可以查看link for code example