【问题标题】:I need to release camera onPause() and also onDestroy() to avoid application crash. Why?我需要释放相机 onPause() 和 onDestroy() 以避免应用程序崩溃。为什么?
【发布时间】:2014-11-05 00:31:26
【问题描述】:

我在我的应用程序中使用相机。所以在onCreate() 中我得到相机实例,在onPause() 中我释放相机,在onResume() 我得到相机实例,如果变量是null。然后我向我的应用程序添加了另一个活动。从第二个活动开始,我想关闭所有活动......关闭应用程序。我使用了这种方法:

Intent intent = new Intent(getApplicationContext(), FirstActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.putExtra("EXIT", true);
startActivity(intent);

if (getIntent().getBooleanExtra("EXIT", false)) {
    finish();
}

效果很好。应用程序关闭。但是当我想再次启动应用程序时,我收到了 force close 消息。我使用了逐步调试,我的代码在maCamera = getCameraInstance(); 线上失败了:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ...

    maCamera = getCameraInstance();

    ...

}

错误日志:

11-05 00:48:02.289: E/AndroidRuntime(8257): FATAL EXCEPTION: main
11-05 00:48:02.289: E/AndroidRuntime(8257): java.lang.RuntimeException: Unable to start activity        ComponentInfo{com.blabla/com.blabla.YoMainActivity}: java.lang.NullPointerException
11-05 00:48:02.289: E/AndroidRuntime(8257):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1651)
11-05 00:48:02.289: E/AndroidRuntime(8257):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
11-05 00:48:02.289: E/AndroidRuntime(8257):     at android.app.ActivityThread.access$1500(ActivityThread.java:117)
11-05 00:48:02.289: E/AndroidRuntime(8257):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
11-05 00:48:02.289: E/AndroidRuntime(8257):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-05 00:48:02.289: E/AndroidRuntime(8257):     at android.os.Looper.loop(Looper.java:130)
11-05 00:48:02.289: E/AndroidRuntime(8257):     at android.app.ActivityThread.main(ActivityThread.java:3687)
11-05 00:48:02.289: E/AndroidRuntime(8257):     at java.lang.reflect.Method.invokeNative(Native Method)
11-05 00:48:02.289: E/AndroidRuntime(8257):     at java.lang.reflect.Method.invoke(Method.java:507)
11-05 00:48:02.289: E/AndroidRuntime(8257):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:842)
11-05 00:48:02.289: E/AndroidRuntime(8257):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
11-05 00:48:02.289: E/AndroidRuntime(8257):     at dalvik.system.NativeStart.main(Native Method)
11-05 00:48:02.289: E/AndroidRuntime(8257): Caused by: java.lang.NullPointerException
11-05 00:48:02.289: E/AndroidRuntime(8257):     at com.blabla.YoCameraPreview.<init>(YoCameraPreview.java:26)
11-05 00:48:02.289: E/AndroidRuntime(8257):     at com.blabla.YoMainActivity.onCreate(YoMainActivity.java:82)
11-05 00:48:02.289: E/AndroidRuntime(8257):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
11-05 00:48:02.289: E/AndroidRuntime(8257):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
11-05 00:48:02.289: E/AndroidRuntime(8257):     ... 11 more

我认为这与释放相机有关。所以我尝试在onDestroy() 中调用camera.release(),它成功了。不再有强制关闭消息。

所以我的问题是:这是正常行为吗?为什么在 onPause() 中调用 release 不够?

附言如果这不是通常的行为,我可以发布更多代码并且问题可能出在我的代码中。

更新:

我的代码中的方法:

@Override
protected void onDestroy(){
    super.onDestroy();
    maPreview = null;
    releaseCamera();   
}

@Override
protected void onResume(){
    super.onResume();
    if (maCamera == null) {
        maCamera = getCameraInstance();
    }
    if (maPreview == null) {
        maPreview = new YoCameraPreview(this, maCamera);
        maLayoutPreview.removeAllViews();
        maLayoutPreview.addView(maPreview);
    }
}

@Override
protected void onPause() {
    super.onPause();
    maPreview = null;
    releaseCamera();
}

private void releaseCamera(){
    if (maCamera != null){
        maCamera.release();
        maCamera = null;
    }
}

我不使用此应用拍照。我只使用相机预览,因此我没有设置 previewCallback。

【问题讨论】:

  • “关闭所有活动”有什么作用?也许,System.exit() 会更好地为您服务?
  • 它关闭(退出)应用程序。那是我的意图。在不是主要(根)活动的活动中单击按钮时关闭我的应用程序。而且,我在网上搜索,据说应该避免使用System.exit(),而是使用finish()
  • 一般来说,Internet 和 SO in particular 确实会警告 System.exit(),但在某些情况下,这种退出方式是最合适的。 finish() 对于所有活动不保证进程会消失,或所有服务将关闭,或所有系统资源将被释放(例如相机实例),以及速度有多快。您如何知道您的应用程序中的某些活动是否已启动?它的进程亲和性、任务亲和性等是什么?
  • 好的,我已经阅读了您链接到的帖子。而且我并没有试图终止我的应用程序。我对这套系统非常满意。我完成了我的应用程序中的所有活动,但它没有在任务管理器中显示为正在运行。我不在乎它是否还在某个地方冬眠。那是操作系统问题而不是mime。我只是想了解为什么当我注释掉我的 onDestroy() 方法时我的应用程序崩溃了。但是我从您发布的链接中学到了一些新东西,谢谢。
  • 好的,所以我弄清楚了问题所在。我偶然发现了this 的帖子。因为我在onCreate() 方法中调用finish(),所以它立即调用onDestroy() 跳过所有其他方法,如onStart()onResume()onPause() 等。

标签: android android-camera


【解决方案1】:

首先,您必须了解 android 活动生命周期 (http://developer.android.com/reference/android/app/Activity.html)。它转到 onPauses(),然后释放相机。之后再进入activity,会进入onResum()而不是oncreate(),因为相机被释放而导致NPE。

除非您的活动被销毁,否则您的活动将再次转到 onCreate()。因此,要解决您的问题,您可以在 onResume() 中检查并获取相机实例并在 onPause() 中释放或创建相机 onCreate() 并释放 onDestroy() (就像你的发现一样)。这意味着您不需要在 onPause() 和 onDestroy() 上都释放,但是,建议使用第一种方法。

【讨论】:

  • 对不起,我想我不够清楚。我了解活动生命周期。我有一个使用相机预览的功能齐全的应用程序。我已经定义了所有常见的东西。释放onPause(),取回相机实例onResume()。这一切都在那里。尝试一次关闭所有活动时,在玩耍后出现问题。我通过释放相机实例onDestroy() 解决了这个问题。这就是我不明白的地方,因为之前应该调用 onResume() 并释放相机,但显然它没有。
  • 一次关闭所有活动是什么意思?可能是问题所在。我不认为活动可以绕过 onResume()。
  • 我在文章开头解释了这个问题。我还发布了我使用的伪代码示例。这就是我感到困惑的原因。
【解决方案2】:

所以 this 帖子解释了我的问题。

因为,我在 onCreate() 方法中捕获了额外的意图,并且我还在这里获得了相机实例:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ...

    if (getIntent().getBooleanExtra("EXIT", false)) {
        finish();
    }

    ...

    maCamera = getCameraInstance();

    ...

}

来自 Android 文档:

You can call finish() from within this function, in which case onDestroy() will be immediately called without any of the rest of the activity lifecycle (onStart(), onResume(), onPause(), etc) executing.

所以onCreate() 方法运行,它获取相机实例,并在onCreate() 完成后立即跳转到onDestroy()。而且因为我只在onPause() 发布了相机实例,所以相机从未发布过。通过在 finish() 之后添加 return 来解决此问题,因此它会跳过获取相机实例。

finish();
return;

【讨论】:

  • 但是你说你只在onResume()中使用Camera,而不是onCreate()
  • 我忘了提到我也在onCreate()onResume() 中创建了相机实例,我有if 声明只有当它是null 时才能获取相机。我的错,我会更新我的问题,以便清楚。
猜你喜欢
  • 2011-05-04
  • 2014-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多