Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/227.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
Android内存管理用于桌面(或屏幕外)活动_Android_Memory Management_Android Activity_Crash - Fatal编程技术网

Android内存管理用于桌面(或屏幕外)活动

Android内存管理用于桌面(或屏幕外)活动,android,memory-management,android-activity,crash,Android,Memory Management,Android Activity,Crash,我正在努力实现的目标: 减少屏幕上不再显示的活动的内存使用(即已启动另一个活动) 此活动仍在导航堆栈中,因此我假设必须在onStart中重新构建在onStop中破坏的内容,但不确定在使用layout.xml构建所有视图/按钮时如何进行 情况: 我有一个Android应用程序,它非常注重图像,但是这些图像在许多布局上都是静态的,具有相同的背景、按钮图像、导航标题等。这使得我可以通过指定layout.xml文件中的所有ImageView、它们的src属性和位置,非常轻松地构建布局,而不需要过多地

我正在努力实现的目标:

  • 减少屏幕上不再显示的活动的内存使用(即已启动另一个活动)
  • 此活动仍在导航堆栈中,因此我假设必须在onStart中重新构建在onStop中破坏的内容,但不确定在使用layout.xml构建所有视图/按钮时如何进行
情况:

我有一个Android应用程序,它非常注重图像,但是这些图像在许多布局上都是静态的,具有相同的背景、按钮图像、导航标题等。这使得我可以通过指定layout.xml文件中的所有ImageView、它们的src属性和位置,非常轻松地构建布局,而不需要过多地接触代码。这非常有效,很容易启动和运行,但是现在有很多报告称由于超过内存使用量而强制关闭

因此,在尝试清理并允许gc删除屏幕上没有的图像和视图时,我看到一篇文章(见问题的底部)建议使用onDestroy方法,抓住布局中的根元素,递归地遍历树删除视图并解除绑定。然而,当按下后退按钮时,这只会被触发,并且根据文档不保证

因此,当我将新活动推到堆栈上时,onDestroy对我没有帮助,我不想清理刚刚离开屏幕的内容。但是使用onDestroy方法的好处是入口点从onCreate开始,因此所有视图都是正确构建的。当我在onStop中使用此方法时,当我开始一个新活动时,内存get会得到很好的清理,但是因为我已经取消了所有视图,并且它们是使用layout.xml构建的,如果我破坏了onStop中的所有内容,我不知道如何或需要在onStart中重新构建,尤其是考虑到我从未在代码中创建任何视图,因为它们都是由于layout.xml文件而设置的

主要问题:启动新活动时如何清理内存?如果上下文处理正确,gc是否会清除所有屏幕外的ImageView并自动重新构建它们

这可以在onStop中使用吗

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

    unbindDrawables(findViewById(R.id.RootView));
    System.gc();
}

private void unbindDrawables(View view) {
    if (view.getBackground() != null) {
        view.getBackground().setCallback(null);
    }
    if (view instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            unbindDrawables(((ViewGroup) view).getChildAt(i));
        }
        ((ViewGroup) view).removeAllViews();
    }
}
@覆盖
受保护的空onDestroy(){
super.ondestory();
不可绑定的drawables(findviewbyd(R.id.RootView));
gc();
}
私有void未绑定可提取项(视图){
if(view.getBackground()!=null){
view.getBackground().setCallback(null);
}
if(视图组的视图实例){
对于(int i=0;i<((视图组)视图)。getChildCount();i++){
未绑定的Drawables(((视图组)视图).getChildAt(i));
}
((视图组)视图);
}
}
A) 使用onCreate()/onDestroy()将在活动进入堆栈时进行分配,并在活动从堆栈弹出时取消分配

(B) 使用onStart()/onStop()将在活动可见时分配,在活动不可见时取消分配

使用A)或B)。不要把它们混在一起,否则你会经常分配或取消分配

在您的情况下,我会将所有内容从onCreate()移动到onStart(),并将所有内容从onDestroy()移动到onStop()

也可以考虑使用.StTraceVIEW(NULL)或OnStutter()中的StCutTeNeVIEW(new VIEW(this)),以确保旧视图可以被垃圾收集:

  @Override
  protected void onStop() {
    super.onStop();
    View root = findViewById(R.id.RootView);
    setContentView(new View(this)) 
    unbindDrawables(root);
    System.gc();
  }

我不认为任何活动回调都是这样做的理想场所。你的活动总是会变得非常缓慢

我想如果可以的话,你宁愿保留图像,但如果系统需要资源,你愿意放弃。如果这(缓存)是你正在看的,那就是你的男人。看看这将帮助你决定/理解

此外,我不认为android是为了让美国开发者担心从布局文件生成的视图何时会被gc’d。只要您没有持有对视图的强引用,您就应该可以了