Search code examples
androidmemory-leaksandroid-memoryjava-memory-leaks

Android: Memory Leak


I am using the code below in my activity class:

public static Activity list_Addresses_Activity;

And in my onCreate I used from this :

list_Addresses_Activity = this;

But it throws an error stated below:

Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)

I need to use it from static because I will use from this in my Service class.

My CloseActivies.class :

public class CloseActivies {
    Activity a;
    Activity b;
    Activity c;

    protected void CLSActivities(Activity ListAddresses, Activity ListOrder, Activity SendReports) {
        a = ListAddresses;
        b = ListOrder;
        c = SendReports;
        if (ListAddressesActivity.FlagLiveAddress && a != null) {
            Log.e("ADASFSDAGWEG", "X");
            a.finish();
            ListAddressesActivity.FlagLiveAddress = false;
        }
        if (ListOrderActivity.FlagLiveOrder && b != null) {
            Log.e("ADASFSDAGWEG", "Y");
            b.finish();
            ListOrderActivity.FlagLiveOrder = false;
        }
        if (SendReportsActivity.FlagSendReport && c != null) {
            Log.e("ADASFSDAGWEG", "Z");
            c.finish();
            SendReportsActivity.FlagSendReport = false;
        }
    }

    protected void CLSActivities() {
        if (ListAddressesActivity.FlagLiveAddress && a != null) {
            Log.e("ADASFSDAGWEG", "X");
            a.finish();
            ListAddressesActivity.FlagLiveAddress = false;
        }
        if (ListOrderActivity.FlagLiveOrder && b != null) {
            Log.e("ADASFSDAGWEG", "Y");
            b.finish();
            ListOrderActivity.FlagLiveOrder = false;
        }
        if (SendReportsActivity.FlagSendReport && c != null) {
            Log.e("ADASFSDAGWEG", "Z");
            c.finish();
            SendReportsActivity.FlagSendReport = false;
        }
    }
}

Solution

  • It will cause a memory leak as your service class is working on a separate thread and passing a static reference to your activity will keep the instance in memory even if the activity is dismissed and not garbage collected, a safer way to do this is passing a reference of your activity as a parameter to your service and storing it in a weakreference something like this

    public class MyIntentService extends IntentService {
    
        private final WeakReference<Context> mContextWeakReference;
    
        public MyIntentService() {
            super("MyIntentService");
        }
    
        public static void startActionFoo(Context context) {
            mContextWeakReference = new WeakReference<>(context);
            Intent intent = new Intent(context, MyIntentService.class);
            context.startService(intent);
        }
    
        @Override
        protected void onHandleIntent(Intent intent) {
            Context context = mContextWeakReference.get();
            if(context != null) {
                //do your work as since context is not null means
                //activity is still present and if activity is dismissed
                //context will come null 
            }
        }
    }
    

    If you need activity reference for one of its static variable you can pass it in intent extras, or you want to call a static function of activity, a broadcast receiver would be a better choice to do this.