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)