Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/186.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 内部课堂活动是否不可接受?_Java_Android_Memory Leaks_Android Asynctask_Inner Classes - Fatal编程技术网

Java 内部课堂活动是否不可接受?

Java 内部课堂活动是否不可接受?,java,android,memory-leaks,android-asynctask,inner-classes,Java,Android,Memory Leaks,Android Asynctask,Inner Classes,众所周知的内存泄漏源是AsyncTasks持有对活动的引用,例如,当将任务声明为内部类时: public class MyActivity extends Activity { ... private class MyTask extends AsyncTask<Void, Void, Void> { ... } } 我在目前从事的项目中看到过这样的活动,我正在考虑对其进行重构,使内部类成为

众所周知的内存泄漏源是
AsyncTasks
持有对活动的引用,例如,当将任务声明为内部类时:

    public class MyActivity extends Activity {

        ...

        private class MyTask extends AsyncTask<Void, Void, Void> {
            ...
        }
    }
我在目前从事的项目中看到过这样的活动,我正在考虑对其进行重构,使内部类成为静态的,并向活动添加weakreference。
问题是内部类很方便,因为它们可以访问活动的私有变量和方法,将它们更改为static还迫使我将活动类中这些成员的访问修饰符从private更改为package default,从而使它们可用于同一个包中的任何其他类。这也破坏了对称性,因为现在活动中有一些方法是包默认的,而它们的对称对应项仍然是私有的(例如,我需要使活动中的
stopFoo
方法对现在的静态类可用,那么我应该如何处理那些类中没有调用的
startFoo
)。那么活动中需要访问的变量呢?我现在应该提供getter吗?
向活动添加弱引用也会在重构的静态类中引入大量的空检查,因此它们只在活动仍然存在的情况下才起作用。此外,弱引用方法可能很难被公司的非熟练程序员理解(此外,他们可能只是开始在任何地方使用它,而不是真正需要它)

简而言之,重构后的活动看起来很难看,而前一个活动很整洁。因此我想知道基于内部类的设计是否可以接受,因为我知道我并不介意在活动结束后是否让可运行或计时器任务在短时间内运行。

现在(如果我错了,请纠正我),任务完成后,活动将再次可供收集

正确,假设没有其他东西对它有静态引用

我可以通过取消计时器和调用处理程序上的removeCallbacks来防止内存泄漏吗

这些步骤会有帮助。此外,你无论如何都需要这样做——除非你停止,否则你的
计时器不会神奇地停止运行

当活动结束时,我并不介意runnable或timer任务是否在短时间内运行

从内存管理的角度来看,您的论点是正确的。虽然“避免非静态内部类”是一个很好的高级设计标准,但它不是绝对的


然而,IMHO,您真正的问题不在于内存管理,而在于配置更改。当用户旋转屏幕、更改语言、将设备放入汽车停靠站等时,您的活动将被销毁并重新创建。然而,据推测,任务中的工作仍然需要,但他们将与错误的活动实例对话。Usi创建一个保留的片段来管理这些任务有助于解决这个问题。

避免非静态的内部类。滚动到链接上并查看要点,感谢您的回复。我想澄清一下,在我的特殊情况下,内部可运行程序和TimerTask的持续时间非常短,它们已经通过activity recreat实现了所以我主要关心的是内存泄漏。
    public class MyActivity extends Activity {
        Handler handler;
        Timer timer;


        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            handler = new Handler();
            timer = new Timer();

            handler.postDelayed(new MyRunnable(), 10000);
            timer.schedule(new MyTimerTask(), 1000);
        }

        @Override
        protected void onDestroy() {
            super.onDestroy();

            handler.removeCallbacksAndMessages(null);
            timer.cancel();
            handler = timer = null;
        }

        private class MyTimerTask extends TimerTask {
            ...
        }

        private class MyRunnable implements Runnable {
            ...
        }
    }