首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

Android 拍照 onActivityResult 閃退之謎:進程被系統回收

     編輯:程式設計疑難解答

現象

調用系統相機或第三方相機(如美顏相機)拍照後,約 20% 機率導致 App 閃退,無錯誤日誌,onActivityResult 似乎執行到 `return` 即消失,成員變數變 `null`,連 `UncaughtExceptionHandler` 都捕捉不到。

根本原因

**拍照過程中原 Activity 進程被系統殺死回收記憶體**。第三方相機佔用大量記憶體,觸發 Low Memory Killer,導致宿主應用進程被終止。系統重新啟動 Activity 時,成員變數(含儲存照片路徑的 `tempPhotoPath`)重置為初始值(`null`),而開發者代碼未處理此情況,直接使用 `null` 導致崩潰。

解決方案

  1. 不依賴成員變數儲存臨時文件路徑,改用 `Intent` 的 `EXTRA_OUTPUT` 指定 `Uri`,並在 `onActivityResult` 中直接從 `Intent` 或已知 `Uri` 讀取。
  2. 在 `onSaveInstanceState` 保存關鍵路徑,`onCreate`/`onRestoreInstanceState` 恢復。
  3. 使用 `FileProvider` 產生 `content://` Uri,避免 `file://` 在 Android 7+ 崩潰。
  4. 啟動相機前檢查權限與儲存空間。

關鍵代碼調整

// 拍照前
String photoPath = getExternalFilesDir(Environment.DIRECTORY_PICTURES) + "/IMG_" + System.currentTimeMillis() + ".jpg";
File photoFile = new File(photoPath);
Uri photoUri = FileProvider.getUriForFile(this, getPackageName() + ".provider", photoFile);
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
startActivityForResult(intent, REQUEST_TAKE_PHOTO);

// onActivityResult
if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
    // 直接使用 photoFile 或 photoUri,不依賴成員變數
    Bitmap bitmap = BitmapFactory.decodeFile(photoFile.getAbsolutePath());
    // ...
}

理解「進程被殺死重建」是 Android 生命週期核心,妥善保存/恢復狀態才能避免此類「詭異閃退」。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved