多個Activity之間傳遞數據

最近項目中要實現一個相機拍攝的效果,在A界面點擊按鈕,跳轉到B界面(拍攝照片或錄制視頻),拍攝完成后跳轉到C界面預覽,在C界面再點擊確定后,再將拍攝的照片或視頻的縮略圖放到A界面。
剛開始碰到時覺得有點棘手,想通過直接從C跳轉到A設置Intentflag屬性實現,但是發現這樣做會導致原先在A界面上的數據全部被清空(比如EditText中輸入的內容),在網上搜了一下找到了一種合適的解決方案。


兩個Activity之間傳遞數據###

首先看一下,如果是兩個Activity之間傳遞數據該怎么做,相信大部分人應該都知道如何去寫。

步驟如下:

  1. 在A界面調用startActivityForResult(intent,requestCode);
  2. 在B界面調用setResult(resultCode,intent); finish();
  3. 在A界面重寫onActivityResult(int requestCode, int resultCode, Intent data)方法,判斷requestCode,如果符合則通過data對象獲取傳遞的參數。

注意在第3步中的requestCode必須與第1步的requestCode相等,否則是沒有辦法接收到數據的

下面給出代碼:
第一步:A界面點擊按鈕跳轉到B界面。
FirstAvtivity

btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
        startActivityForResult(intent,0);//requestCode=0
    }
});

第二步:B界面點擊按鈕返回A界面,并將TextView中顯示的值傳回A界面。
SecondActivity

btn.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent();
        String text = textview.getText().toString();
        intent.putExtra("text",text);
        setResult(1,intent);//requestCode=1
        finish();
    }
});

第三步:在A界面對返回的數據進行處理,注意此時requestCode必須為0才能接受到數據。

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_first);
    ...
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == 0){
        String text = data.getStringExtra("text");
        mText.setText("接受的數據為:"+text);
    }
}

程序運行的效果如下:

兩個界面.gif

三個Activity之間傳遞數據###

知道了兩個Activity之間傳遞數據的方法,其實我們不難想到解決方案。只要進行兩次兩個Activity之間傳遞數據的過程就好了。具體步驟看下圖:

流程圖.png
  1. 在A界面調用startActivityForResult(intent,requestCode);跳轉到B。
  2. 在B界面調用startActivityForResult(intent,requestCode);跳轉到C(requestCode與1不同)。
  3. 在C界面點擊返回時調用setResult(resultCode,intent); finish();后退到B,并將數據傳給B。
  4. B界面重寫onActivityResult(int requestCode, int resultCode, Intent data)方法,判斷requestCode,如果符合則調用。setResult(resultCode,intent); finish();繼續后退一次到A,并將數據傳給A。
  5. 在A界面重寫onActivityResult(int requestCode, int resultCode, Intent data)方法,判斷requestCode,如果符合則通過data對象獲取傳遞的數據。

整個流程就是這樣,下面來看看代碼:
FirstActivity

public class FirstActivity extends AppCompatActivity {
    private TextView mText;

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

        Button btn = (Button) findViewById(R.id.button);
        mText = (TextView) findViewById(R.id.textview);

        //1、跳轉到B
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
                startActivityForResult(intent,0);
            }
        });


    }

    //5、接受B的數據(實際是C的,B只是轉發)并處理
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == 0){
            String text = data.getStringExtra("text");
            mText.setText("接受的數據為:"+text);
        }
    }

}

SecondActivity

public class SecondActivity extends AppCompatActivity {
    private TextView textview;

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

        Button btn = (Button) findViewById(R.id.button2);
        textview = (TextView) findViewById(R.id.textView);

        //2、跳轉到C
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(SecondActivity.this,ThirdActivity.class);
                startActivityForResult(intent,1);

            }
        });
    }

    //4、接受C的數據,返回并傳遞給A
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(requestCode == 1){
            Intent intent = new Intent();
            String text = data.getExtras().getString("text");
            intent.putExtra("text",text);
            setResult(3,intent);
            finish();
        }
    }
}

ThirdActivity

public class ThirdActivity extends AppCompatActivity {
    private EditText edittext;

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

        Button btn = (Button) findViewById(R.id.button3);
        edittext= (EditText) findViewById(R.id.edittext);

        //3、返回B,并傳遞數據,執行B的onActivityResult()方法
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent();
                intent.putExtra("text",edittext.getText().toString());
                setResult(1,intent);
                finish();
            }
        });
    }
}

最后是效果圖:

三個界面.gif

可以看到跳轉到C后,點擊按鈕直接回退到了A,并且也拿到了C傳遞的數據。


新的問題###

由于自己對這方面理解不準,后來發現了一個問題,這樣的代碼,在進行A->B->C->A這樣的順序時沒有問題,而如果在B或者C界面返回時,會出現程序崩潰的情況。
問題其實很簡單,比如在重寫A界面onActivityResult()方法時,只判斷了requestCode,這樣,其實在B界面按下返回鍵同樣也是能執行后面的接收數據代碼的,而這時并沒有從B界面傳數據回來,因而獲取的數據自然為空,從而導致出錯。解決方法很簡單:在onActivityResult()方法中同時判斷requestCode與resultCode,只有同時滿足兩個條件,才表明接收到數據,從而執行處理數據的代碼。
修改代碼:
FirstActivity

//5、接受B的數據(實際是C的,B只是轉發)并處理
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == 0 && resultCode == 3){//resultCode為4中setResult(3,intent)設置的值
        String text = data.getStringExtra("text");
        mText.setText("接受的數據為:"+text);
    }
}

SecondActivity

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == 1 && resultCode == 1){//添加resultCode判斷
        Intent intent = new Intent();
        String text = data.getExtras().getString("text");
        intent.putExtra("text",text);
        setResult(3,intent);
        finish();
    }
}

這樣如果從B界面直接返回的話,會因為resultCode不滿足條件,不會執行處理數據的代碼,也就不會崩潰了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容