跳到主要内容

Android学习笔记之传递数据

· 阅读需 9 分钟
Skyone

在 Android 开发中,可以使用 Intent 来在两个 Activity 之间传递数据。通过在 Intent 中添加键值对,然后在下一个 Activity 中使用 getIntent() 方法获取 Intent 对象,再使用 getXXXExtra() 方法获取数据。可以使用 putExtra() 传值,使用 getXXXExtra() 取值。

让然其他办法也很多:全局变量啦、单例啦、依赖注入感觉更好用,但不在本文讨论范围内。

Intent

Intent 类封装了下面6种信息:

  1. 组件名称(ComponentName
  2. 动作(Action
  3. 种类(Category
  4. 数据(Data
  5. 附件信息(Extra
  6. 标志(Flag

Data 可以传递数据,但涉及到 Intent 的筛选机制比较复杂(还没学到),这里,我使用 Extra 传递数据。

让我们声明一个 Intent 并写入数据:

Intent intent = new Intent(this, GetMessage.class);	// GetMessage.class 表示数据接收者
intent.putExtra("key", value); // 键值对,key是字符串,value是任意Java内置数据类型

设置上下文

上面的代码第一行用于设置上下文( context )。第一个参数引用自身,用 this ;第二个参数引用目标类 (数据接收者),注意,是对类的引用,不是对象。

你可以这样设置上下文:

  • 方法一
Intent intent = new Intent(this, GetMessage.class);
  • 方法二
Intent intent = new Intent();
intent.setClass(this, GetMessage.class);
  • 方法三
Intent intent = new Intent();
intent.setClassName(this, "host.skyone.intent.GetMessage");
  • 方法四
Intent intent = new Intent();
intent.setClassName("host.skyone.intent.MainActivity", "host.skyone.intent.GetMessage");

设置数据

设置数据使用 intent.putExtra(String key, value) 方法,value 可以说任意 Java内置数据类型及其数组

intent.putExtra("name", "skyone");
intent.putExtra("age", 19);

当然,你也可以使用 intent.putExtras(Bundle data) 方法并传入 Bundle 对象设置数据。

Bundle bundle = new Bundle();
bundle.putString("name", "skyone");
bundle.putInt("age", 19);
intent.putExtras(bundle);

传出数据

想要打开一个 activity 并写入数据,只需要调用:

satrtActivity(intent);

是不是很简单?

接收数据

从打开的新 activity 中接收数据:

Intent intent = getIntent();
String name = intent.getStringExtra("name"); // name = "skyone"
int age = intent.getIntExtra("age"); // age = 19

当然,使用 bundle 也是可以滴:

Intent intent = getIntent();
Bundle bundle = intent.getExtras();
String name = bundle.getString("name"); // name = "skyone"
int age = bundle.getInt("age"); // name = 19

返回数据

从子Activity中返回数据,可以在子Activity中声明一个 Intent ,并传给 setResult(int resultCode, Intent intent)

例如,在 ReturnMessage 中返回数据到 MainActivity 。在 ReturnMessage.java 中:

Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("message", "Hello world!");
setResult(52021, intent);
finish();

MainActivity 中调用 ReturnMessage

startActivityForResult(new Intent(this, ReturnMessage.class), 2021); // 2021 是RequestCode

MainActivity 中接收数据通过重写 onActivityResult(int requestCode, int resultCode, Intent data) 实现,而 requestCoderesultCode 则用于判断是谁返回的数据

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 2021 && resultCode == 52021) {
Toast.makeText(this,
"接收到消息:" + data.getStringExtra("message"),
Toast.LENGTH_LONG).show();
}
}

使用 Bundle

还可以使用 Bundle 来在两个 Activity 之间传递数据。 在第一个 Activity 中,使用 Bundle 传递数据:

Intent intent = new Intent(this, SecondActivity.class);
Bundle bundle = new Bundle();
bundle.putString("name", "John");
bundle.putInt("age", 25);
intent.putExtra("user", bundle);
startActivity(intent);

在第二个 Activity 中,获取传递过来的数据:

Bundle bundle = getIntent().getBundleExtra("user");
String name = bundle.getString("name");
int age = bundle.getInt("age");

示例

传出数据

创建一个 Empty Activity ,包名我取名为 host.skyone.intent

先画一个简单的页面,用到了两个按钮 Button ,一个输入框 EditText ,一个label TextView

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

<TextView
android:id="@+id/tips2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:text="@string/TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<EditText
android:id="@+id/edit_msg"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:autofillHints=""
android:hint="@string/hint"
android:inputType="text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/tips2"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/send_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onSendMessage"
android:text="@string/send_message"
app:layout_constraintBottom_toTopOf="@+id/button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/edit_msg" />

<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/return_test"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/edit_msg" />

</androidx.constraintlayout.widget.ConstraintLayout>

再看 MainActivity.javaonCreate 方法保存原样就好:

onCreate

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

新建一个按钮事件,用来读取文本框的值并传递给子Activity

onSendMessage

public void onSendMessage(View view) {
String message = ((EditText) findViewById(R.id.edit_msg)).getText().toString();
Intent intent = new Intent(this, GetMessage.class);
intent.putExtra("message", message);
startActivity(intent);
}

这里我们用需要创建新Empty Activity: GetMessage

好,MainActivity.java完成了,来到 GetMessage 。首先,依然先画个简单的界面:

activity_get_message.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".GetMessage">

<TextView
android:id="@+id/tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tips"
app:layout_constraintBottom_toTopOf="@+id/showMessage"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/showMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

GetMessage.java 部分也没什么好说的,就是读取数据嘛,在第一节已经讲过了

GetMessage.java

package host.skyone.intent;

import androidx.appcompat.app.AppCompatActivity;

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

public class GetMessage extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_get_message);
Intent intent = getIntent();
String message = intent.getStringExtra("message");
((TextView)findViewById(R.id.showMessage)).setText(message); // 找到View并显示数据
}
}

再次提醒, Strings.xml 在最下面

返回数据

创建新Empty Activity: ReturnMessage

MainActivity 中加入onReturnMessageTest

public void onReturnMessageTest(View view) {
startActivityForResult(new Intent(this, ReturnMessage.class), 2021);
}

记得在 activity_main.xml 中第二个按钮中加入 android:onClick="onReturnMessage"

然后开始写 ReturnMessage ,同样,界面如下:

activity_return_message.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ReturnMessage">

<EditText
android:id="@+id/edit_query"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:autofillHints="Hello world!"
android:hint="@string/hint"
android:inputType="text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textView"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/return_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onReturnMessage"
android:text="@string/return_message"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/edit_query" />

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:text="@string/TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

按钮的事件函数如下:

public void onReturnMessage(View view) {
String message = ((EditText)findViewById(R.id.edit_query)).getText().toString();
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("message", message);
setResult(52021, intent);
finish();
}

OK,快编译安装试试吧~~~

例图

MainActivity
GetMessage
ReturnMessage
ReturnTest

代码

MainActivity.java

package host.skyone.intent;

import androidx.appcompat.app.AppCompatActivity;

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

public class MainActivity extends AppCompatActivity {

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

public void onSendMessage(View view) {
String message = ((EditText) findViewById(R.id.edit_msg)).getText().toString();
Intent intent = new Intent(this, GetMessage.class);
intent.putExtra("message", message);
startActivity(intent);
}

public void onReturnMessageTest(View view) {
startActivityForResult(new Intent(this, ReturnMessage.class), 2021);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 2021 && resultCode == 52021) {
Toast.makeText(this, "接收到消息:" + data.getStringExtra("message"), Toast.LENGTH_LONG).show();
}
}
}

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

