aphelion
aphelion

Reputation: 681

(Android) Atempting to implement static Weakreference runnable

Initially i set myself a simple task to make a function to execute with delay. At first i made a runnable and executed it with new Thread(runnable).start();, but i've read, that non-static inner classes can lead to memory leaks, so i tried to make Runnable as static.

I followed example in Is this Runnable safe from memory leak? and ended with this code:

public class ApproxManager {
    private Context mContext;
    private AlarmManager mAlarmManager;

    public ApproxManager(Context context){
        mContext = context;
        mAlarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    }

    public void setPeriod(int type, long when, int extendCount){
        Intent i = new Intent(mContext, OnAlarmReceiver.class);
        long alarmtime = when;
        i.putExtra(RReminder.PERIOD_TYPE, type);
        i.putExtra(RReminder.EXTEND_COUNT, extendCount);
        i.setAction(RReminder.CUSTOM_INTENT_APPROXIMATE_PERIOD_END);
        PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
        new Thread(new WeakRunnable(mContext, alarmtime,pi)).start();
    }

    public void setAlarm(long alarmTime, PendingIntent pi){
        mAlarmManager.set(AlarmManager.RTC_WAKEUP, alarmTime, pi);
    }

    private static final class WeakRunnable implements Runnable {
        private final WeakReference<Context> mContext;
        long mAlarmtime;
        PendingIntent mpi;

        protected WeakRunnable(Context context, long alarmtime, PendingIntent pi){
        mContext = new WeakReference<Context>(context);
        mAlarmtime = alarmtime;
        mpi = pi;

        }

        @Override
        public void run() {
            Context context = mContext.get();
            if (context != null) {
                try {
                    Thread.sleep(1500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                ApproxManager approxManager = new ApproxManager(context);
                approxManager.setAlarm(mAlarmtime,mpi);
            }
        }
    }
} 

I am unfamiliar with inner classes and referencing, so despite my code appears to be working, i am not sure, if i have suceeded with my goal to avoid memory leaks. So i would appreciate if someone could look at my code.

Upvotes: 0

Views: 313

Answers (1)

Danail Alexiev
Danail Alexiev

Reputation: 7772

Your code looks fine IMHO. I think you have managed to successfully implement you runnable and protect yourself against a memory leak.

Non - static inner classes hold a implicit reference to the instance that created them. This means that, if you go with the non - static approach, you will be keeping a reference to a ApproxManager instance and this instance will not be garbage collected. The ApproxManager keeps a reference to the Context and AlarmManager instances and they won't be garbage collected neither and this is you memory leak.

Static inner classes don't hold any implicit references, but they can't access non - static members, so you are forced to provide all the needed dependencies so the class can do it's work. Using WeakReference you won't prevent eventual garbage collection of the variable, if there is need for one.

Upvotes: 2

Related Questions