天天看點

Android程式設計權威指南(第三版)第五章:章節梳理、挑戰練習:堵住漏洞

第五章内容非常繁多,需要反複學習。

總結:

5.2 啟動activity:

啟動activity方法:

(1):

調用startActivity(Intent),直接啟動對應的Activity

Intent intent=new Intent(QuizActivity.this,CheatActivity.class);
startActivity(intent);
           

(2):

①使用intent extra,将資料傳入intent,然後傳入對應的Activity.

知識點一:Extra是一個鍵值對,鍵的設定需要用包名修飾,以避免重名的問題。由該Activity産生的資料,應在該Activity類下建立專門方法,友善其它Activity調用。

private static final String EXTRA_ANSWER_IS_TRUE=
"com.bignerdranch.android.geoquiz.answer_is_true";

public static Intent newIntent(Context packageContext,boolean answerIsTrue){
Intent intent= new Intent(packageContext,CheatActivity.class)
intent.putExtra(EXTRA_ANSWER_IS_TRUE,answerIsTrue);
return intent;
}
           

調用執行個體:

boolean answerIsTrue =mQuestionBank[mCurrentIndex].isAnswerTrue();
Intent intent=CheatActivity.newIntent(QuizActivity.this,answerIsTrue);
startActivity(intent);
           

②擷取intent中extra中資料

private boolean mAnswerIsTrue;

mAnswerIsTrue = getIntent().getBooleanExtra(EXTRA_ANSWER_IS_TRUE,false);
           

編碼邏輯:

1.a是B_Activity要向A_Activity傳輸的資料,先将a資料的EXTRA_A鍵值在A_Activity中聲明好,并建立專門的newIntent建立方法,用于建立一個傳輸EXTRA_A的Intent

2.在B_Activity在需要傳輸a值時,調用A_Activity的newIntent方法,

starActivity(Intent)啟動A_Activity同時傳值如A_Activity。

3.A_Activity,調用getIntet().getBooleanExtra(EXTRA_ANSWER_IS_TRUE,false);

以上方法,時單車道資訊傳輸:

即B_Activity->A_Activity 傳輸資料a,但是A_Activity不能将其資料傳輸回B_Activity。

實作B_Activity->A_Activity->B_Activity:

①聲明 requestCode變量,requestCode變量的作用在于,一個B_Activity可能同時啟動了C_Activity和A_Activity,requestCode可以幫助B_Activity判斷消息回饋方來自于哪一個子activity.

private static final int REQUEST_CODE_CHEAT=0;
 
//棄用startActivity(intent);
 startActivityForResult(intent, REQUEST_CODE_CHEAT);
           

②設定"傳回結果"

這裡有個相關知識,我們要設定傳回結果,就需要setResult(int resultCode)/setResult(int resultCode,Intent data)函數

resultCode 有預定義常量:RESULT_OK,RESULT_CANCELED,預設值為RESULT_CANCELED

由于資料需要綁定在Intent裡面,是以需要通過EXTRA綁定如Intent。由于EXTRA是鍵值對,是以需要聲明對應鍵值EXTRA_ANSWER_SHOWN

private static final String EXTRA_ANSWER_SHOWN =
"com.bignerdranch.android.geoquiz.answer_shown";

private void setAnserShownResult(boolean isAnswerShown){
	Intent data = new Intent();
	data.putExtra(EXTRA_ANSWER_SHOWN,isAnswerShown);
	setResult(RESULT_OK,data);
}
           

③擷取“傳回結果”

需要擷取傳回結果,需要兩個步驟,B_Activity把從A_Activity傳輸過來的Intent裡的Extra資料解析出來,我們知道要擷取Intent中的Extra,需要Extra鍵,而該鍵存儲在A_Activity中,是以要在A_Activity建立一個靜态方法供B_Activity使用.

最後通過複寫 onActivityResult(…)方法實作資料擷取

B_Activity中的靜态方法:

public static boolean wasAnswerShown(Intent result){
	return result.getBooleanExtra(EXTRA_ANSWER_SHOWN,false);
}
           

複寫onActivityResult(…)

@override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
	if(resultCode!=Activity.RESULT_OK){
		return;
		}
	if(requestCode==REQEUST_CODE_CHEAT){
		if (data==null){retun;}
		mIsCheater = CheatActivity.wasAnswerShown(data);
		//mIsCheater 為事先聲明的變量 用于存儲傳回來的資料。
	}
}
           

編碼邏輯

1.startActivityForResult(intent,requestCode),啟動子activity

2.子activity 聲明Extra鍵值,聲明私有方法調用serResult(int,Intent)存儲資料.

3.子activity中聲明靜态方法解析Intent中Extra,複寫父activity中的onActivityResult(…)方法

挑戰題:

Android程式設計權威指南(第三版)第五章:章節梳理、挑戰練習:堵住漏洞

1.使用者作弊後,可以旋轉CheatActivity,則需要在CheatActivity中進行saveInstanceState,需要聲明一個變量mCheatState=false來儲存使用者是否作弊的狀态 如果使用者點選了作弊按鈕,則mCheatState=ture

在onCreat函數被調用時,做檢查,如果作弊狀态為true,則調用setResult()函數

private static final String KEY_CHEAT_STATE = "cheat_state";
    private boolean mCheatState=false;


	    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_cheat);

        if(savedInstanceState!=null){//提取狀态值
            mCheatState=savedInstanceState.getBoolean(KEY_CHEAT_STATE,false);
        }
        if(mCheatState){//判定作弊狀态
            setAnswerShownResult(true);
        }
	...
	...
	...
	}

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(KEY_CHEAT_STATE,mCheatState);
    }
           

2.依然是将mIscheater值通過saveInstance儲存就好了。這裡沒有難度。且代碼與第三題邏輯重複,不做編寫。

3.可以跳過的主要原因是作弊記錄無法針對到題目,是以我們将mIscheater這裡改為boolean數組即可.

private  boolean[] mIsCheater= new boolean[]{false,false,false,false,false,false};

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d(TAG,"onCreat(Bundle) called");
        setContentView(R.layout.activity_main);

        if(savedInstanceState!=null){
            mIsCheater=savedInstanceState.getBooleanArray(KEY_CHEAT_STATE);
        }
        ...
        ...
        ...
    }
    public void onSaveInstanceState(Bundle saveInstanceState) {
        super.onSaveInstanceState(saveInstanceState);
        saveInstanceState.putBooleanArray(KEY_CHEAT_STATE,mIsCheater);
    }

	//原代碼中所有mIsCheater改為mIsCheater[mCurrentIndex]