<TextView
android:id="@+id/tips2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:text="@string/TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<EditText
android:id="@+id/edit_msg"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:autofillHints=""
android:hint="@string/hint"
android:inputType="text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/tips2"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/send_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onSendMessage"
android:text="@string/send_message"
app:layout_constraintBottom_toTopOf="@+id/button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/edit_msg" />

<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onReturnMessageTest"
android:text="@string/return_test"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/edit_msg" />

</androidx.constraintlayout.widget.ConstraintLayout>

GetMessage.java

package host.skyone.intent;

import androidx.appcompat.app.AppCompatActivity;

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

public class GetMessage extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_get_message);
Intent intent = getIntent();
String message = intent.getStringExtra("message");
((TextView)findViewById(R.id.showMessage)).setText(message);
}
}

activity_get_message.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".GetMessage">

<TextView
android:id="@+id/tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/tips"
app:layout_constraintBottom_toTopOf="@+id/showMessage"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/showMessage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=""
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

ReturnMessage.java

package host.skyone.intent;

import androidx.appcompat.app.AppCompatActivity;

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

public class ReturnMessage extends AppCompatActivity {

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

public void onReturnMessage(View view) {
String message = ((EditText)findViewById(R.id.edit_query)).getText().toString();
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra("message", message);
setResult(52021, intent);
finish();
}
}

activity_return_message.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:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ReturnMessage">

<EditText
android:id="@+id/edit_query"
android:layout_width="200dp"
android:layout_height="wrap_content"
android:autofillHints="Hello world!"
android:hint="@string/hint"
android:inputType="text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textView"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/return_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onReturnMessage"
android:text="@string/return_message"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/edit_query" />

<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="40dp"
android:text="@string/TextView"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="host.skyone.intent">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Intent">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".GetMessage"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
<activity
android:name=".ReturnMessage"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
</application>

</manifest>

strings.xml

<resources>
<string name="app_name">intent</string>
<string name="TextView">输入一些东西</string>
<string name="return_message">返回消息</string>
<string name="return_test">测试返回消息</string>
<string name="send_message">发送消息</string>
<string name="hint">message</string>
<string name="tips">接收到了以下信息:</string>
</resources>