(Android)试图实现静态Weakreference runnable

时间:2016-08-11 14:29:07

标签: android memory-leaks runnable

最初,我为自己设置了一个简单的任务,使函数能够以延迟执行。起初我做了一个runnable并用new Thread(runnable).start();执行它,但我读过,非静态内部类可能导致内存泄漏,所以我试图使Runnable为静态。

我在Is this Runnable safe from memory leak?中关注了示例,并以此代码结束:

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);
            }
        }
    }
} 

我不熟悉内部类和引用,所以尽管我的代码似乎正在工作,但我不确定,如果我已经超越了我的目标以避免内存泄漏。如果有人能查看我的代码,我将不胜感激。

1 个答案:

答案 0 :(得分:2)

你的代码看起来很好恕我直言。我认为你已成功实现了runnable并保护自己免受内存泄漏。

非静态内部类包含对创建它们的实例的隐式引用。这意味着,如果您使用非静态方法,您将保留对ApproxManager实例的引用,并且此实例不会被垃圾回收。 ApproxManager保留对ContextAlarmManager个实例的引用,它们也不会被垃圾收集,这就是内存泄漏。

静态内部类不会包含任何隐式引用,但是它们无法访问非静态成员,因此您不得不提供所有必需的依赖项,以便类可以执行它的工作。如果需要,可以使用WeakReference来阻止变量的最终垃圾收集。