最初,我为自己设置了一个简单的任务,使函数能够以延迟执行。起初我做了一个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);
}
}
}
}
我不熟悉内部类和引用,所以尽管我的代码似乎正在工作,但我不确定,如果我已经超越了我的目标以避免内存泄漏。如果有人能查看我的代码,我将不胜感激。
答案 0 :(得分:2)
你的代码看起来很好恕我直言。我认为你已成功实现了runnable并保护自己免受内存泄漏。
非静态内部类包含对创建它们的实例的隐式引用。这意味着,如果您使用非静态方法,您将保留对ApproxManager
实例的引用,并且此实例不会被垃圾回收。 ApproxManager
保留对Context
和AlarmManager
个实例的引用,它们也不会被垃圾收集,这就是内存泄漏。
静态内部类不会包含任何隐式引用,但是它们无法访问非静态成员,因此您不得不提供所有必需的依赖项,以便类可以执行它的工作。如果需要,可以使用WeakReference
来阻止变量的最终垃圾收集。