2012-03-06 84 views
9

首先,我是Android開發新手,請耐心等待。在Android上創建兩次活動

我將從界面開始,我有一個按鈕,一旦你點擊它,開始一個結果的活動。

public class GUIActivity extends Activity 

    @Override 
    public void onClick(....){ 
     Intent intent = new Intent(getApplicationContext(), GetImageActivity.class); 
     intent.putExtra("action", FROM_CAMERA); 
     startActivityForResult(intent, GET_IMAGE); 
    } 

    @Override 
    onActivityResult(int requestCode, int resultCode, Intent data){ 
     Log(TAG, "onActivityResult"); 
     //handle result 
    } 

} 

GetImageActivity類是其他兩項活動的包裝,一個從攝像機捕獲和其他的圖像從庫中得到它。它返回所選圖像的Uri對象。

public class GetImageActivity extends Activity{ 
    private Uri mediaUri; 

    @Override 
    public void onCreate(Bundle savedInstanceState){ 
     super.onCreate(savedInstanceState); 
     Bundle extras = getIntent().getExtras(); 
     int action = extras.getInt("action"); 

     Log.d(TAG, "onCreate"); 

     switch(action){ 
      case FROM_CAMERA: 
       mediaUri = Uri.fromFile(new File(....)); 
       Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); 
       intent.putExtra(MediaStore.EXTRA_OUTPUT, mediaUri); 

       Log.d(TAG, "Calling camera activity" 
       startActivityForResult(intent, action); 
       break; 
      case FROM GALLERY: 
       //... 
     }    
    } 

    @Override 
    onActivityResult(int requestCode, int resultCode, Intent data){ 
     Log.d(TAG, "onActivityResult"); 

     switch(requestCode){ 
      case FROM_CAMERA: 
       if(resultCode == Activity.RESULT_OK){ 
        Intent data = new Intent(); 
        data.putExtra("uri", mediaUri); 
        setResult(Activity.RESULT_OK, data); 
        finish(); 
       }else{ 
        Log.e(TAG, "Camera activity failed!"); 
        setResult(Activity.RESULT_CANCELED); 
        finish(); 
       } 
       break; 

      case FROM_GALLERY: 
       //... 

     } 
    } 
} 

這是預期,當用戶點擊該按鈕會發生:

  • 相機活動應該開始。
  • 一旦用戶拍攝照片,它應該將其URI發送回GUI類。

有時(通常50%的機率是)它工作於預期,但其他時間,這是發生了什麼:

  • 相機活動開始。
  • 用戶拍攝照片。
  • 攝像機活動重新開始。
  • 用戶可以拍攝另一張照片或返回。
  • 無論哪種情況,返回到GUI類的URI都不存在。

我已經添加了一些調試日誌行來跟蹤事件的順序。當我得到的不良行爲,這是輸出I得到:

  • GetImageActivity - 的onCreate
  • GetImageActivity - 呼叫相機活動

相機打開,一旦我拍攝的照片,它說:

  • GetImageActivity - 的onCreate(再次)
  • GetImageActivity - 呼叫相機活動
  • GetImageActivity - onActivityResult

相機第二次打開。用戶拍攝另一張照片和:

  • GetImageActivity - onActivityResult
  • GUIActivity - onActivityResult

所以我的問題是,有什麼能引起GetImageActivity被調用兩次?

回答

6

問題在於對Activity生命週期的處理不當。

onCreate的第二個呼叫用於處理結果。

Android可能會選擇銷燬正在等待撥打onActivityResultActivity;尤其是當可用內存不足時。有些設備對於銷燬任務堆棧上的活動顯得更積極。我可以可靠地在三星設備上重新創建問題,將其設置爲稱爲「嚴格模式」的調試模式。

您可以驗證這是否是你的問題通過登錄調用onCreate & onDestroy

在活動被破壞的情況下,當活動結果需要處理時,Android會重新創建Activity,並將savedInstanceState傳遞給onCreate。所以,補救措施是檢查您的GetImageActivity.onCreate中的savedInstanceState的值。如果不是null,則不要致電startActivity,因爲您的Activity正在重新創建,致電onActivityResult

(可選)如果您需要保留任何狀態,則覆蓋onSaveInstanceState(Bundle outState)並將需要的數據放入outState

0

當您撥打startActivityForResult時,它告訴Android,您希望將結果傳送到撥打該電話的Activity。這解釋了您在登錄GetImageActivity - onCreate (again)時看到的內容。

既然你叫你第一活動startActivityForResult,就是GUIActivity比你應該調用GetImageActivitysetResult正確傳回的結果。

所以在GetImageActivity.onActivityResult()您電話之前finish()你應該叫setResult,這樣當您返回到GUIActivity它可以處理預期的結果。

+0

我將修改代碼,使其更清晰。它在'GetImageActivity'類中說//處理結果,我實際上調用'setResult()'。需要注意的是,即使在第一次調用onActivityResult()方法之前,該活動也會再次創建。 –

1

在AndroidManifest.xml添加到您的活動定義:

android:launchMode = "singleInstance" 
1

在AndroidManifest.xml您的活動定義這個地址:

android:launchMode = "singleTask"