【问题标题】:Activity gets killed while executing the camera intentActivity 在执行相机意图时被杀死
【发布时间】:2012-03-16 19:57:32
【问题描述】:

[编辑:问题已解决。请参阅下面的my answer。]

在我的应用程序中,我调用系统相机拍照,然后在onActivityResult 中处理结果。你知道的,平常的。它曾经可以工作,但现在我的通话活动在我拍照时被杀死了。具体来说,onDestroy() 在我按下相机快门后立即调用我的活动。照片确实被拍摄并保存(我已经检查过文件是否写入了 SD 卡上)。在我接受照片后,不是返回调用活动并调用onActivityResult,而是调用活动堆栈中的前一个活动。我在 logcat 中没有看到任何异常。我的自定义异常处理程序没有被调用。如果重要的话,我的应用程序还包括一个侦听 GPS 更新的服务,但我在 onPause() 中取消了所有接收器的注册。

这是MyCallingActivity.onDestroy() 的调用堆栈:

Thread [<1> main] (Suspended (breakpoint at line 303 in NewPlaceDetailsActivity))   
    NewPlaceDetailsActivity.onDestroy() line: 303   
    ActivityThread.performDestroyActivity(IBinder, boolean, int, boolean) line: 2663    
    ActivityThread.handleDestroyActivity(IBinder, boolean, int, boolean) line: 2694 
    ActivityThread.access$2100(ActivityThread, IBinder, boolean, int, boolean) line: 117    
    BinderProxy(ActivityThread$H).handleMessage(Message) line: 968  
    ActivityThread$H(Handler).dispatchMessage(Message) line: 99 
    Looper.loop() line: 130 
    ActivityThread.main(String[]) line: 3687    
    Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]  
    Method.invoke(Object, Object...) line: 507  
    ZygoteInit$MethodAndArgsCaller.run() line: 842  
    ZygoteInit.main(String[]) line: 600 
    NativeStart.main(String[]) line: not available [native method]  

这就是我启动相机活动的方式,以防您想知道:

protected void startCamera() {
    createPhotoDirsIfNeeded();

    String fileName = "temp.jpg";  
    ContentValues values = new ContentValues();  
    values.put(MediaStore.Images.Media.TITLE, fileName);  
    m_capturedImageUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);  

    m_photoFileName = APP_PHOTO_PATH + "/" + DateFormat.format(DATE_FORMAT, Calendar.getInstance().getTime()) + ".jpg";
    File picFile = new File(m_photoFileName);
    if(picFile.exists()) {
        picFile.delete();
    }

    // start the camera activity
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT,  Uri.fromFile(picFile));
    startActivityForResult(intent, IntentHelper.REQUEST_TAKE_PHOTO);
}

如何找出我的 Activity 为何会被杀死,并从堆栈中删除而不是重新创建?

【问题讨论】:

  • 发布相关代码。看来您的代码查杀应用可能正在调用一些与查杀活动相关的命令。
  • 发布了更多代码。 onActivityResult() 永远不会被调用,因为当我从相机返回时,活动已被破坏。
  • NewPlaceDetailsActivity.onDestroy()中,检查isFinishing()是否返回true。如果没有,您的活动将被销毁以便重新启动(可能是由于拍摄照片时方向发生变化)。
  • isFinishing() 返回真。我还确保这次不要改变方向。另外,即使由于方向改变而重新启动,onActivityResult 仍然会被调用,不是吗?
  • 首先,您的进程极有可能被终止,以释放内存。没有什么不妥。关于您的异常,您在 Eclipse 中捕获异常。让执行继续,然后检查 LogCat 堆栈跟踪。如果您的NewPlaceDetailsActivity 中的第 303 行仍然显示您有问题,您将需要检查该行的内容。

标签: android android-activity android-intent


【解决方案1】:

好的,我发现了问题。问题不在于活动被杀死,而在于它没有被恢复。我意识到,当您的活动在清单中以android:noHistory="true" 声明时,可能会发生这种情况。因此,该活动在被杀死时从堆栈中删除,并显示之前的活动。

我去掉noHistory参数后,在使用相机后,activity又开始出现了。

【讨论】:

  • 我认为它的方向改变问题。你也可以从你的清单文件中解决这个问题。
  • 不,这不是方向变化。我确保在测试期间方向保持不变。
  • 哦,是的 android:noHistory="true" 如果你保留这意味着你没有监控活动的状态,仅仅意味着当控制离开你的活动时它被系统杀死。
【解决方案2】:

我猜问题是 1)在您的异常处理程序的自定义实现中和 2)这一行:

intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(picFile));
  1. 当您尝试从返回的Intent 访问数据时,您的异常处理程序实现不允许您看到onActivityResult 方法中抛出的NullPointerException
  2. 这似乎是一个错误,如果输出文件已作为 Intent 启动相机 Activity 的附加文件,则阻止 Intent 传递给 onActivityResult 方法。

尝试删除该行并查看相机 Activity 完成后是否重新创建了您的 Activity。

【讨论】:

  • EXTRA_OUTPUT 确实有同样的问题。看来android不喜欢你指定一个输出文件夹。这对于涉及缓冲和流式传输的视频更为关键。我通过等待拍摄照片或视频然后将其移动到用户想要的位置来解决问题。
  • 嗨——我已经删除了我指定文件名的行。我还删除了自定义异常处理程序(首先打开它只是为了调试这个问题)。问题仍然存在。所以肯定有别的东西。
  • 你没有得到任何异常吗?显示您的onActivityResult 代码。
  • @a.ch.: onActivityResult 从未被调用过。我已经找到原因了,请看我自己的回答。
【解决方案3】:

请按以下步骤操作:

1)  Add this in manifest :
    <uses-feature android:name="android.hardware.camera"></uses-feature>

2)  startCamera() :
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT,  Uri.fromFile(picFile));
    startActivityForResult(intent, IntentHelper.REQUEST_TAKE_PHOTO);


3)  if (requestCode == PICTURE_RESULT) //
             if (resultCode == Activity.RESULT_OK) {
                // Display image received on the view
                 Bundle b = data.getExtras(); // Kept as a Bundle to check for other  things in my actual code
                 Bitmap pic = (Bitmap) b.get("data");

                 if (pic != null) { // Display your image in an ImageView in your layout (if you want to test it)
                     pictureHolder = (ImageView) this.findViewById(R.id.IMAGE);
                     pictureHolder.setImageBitmap(pic);
                     pictureHolder.invalidate();
                 }
             }
             else if (resultCode == Activity.RESULT_CANCELED) {...}
    }

如果此代码仍然不适合您,请参考以下链接:

【讨论】:

  • 嘿,谢谢。我实际上发现了问题(请参阅我自己的答案)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-09
  • 2017-01-18
  • 2015-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多