05-Android中在activity销毁后将数据传递给上一个活动

899 阅读4分钟

使用的工具

现在android项目使用的 android studio 来进行开发,开发的语言现在推荐的是 kotlin, 不过这里还是先使用 Java 来开发

  • AndroidStudio 版本: Android Studio Iguana | 2023.2.1

  • 项目语言: Java

  • JDK版本: 17

    整体demon代码地址

前置文章

使用Intent进行数据传递

在 [[04-Android中的Intent]] 这篇文章中也讲解了在跳转到新的 activity 的时候如何通过 Intent 进行数据传递,其实在当前的 activity 销毁的时候也可以通过 Intent 进行数据的返回,接下来的示例就是完成这个功能

代码结构

现在还是两个 activity 文件 和两个布局文件,代码分别如下

public class MainActivity extends AppCompatActivity {  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        Log.d("MainActivity", "开始创建主Activity");  
        super.onCreate(savedInstanceState);  
        //EdgeToEdge.enable(this);  
        setContentView(R.layout.activity_main);  
        // 通过 findViewById 方法获取 Button 实例  
        Button button = (Button)findViewById(R.id.cus_button);  
        // 给 button 设置点击监听器  
        button.setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                //Intent intent = new Intent(MainActivity.this, SecondActivity.class);  
                Intent intent = new Intent("com.example.ademo.MainActivity.MAIN_ACTION");  
                intent.addCategory("com.example.ademo.MainActivity.CATEGORY_ONE");  
                intent.putExtra("main_key_str", "main_value1");  
                intent.putExtra("main_key_int", 1);  
                startActivity(intent);  
            }  
        });  
    }  
}


public class SecondActivity extends AppCompatActivity {  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_second);  
        Intent intent = getIntent();  
        String mainKeyStr = intent.getStringExtra("main_key_str");  
        int mainKeyInt = intent.getIntExtra("main_key_int", 0);  
        Log.d("SecondActivity", mainKeyStr);  
        Log.d("SecondActivity", mainKeyInt + "");  
    }  
}

activity_main.xml 文件

<?xml version="1.0" encoding="utf-8"?>  
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:app="http://schemas.android.com/apk/res-auto"  
    xmlns:tools="http://schemas.android.com/tools"  
    android:id="@+id/main"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent"  
    tools:context=".MainActivity">  
  
    <Button  
        android:id="@+id/cus_button"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="MainActivityButton"  
        tools:ignore="MissingConstraints"></Button>  
    <TextView  
        android:layout_width="wrap_content"  
        android:layout_height="wrap_content"  
        android:text="Hello World test!"  
        app:layout_constraintBottom_toBottomOf="parent"  
        app:layout_constraintEnd_toEndOf="parent"  
        app:layout_constraintStart_toStartOf="parent"  
        app:layout_constraintTop_toTopOf="parent" />  
  
</androidx.constraintlayout.widget.ConstraintLayout>

activity_second.xml 文件内容

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"  
    android:layout_width="match_parent"  
    android:layout_height="match_parent">  
  
    <!--  
        android:id="@+id/button_1" 表示给该控件添加了一个id  
        layout_width=match_parent 表示该button控件的宽度和父组件一致  
        layout_height=wrap_content 表示该button控件的高度是按照实际内容来的  
        android:text="ButtonOne" 是button中显示的内容  
    -->  
    <Button  
        android:id="@+id/second_activity_button_1"  
        android:layout_width="match_parent"  
        android:layout_height="wrap_content"  
        android:text="SecondActivityButtonOne"/>  
</LinearLayout>

AndroidManifest.xml 文件内容

<?xml version="1.0" encoding="utf-8"?>  
<manifest xmlns:android="http://schemas.android.com/apk/res/android"  
    xmlns:tools="http://schemas.android.com/tools">  
  
    <application  
        android:allowBackup="true"  
        android:dataExtractionRules="@xml/data_extraction_rules"  
        android:fullBackupContent="@xml/backup_rules"  
        android:icon="@mipmap/ic_launcher"  
        android:label="@string/app_name"  
        android:roundIcon="@mipmap/ic_launcher_round"  
        android:supportsRtl="true"  
        android:theme="@style/Theme.ADemo"  
        tools:targetApi="31">  
        <activity android:name=".SecondActivity"  
            android:exported="true"  
            android:launchMode="standard">  
            <intent-filter>  
                <action android:name="com.example.ademo.MainActivity.MAIN_ACTION"></action>  
                <action android:name="com.example.ademo.MainActivity.MAIN_ACTION2"></action>  
                <!--这里需要注意的是,即使有其他的 category,默认的category还是需要加上-->  
                <category android:name="android.intent.category.DEFAULT"/>  
                <category android:name="com.example.ademo.MainActivity.CATEGORY_ONE"/>  
            </intent-filter>  
        </activity>  
  
        <activity  
            android:name=".MainActivity"  
            android:exported="true">  
            <intent-filter>  
                <action android:name="android.intent.action.MAIN" />  
                <category android:name="android.intent.category.LAUNCHER" />  
            </intent-filter>  
        </activity>  
    </application>  
  
