Use startActivityForResult to return data to the previous Activity (with source code + analysis)

In Android, jumping from one Activity to another Activity, and then back, the previous Activity can save data and state by default. But this time I want to achieve the same goal by using startActivityForResult. Although it seems more complicated, I can explore the principles behind startActivityForResult and precautions for use.

The functions to be realized are as follows:

Transfer data from Activity A to Activity B, and then get the data from Activity B, and then pass it back to Activity A. Add a "Back to the previous page" Button in Activity B. After returning to Activity A, you need to keep the relevant information you entered before. We use startActivityForResult to pull up Activity B. In this way, Activity A will have a wait for Activity B The return.

Specific steps are as follows:

  1. There is a Button in Activity A. After clicking the Button, get the data to be sent to Activity B, encapsulate the data in the Bundle, and then call startActivityForResult to send the data to Activity B

  2. Activity A rewrites the onActivityResult function to determine whether requestCode and resultCode are the expected results. If they are, then get the data from the Bundle and redisplay it in Activity A

  3. Get the Intent object passed by Activity A in Activity B, take out the Bundle object, and then take out the data field from the Bundle and display it on the current page

  4. There is also a Button in Activity B. After clicking the Button, call setResult to return the result and close the current page. Therefore, it seems that the effect is back to Activity A

The source code is as follows:

1. Implementation of Activity A :

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. Layout file main_page_layout.xml:

<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. Implementation of Activity B:

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. The layout of Activity B:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                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>

The code comments are clearly written, so you can use them directly. The renderings are as follows:

image

 

But there are three things to note here:

1. The second parameter requestCode of startActivityForResult is 0, so let's see what the result is if the value passed is less than 0 and greater than 0:

  • Pass a value less than 0, such as -1: equivalent to calling startActivity, onActivityResult will not be called

  • Pass a value greater than 0, such as 1: the effect is equivalent to passing 0, the first parameter of onActivityResult is the requestCode passed by startActivityForResult

2. The second parameter resultCode of onActivityResult: it is returned by the second activity through setResult, and there are two commonly used values: RESULT_CANCELED, RESULT_OK

  • RESULT_CANCELED : Activity B failed to pull up, such as crash

  • RESULT_OK : The return value after the successful operation of Activity B

There is also a less commonly used value: RESULT_FIRST_USER . The Android source code defines this value as "user-defined activity results" (user-defined). I searched it globally in the source code, and it is not used much. Pick one or two places to use:

(1) InstallFailed.java under PackageInstaller (related pages for failed installation of apk)

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) InstallStaging.java under PackageInstaller

private void showError() {
        (new ErrorDialog()).showAllowingStateLoss(getFragmentManager(), "error");
        // ……. 
        setResult(RESULT_FIRST_USER, result);
}

(3) UninstallerActivity.java under PackageInstaller (relevant page for uninstalling apk): There are many settings in the onCreate method as RESULT_FIRST_USER.

Therefore, my understanding is that the business itself is used in some wrong or invalid scenarios and is defined by the business itself .

3. If the new_task startup mode is set when starting Activity B, after entering Activity B, Activity A will immediately call back onActivityResult, and the resultCode is 0; after returning from Activity B setResult, there will be no more onActivityResult callback!

Guess you like

Origin blog.csdn.net/Xia_Leon/article/details/112913535