Redirection的意思就是“呼叫轉移,重寄”的意思
我們也許會再程序開發中遇到這種情況,需要從一個Activity(A)跳轉到另一個Activity(B),當在這個Activity(B)中處理完一些操作后在返回到之前的Activity(A)。常用的方法是在A中調用startActivityForResult(intent, requestCode);來跳轉到B,并在A中重寫方法:
protected void onActivityResult(int requestCode, int resultCode,Intent data) {........ },在B中處理完操作后調用語句:setResult(resultCode);來返回A并執行A中的onActivityResult(int requestCode, int resultCode,Intent data)方法。
(為了方便起見,下文中提到的ABC都是3個不同的Activity)
如果我們需要從A跳轉到B,在B中處理完一些操作后返回到C,在C中我們可以分別跳轉到A或者B中。哪么你會怎么做呢?如果你是用:startActivity(intent);這種最初級的Activity之間的跳轉,那么只能說你還是個初級入門的android開發者。下面我來講解下Rediretion這個Demo。交你巧妙的實現Activity之間的跳轉。
首先看下第一個Activity(A)中的代碼:
Activity A:
public class RedirectEnter extends Activity
{
??? @Override
?protected void onCreate(Bundle savedInstanceState)
??? {
??????? super.onCreate(savedInstanceState);
??????? setContentView(R.layout.redirect_enter);
??????? // Watch for button clicks.
??????? Button goButton = (Button)findViewById(R.id.go);
??????? goButton.setOnClickListener(mGoListener);
??? }
??? private OnClickListener mGoListener = new OnClickListener()
??? {
??????? public void onClick(View v)
??????? {
??????????? // Here we start up the main entry point of our redirection
??????????? // example.
??????????? Intent intent = new Intent(RedirectEnter.this, RedirectMain.class);//跳轉到Activity(C)
??????????? startActivity(intent);
??????? }
??? };
}
很簡單的一段代碼,一個按鈕跳轉到下一個Activity(C)。
也許你會感到奇怪,為什么是C而不是B呢?是不是我打錯了?其實就是C啦。我來說下這里的原理也是重點(其實很簡單,講的多只是想讓入門的朋友能更明白)。
A跳轉到B,其實是A先到C然后在到B,只是A剛剛跳轉到C還沒有顯示任何東西的時候又直接跳轉到B了。所以我們根本察覺不到C的存在,但恰恰相反,C是這個例子中最重要的地方,也是最復雜的地方,下面我們直接說C(B就很好理解了)。
Activity C:
public class RedirectMain extends Activity {
??? static final int INIT_TEXT_REQUEST = 0;
??? static final int NEW_TEXT_REQUEST = 1;
??? @Override
?protected void onCreate(Bundle savedInstanceState) {
??????? super.onCreate(savedInstanceState);
??????? setContentView(R.layout.redirect_main);
??????? // Watch for button clicks.
??????? Button clearButton = (Button)findViewById(R.id.clear);
??????? clearButton.setOnClickListener(mClearListener);
??????? Button newButton = (Button)findViewById(R.id.newView);
??????? newButton.setOnClickListener(mNewListener);
//這里就是關鍵,程序第一次加載時loadPrefs()方法的返回值一定是false,所以直接在跳轉到B了。
??????? if (!loadPrefs()) {
??????????? Intent intent = new Intent(this, RedirectGetter.class);
??????????? startActivityForResult(intent, INIT_TEXT_REQUEST);
??????? }
??? }
??? @Override
?protected void onActivityResult(int requestCode, int resultCode,
??Intent data) {
??????? if (requestCode == INIT_TEXT_REQUEST) {
?????//如果我們在B中點擊返回按鈕,那么默認的resultCode是?RESULT_CANCELED,所以關閉當前Activity,就又放回到A了。(第一次請求時)
?????????? if (resultCode == RESULT_CANCELED) {
??????????????? finish();
??????????? // Otherwise, there now should be text...? reload the prefs,
??????????? // and show our UI.? (Optionally we could verify that the text
??????????? // is now set and exit if it isn't.)
??????????? } else {
??????????????? loadPrefs();//執行loadPrefs(),這時RedirectData.xml文件中的text鍵已經不為null了。因為在B中為它設置了值。
??????????? }
??????? } else if (requestCode == NEW_TEXT_REQUEST) {??
??????????? // In this case we are just changing the text, so if it was
??????????? // cancelled then we can leave things as-is.
??????????? if (resultCode != RESULT_CANCELED) {
??????????????? loadPrefs();
??????????? }
??????? }
??? }
//獲取(沒有就自動創建)RedirectData.xml文件,并從文件中獲取鍵為text對應的值,( SharedPreferences 文件內的內容都是通過鍵值對的形式存放的),程序第一次加載當然不會有數據,所以返回false。下面我們去看看B中的程序,一會或過頭再來看C。
??? private final boolean loadPrefs() {
??????? SharedPreferences preferences = getSharedPreferences("RedirectData", 0);
??????? mTextPref = preferences.getString("text", null);? //此句表示如果沒有名為text的鍵,則返回null
??????? if (mTextPref != null) {
??????????? TextView text = (TextView)findViewById(R.id.text);
??????????? text.setText(mTextPref);
??????????? return true;
??????? }
??????? return false;
??? }
??? private OnClickListener mClearListener = new OnClickListener() {
??????? public void onClick(View v) {
??????????? // Erase the preferences and exit!
??????????? SharedPreferences preferences = getSharedPreferences("RedirectData", 0);
??????????? preferences.edit().remove("text").commit();
??????????? finish();
??????? }
??? };
??? private OnClickListener mNewListener = new OnClickListener() {
??????? public void onClick(View v) {
??????????? // Retrieve new text preferences.
??????????? Intent intent = new Intent(RedirectMain.this, RedirectGetter.class);
??????????? startActivityForResult(intent, NEW_TEXT_REQUEST);
??????? }
??? };
??? private String mTextPref;
}
?
Activity B:
public class RedirectGetter extends Activity
{
??? @Override
?protected void onCreate(Bundle savedInstanceState)
??? {
??????? super.onCreate(savedInstanceState);
??????? setContentView(R.layout.redirect_getter);
??????? // Watch for button clicks.
??????? Button applyButton = (Button)findViewById(R.id.apply);
??????? applyButton.setOnClickListener(mApplyListener);
??????? // The text being set.
??????? mText = (EditText)findViewById(R.id.text);
??? }
????private OnClickListener mApplyListener = new OnClickListener()
??? {
??????? public void onClick(View v)
??????? {
//當點擊確定按鈕,將文本框內輸入的內容存放到RedirectData.xml文件中,并于鍵text對應,(也就是作為text鍵的值)
??????????? SharedPreferences preferences = getSharedPreferences("RedirectData", 0);
??????????? SharedPreferences.Editor editor = preferences.edit();
??????????? editor.putString("text", mText.getText().toString());
??????????? if (editor.commit()) {
??????????????? setResult(RESULT_OK);? //提交后返回上一個Activity。(由于C到B的跳轉方法是startActivityForResult(intent,requestCode),所以返回到C中執行方法 onActivityResult(int requestCode, int resultCode,Intent data)中相應的語句)
??????????? }
??????????? finish();
??????? }
??? };
??? private String mTextPref;
??? EditText mText;
}
也許沒有圖你看的很郁悶,所以還是自己看看ApiDemo吧。總而言之,原理是:
A通過startAcitivity到C然后直接通過startActvityForResult到B,B中完成操作通過setResult返回到C,在C中通過判斷 SharedPreferences preferences文件中是否有在B中存放的數據,如果有就再C中顯示,并且下次程序運行會直接從A跳轉到C,當在C中清除了B中存放的數據,也就是 SharedPreferences preferences文件中的數據,那么A有恢復到初始狀態,及A跳轉到B。C是中間站,決定了A的下一次跳轉究竟是到B還是C,C也是自由者,他可以在A和B中隨意跳轉。(finish自身及跳轉到A,startActvityForResult方法及跳轉到B)