</manifest>

需要完成的功能点

接下来要做的事情就是在上面的代码基础上进行改造,实现当点击 SecondActivity 中的 Button 的时候销毁当前 activity,并且将一些数据传递给 MainActivity, 然后在 MainActivity 中将接收到的数据打印出来

代码实现

这里对涉及到的方法先简述一下

  • 从 MainActivity 跳转到 SecondActivity 时不再是调用 startActivity(Intent) 方法,而是调用 public void startActivityForResult(@NonNull Intent intent, int requestCode) 方法
  • 在 SecondActivity 销毁前将数据通过 public final void setResult(int resultCode, Intent data) 方法来保存结果
  • 在 MainActivity 类中重写 protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) 方法来获取结果 接下来就看看修改后的 MainActivity 类和 SecondActivity 类代码
package com.example.ademo;  
  
import android.content.Intent;  
import android.os.Bundle;  
import android.util.Log;  
import android.view.View;  
import android.widget.Button;  
  
import androidx.activity.EdgeToEdge;  
import androidx.annotation.Nullable;  
import androidx.appcompat.app.AppCompatActivity;  
  
public class MainActivity extends AppCompatActivity {  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        Log.d("MainActivity", "开始创建主Activity");  
        super.onCreate(savedInstanceState);  
        //EdgeToEdge.enable(this);  
        setContentView(R.layout.activity_main);  
        // 通过 findViewById 方法获取 Button 实例  
        Button button = (Button)findViewById(R.id.cus_button);  
        // 给 button 设置点击监听器  
        button.setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                //Intent intent = new Intent(MainActivity.this, SecondActivity.class);  
                Intent intent = new Intent("com.example.ademo.MainActivity.MAIN_ACTION");  
                intent.addCategory("com.example.ademo.MainActivity.CATEGORY_ONE");  
                intent.putExtra("main_key_str", "main_value1");  
                intent.putExtra("main_key_int", 1);  
                //startActivity(intent);  
                startActivityForResult(intent, 2);  
            }  
        });  
    }  
  
    @Override  
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {  
        super.onActivityResult(requestCode, resultCode, data);  
        switch (requestCode) {  
            // 这里的 requestCode 就是调用 startActivityForResult 时传递的 requestCode, 两者保持一致  
            case 2:  
                if (resultCode == RESULT_OK) {  
                    String returnedData = data.getStringExtra("second_back_to_main");  
                    Log.d("MainActivity", returnedData);  
                }  
                break;  
            default:  
        }  
    }  
}
package com.example.ademo;  
  
import android.content.Intent;  
import android.os.Bundle;  
import android.util.Log;  
import android.view.View;  
import android.widget.Button;  
  
import androidx.appcompat.app.AppCompatActivity;  
  
public class SecondActivity extends AppCompatActivity {  
  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_second);  
        Intent intent = getIntent();  
        String mainKeyStr = intent.getStringExtra("main_key_str");  
        int mainKeyInt = intent.getIntExtra("main_key_int", 0);  
        Log.d("SecondActivity", mainKeyStr);  
        Log.d("SecondActivity", mainKeyInt + "");  
  
        // 给 activity_second.xml 中的 button 添加点击事件  
        Button button = findViewById(R.id.second_activity_button_1);  
        button.setOnClickListener(new View.OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                Intent intent1 = new Intent();  
                intent1.putExtra("second_back_to_main", "这个是secondActivity中返回的数据");  
                // setResult 方法就是保存结果数据,第一个参数一般是 RESULT_OK或者RESULT_CANCLED, 第二个参数是 Intent 对象  
                setResult(RESULT_OK, intent1);  
                // finish() 方法的作用就是销毁当前的 activity                finish();  
            }  
        });  
    }  
}

onBackPressed方法

上面代码在 SecondActivity 中是通过点击 Button 手动调用 finish() 方法来销毁当前的 Activity,如果是点击返回按钮的话则需要通过重写 onBackPressed 方法来实现数据的传递,所以在 SecondActivity 中重写 onBackPressed 方法,代码如下所示

public class SecondActivity extends AppCompatActivity {
	@Override  
	public void onBackPressed() {  
	    super.onBackPressed();  
	    Intent intent1 = new Intent();  
	    intent1.putExtra("second_back_to_main", "这个是secondActivity中通过点击返回按钮后返回的数据");  
	    // setResult 方法就是保存结果数据,第一个参数一般是 RESULT_OK或者RESULT_CANCLED, 第二个参数是 Intent 对象  
	    setResult(RESULT_OK, intent1);  
	    // finish() 方法的作用就是销毁当前的 activity    
	    finish();  
	}
}