0%

Activity之间通讯

Activity之间通讯

Activity之间经常需要传输数据,我们常用的方法就是使用Intent

实例一单方面传输

创建项目TwoActivity,然后在项目中除MainActivity之外,再添加一个SecondActivity

activity_main.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
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="please input something"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="send to secondActivity"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/editText" />

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity中写下以下内容

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
package com.example.twoactivity;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends AppCompatActivity {
private EditText mEditText;

private Button mButton;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEditText = findViewById(R.id.editText);
mButton = findViewById(R.id.button);
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String str = mEditText.getText().toString();
//启动另一个Activity
Intent intent = new Intent(MainActivity.this, SecondAcrivity.class);
intent.putExtra("information", str);
startActivity(intent);
}
});
}
}

activity_second.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
<?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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:hint="please input something"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="send to secondActivity"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/editText" />

</androidx.constraintlayout.widget.ConstraintLayout>

SecondActivity写下以下内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.example.twoactivity;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class SecondAcrivity extends AppCompatActivity {
private TextView mTextView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
mTextView = findViewById(R.id.textView);
Intent intent = getIntent();
String information = intent.getStringExtra("information");
mTextView.setText(information);
}
}

运行程序,再输入框输入test,然后按下按钮

image-20210820175350586

可以看到在的SecondActivity上展示了我们输入的内容

image-20210820175557003

可以看到需要传输的内容从MainActivity传输到了SecondActivity

实例二双方互相传输

有的时候我们需要把信息从MainActivity传输到SecondActivity,这种类似于父子Activity之间的传输,原本是使用startActivityForResult进行处理,但是由于startActivityForResult存在的问题,现在官方推荐的是使用registerForActivityResult()Activity Results API相关的方法

👉官方文档:https://developer.android.com/training/basics/intents/result

更改MainActivity中代码

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
package com.example.twoactivity;

import androidx.activity.result.ActivityResultCallback;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContract;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
private EditText mEditText;

private Button mButton;
//制定协议
private ActivityResultContract<String, String> mStringStringActivityResultContract = new ActivityResultContract<String, String>() {
@NonNull
@Override
public Intent createIntent(@NonNull Context context, String input) {
Intent intent = new Intent(MainActivity.this, SecondAcrivity.class);
intent.putExtra("information", input);
return intent;
}

@Override
public String parseResult(int resultCode, @Nullable Intent intent) {
if (resultCode != Activity.RESULT_OK || intent == null) {
return null;
}
return intent.getStringExtra("second information");
}
};
//制定启动器
private ActivityResultLauncher mActivityResultLauncher = registerForActivityResult(mStringStringActivityResultContract,
new ActivityResultCallback<String>() {
@Override
public void onActivityResult(String result) {
Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show();
}
});

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mEditText = findViewById(R.id.editText);
mButton = findViewById(R.id.button);

mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String str = mEditText.getText().toString();
mActivityResultLauncher.launch(str);
}
});
}
}

ActivityResultContractActivityResultLauncherActivity Results API中两个重要的组件

  • ActivityResultContract: 协议,它定义了如何传递数据和如何处理返回的数据。ActivityResultContract是一个抽象类,你需要继承它来创建自己的协议,每个 ActivityResultContract 都需要定义输入和输出类,如果您不需要任何输入,可使用 Void(在 Kotlin 中,使用 Void? 或 Unit)作为输入类型。
  • ActivityResultLauncher: 启动器,调用ActivityResultLauncherlaunch方法来启动页面跳转,作用相当于原来的startActivity()

SecondAcrivity写入以下内容

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
package com.example.twoactivity;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class SecondAcrivity extends AppCompatActivity {
private TextView mTextView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
mTextView = findViewById(R.id.textView);
Intent intent = getIntent();
String information = intent.getStringExtra("information");
mTextView.setText(information);
Intent data = new Intent();
data.putExtra("second information", "返回了secondActivity的信息");
//设置返回结果
setResult(Activity.RESULT_OK, data);
}
}

实现子activity发送返回信息给父activity,有以下两种方法可用:

public final void setResult(int resultCode)

public final void setResult(int resultCode, Intent data)

一般来说,参数resultCode可以是以下任意一个预定义常量。

  • Activity.RESULT_OK
  • Activity.RESULT_CANCELED

当然如需自己定义结果代码,还可使用另一个常量:RESULT_FIRST_USER

在父activity需要依据子activity的完成结果采取不同操作时,设置结果代码就非常有用。 例如,假设子activity有一个OK按钮和一个Cancel按钮,并且每个按钮的单击动作分别设置 有不同的结果代码。那么,根据不同的结果代码,父activity就能采取不同的操作。 子activity可以不调用setResult(...)方法。如果不需要区分附加在intent上的结果或其他信 息,可让操作系统发送默认的结果代码。如果子activity是以调用startActivityForResult(...)或者ActivityResultLauncher方法启动的,结果代码则总是会返回给父activity。在没有调用setResult(...)方法的情况下, 如果用户按了后退按钮,父activity则会收到Activity.RESULT_CANCELED的结果代码。

最终结果展示,发送信息之后按返回键,会出结果展示

image-20210820215024582

总结

写了两个有关Android之间Activity的信息相互传输

参考: