在Android里面,从一个Activity跳转到另一个Activity、再返回,前一个Activity默认是能够保存数据和状态的。但这次我想通过利用startActivityForResult达到相同的目的,虽然看起来变复杂了,但可以探索下startActivityForResult背后的原理和使用注意事项。
要实现的功能如下:
从Activity A将数据传到Activity B,再从Activity B中获取数据后,再传回Activity A。在Activity B中添加一个“回到上一页”的Button,返回到Activity A之后,需要保留之前输入的相关信息,我们用startActivityForResult来拉起Activity B,这样,Activity A就会有一个等待Activity B的返回。
具体步骤如下:
- 在Activity A中有一个Button,点击Button后,获取要传到Activity B的数据,将数据封装到Bundle中,再调用startActivityForResult将数据传到Activity B
- Activity A 重写onActivityResult函数,判断requestCode和resultCode是否是我们预期的结果,如果是,那么从Bundle中获取数据,重新显示在Activity A中
- 在Activity B中获取Activity A传过去的Intent对象,并取出Bundle对象,再从Bundle中取出数据字段,显示在当前页面
- Activity B中也有一个Button,点击Button后,调用setResult传回结果,并关闭当前页面。因此,看起来的效果就是回到了Activity A
源码如下:
1、Activity A的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | public class ExampleActivity extends Activity { private EditText mEditText; private RadioButton mRb1; private RadioButton mRb2; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.main_page_layout); Button button = findViewById(R.id.buttonGoToLayout2); button.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { mEditText = findViewById(R.id.editText); // 获取输入的身高 double height = Double.parseDouble(mEditText.getText().toString()); // 获取性别 String gender = "" ; mRb1 = findViewById(R.id.radioButtonMale); mRb2 = findViewById(R.id.radioButtonFemale); if (mRb1.isChecked()) { gender = "M" ; } else { gender = "F" ; } Intent intent = new Intent(ExampleActivity. this , SecondActivity. class ); // 将数据传入第二个Activity Bundle bundle = new Bundle(); bundle.putDouble( "height" , height); bundle.putString( "gender" , gender); intent.putExtras(bundle); startActivityForResult(intent, 0 ); } }); } @Override protected void onActivityResult( int requestCode, int resultCode, Intent data) { super .onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK && requestCode == 0 ) { Bundle bundle = data.getExtras(); double height = bundle.getDouble( "height" ); String gender = bundle.getString( "gender" ); mEditText.setText( "" + height); if (gender.equals( "M" )) { mRb1.setChecked( true ); } else { mRb2.setChecked( true ); } } } } |
2、布局文件main_page_layout.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | <RelativeLayout xmlns:android= "http://schemas.android.com/apk/res/android" android:layout_width= "match_parent" android:layout_height= "match_parent" android:layout_gravity= "center" > <TextView android:id= "@+id/textView1" android:layout_width= "match_parent" android:layout_height= "wrap_content" android:text= "计算标准体重" android:paddingTop= "20dp" android:paddingLeft= "20dp" android:textSize= "30sp" /> <TextView android:text= "性别:" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:id= "@+id/textView3" android:layout_alignStart= "@id/textView1" android:layout_marginTop= "38dp" android:layout_below= "@id/textView1" android:layout_marginStart= "46dp" /> <TextView android:text= "身高:" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:id= "@+id/textView4" android:layout_alignStart= "@id/textView1" android:layout_marginStart= "46dp" android:layout_below= "@id/textView3" android:layout_marginTop= "29dp" /> <EditText android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:id= "@+id/editText" android:layout_toEndOf= "@id/textView4" android:layout_marginStart= "36dp" android:autofillHints= "@string/app_name" android:hint= "0" android:layout_alignBaseline= "@id/textView4" /> <TextView android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:text= "厘米" android:layout_alignBaseline= "@id/editText" android:layout_toRightOf= "@id/editText" android:layout_marginStart= "10dp" /> <RadioButton android:layout_below= "@id/textView1" android:id= "@+id/radioButtonMale" android:text= "男" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:layout_alignStart= "@id/textView1" android:layout_marginTop= "30dp" android:layout_marginStart= "113dp" /> <RadioButton android:id= "@+id/radioButtonFemale" android:text= "女" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:layout_below= "@id/textView1" android:layout_toEndOf= "@id/radioButtonMale" android:layout_marginLeft= "15dp" android:layout_marginTop= "30dp" android:layout_marginStart= "49dp" /> <Button android:text= "计算" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:id= "@+id/buttonGoToLayout2" android:layout_marginTop= "90dp" android:layout_below= "@id/radioButtonMale" android:layout_alignStart= "@id/textView1" android:layout_marginStart= "92dp" /> </RelativeLayout> |
3、Activity B的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | public class SecondActivity extends Activity { private Intent mIntent; private Bundle mBundle; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.second_layout); mIntent = getIntent(); mBundle = mIntent.getExtras(); // 记得判空 if (mBundle == null ) { return ; } // 获取Bundle中的数据 double height = mBundle.getDouble( "height" ); String gender = mBundle.getString( "gender" ); // 判断性别 String genderText = "" ; if (gender.equals( "M" )) { genderText = "男性" ; } else { genderText = "女性" ; } // 获取标准体重 String weight = getWeight(gender, height); // 设置需要显示的文字内容 TextView textView = findViewById(R.id.textView2); textView.setText( "你是一位" + genderText + "\n你的身高是" + height + "厘米\n你的标准体重是" + weight + "公斤" ); Button button = findViewById(R.id.buttonGoBack); button.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { // 设置结果,并关闭页面 setResult(RESULT_OK, mIntent); finish(); } }); } // 四舍五入格式化 private String format( double num) { NumberFormat formatter = new DecimalFormat( "0.00" ); return formatter.format(num); } // 计算标准体重的方法 private String getWeight(String gender, double height) { String weight = "" ; if (gender.equals( "M" )) { weight = format((height - 80 ) * 0.7 ); } else { weight = format((height - 70 ) * 0.6 ); } return weight; } } |
4、Activity B的布局:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | android:layout_width = "match_parent" android:layout_height = "match_parent" > < TextView android:text = "This is the second layout" android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:id = "@+id/textView2" android:paddingTop = "30dp" android:paddingStart = "50dp" /> < Button android:layout_width = "wrap_content" android:layout_height = "wrap_content" android:id = "@+id/buttonGoBack" android:text = "回到上一页" android:layout_alignStart = "@id/textView2" android:layout_below = "@id/textView2" android:layout_marginTop = "54dp" android:layout_marginStart = "52dp" /> </ RelativeLayout > |
不过这里有3个地方需要注意:
1.startActivityForResult的第二个参数requestCode传的是0,那么我们分别看下传递的值小于0和大于0是什么结果:
(1)传一个小于0的值,比如-1:等同于调用 startActivity,onActivityResult不会被调用
(2)传一个大于0的值,比如1:效果等同于传0,onActivityResult的第一个参数正是我们通过startActivityForResult传递的requestCode
2.onActivityResult的第二个参数resultCode:它是第二个activity通过setResult返回的,常用的取值有2个:RESULT_CANCELED、RESULT_OK
(1)RESULT_CANCELED:Activity B拉起失败,比如crash
(2)RESULT_OK:Activity B操作成功后的返回值
还有一个不太常用的取值:RESULT_FIRST_USER,Android源码对这个取值的定义是“user-defined activity results”(用户自定义的),我在源码中全局搜索了下,用的地方不多,挑了一两个使用的地方:
(1)PackageInstaller下面的InstallFailed.java(安装apk失败的相关页面)
1 2 3 4 5 6 7 8 9 | protected void onCreate( @Nullable Bundle savedInstanceState) { super .onCreate(savedInstanceState); int statusCode = getIntent().getIntExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE); if (getIntent().getBooleanExtra(Intent.EXTRA_RETURN_RESULT, false )) { // …….. setResult(Activity.RESULT_FIRST_USER, result); finish(); } |
(2)PackageInstaller下面的InstallStaging.java
1 2 3 4 5 | private void showError() { ( new ErrorDialog()).showAllowingStateLoss(getFragmentManager(), "error" ); // ……. setResult(RESULT_FIRST_USER, result); } |
PackageInstaller下面的UninstallerActivity.java(卸载apk的相关页面):在onCreate方法里面有多处设置为RESULT_FIRST_USER。
因此,我的理解是业务自身在一些错误或无效的场景下使用,由业务自己定义。
3. 如果启动Activity B时设置了new_task启动模式,进入Activity B后,Activity A会立即回调onActivityResult,而且resultCode是0;从Activity B setResult返回后,不再有onActivityResult的回调!
以上就是Android利用startActivityForResult返回数据到前一个Activity的详细内容,更多关于Android 返回数据到前一个Activity的资料请关注自学编程网其它相关文章!
- 本文固定链接: https://zxbcw.cn/post/204578/
- 转载请注明:必须在正文中标注并保留原文链接
- QQ群: PHP高手阵营官方总群(344148542)
- QQ群: Yii2.0开发(304864863)