之前博文《Android学习笔记之——通过Intent来启动不同的活动》已经介绍了如果通过Intent来启动不同的Activity,本博文介绍一下如何启动活动的同时,传递数据
目录
向下一个活动传递数据
Intent中提供了一系列putExtra() 方法的重载,可以把我们想要传递的数据暂存在Intent中,启动了另一个活动后,只需要把这些数据再从Intent中取出就可以了。
比如说FirstActivity中有一个字符串,现在想把这个字符串传递到SecondActivity中。修改first和scecond文件如下
package com.example.activitytest;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class FirstActivity extends AppCompatActivity {
//重写onCreateOptionsMenu方法,将菜单显示出来
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
//通过getMenuInflater() 方法能够得到MenuInflater 对象
//再调用它的inflate() 方法就可以给当前活动创建菜单了
//inflate() 方法接收两个参数,
//第一个参数用于指定我们通过哪一个资源文件来创建菜单,这里当然传入R.menu.main 。
//第二个参数用于指定我们的菜单项将添加到哪一个Menu 对象当中,这里直接使用onCreateOptionsMenu() 方法中传入的menu 参数。
return true;
//返回true ,表示允许创建的菜单显示出来
//若返回了false ,创建的菜单将无法显示。
}
//重写onOptionsItemSelected方法,定义菜单的相应事件
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){ //通过调用item.getItemId() 来判断我们点击的是哪一个菜单项
case R.id.add_item:
Toast.makeText(FirstActivity.this, "你点了add!",Toast.LENGTH_SHORT).show();
break;
case R.id.remove_item:
Toast.makeText(FirstActivity.this, "你点了remove!",Toast.LENGTH_SHORT).show();
break;
default:
break;
}
return true;
}
////////////////////////////////////////************************************///////
//定义布局
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);//通过文件名字来调用,加载布局
//setContentView方法用于加载布局
//项目中添加的任何资源都会在R文件中生成一个相应的资源id
// 因此,所创建的layout文件会自动将id添加到R文件中
// 只需要调用R.layout.first_layout 就可以得到first_layout.xml 布局的id
///////////**********************///////////////
Button button1=(Button) findViewById(R.id.button_1);
//通过findViewById() 方法获取到在布局文件中定义的元素
//在first_layout文件中,通过android:id="@+id/button_1"定义了按钮
//findViewById() 方法返回的是一个View 对象,我们需要向下转型将它转成Button 对象
button1.setOnClickListener(new View.OnClickListener() {
@Override //表示重写
public void onClick(View v) {
//**************************传递消息
String data = "传输了一条数据哈哈哈";
Intent intent=new Intent(FirstActivity.this, SecondActivity.class);//采用显式启动
intent.putExtra("extra_data", data);//传递了data这个字符串。第一个参数是键,第二参数是值
startActivity(intent);//启动活动
///////////////////////*****************启动其他活动
// Intent intent=new Intent(Intent.ACTION_VIEW);//首先指定了Intent的action 是Intent.ACTION_VIEW(android内部动作)
// //构建出intent的“意图”
// intent.setData(Uri.parse("http://www.baidu.com"));
// //通过Uri.parse() 方法,将一个网址字符串解析成一个Uri对象,
// //再调用Intent的setData() 方法将这个Uri 对象传递进去
// //setData()接收一个Uri 对象,主要用于指定当前Intent正在操作的数据,
// // 而这些数据通常都是以字符串的形式传入到Uri.parse() 方法中解析产生的
//
// //电话
// Intent intent=new Intent(Intent.ACTION_DIAL);//Intent的action 是Intent.ACTION_DIAL
// intent.setData(Uri.parse("tel:10086"));
//
// startActivity(intent);//启动活动
}
});
// button1.setOnClickListener(new View.OnClickListener() {
// @Override //表示重写
// public void onClick(View v) {
// Intent intent=new Intent("com.example.ActivityTest.ACTION_START");
// //构建出intent的“意图”
// intent.addCategory("com.example.ActivityTest.MY_CATEGORY");
// //调用Intent中的addCategory() 方法来添加一个category
//
// startActivity(intent);//启动活动
// }
// });
// button1.setOnClickListener(new View.OnClickListener() {
// @Override //表示重写
// public void onClick(View v) {
// Intent intent=new Intent(FirstActivity.this, SecondActivity.class);
// //构建出intent的“意图”
// startActivity(intent);//启动活动
// }
// });
// button1.setOnClickListener(new View.OnClickListener() {
// //通过调用setOnClickListener() 方法为按钮注册一个监听器
// //点击按钮时就会执行监听器中的onClick() 方法。
// @Override //表示重写
// public void onClick(View v) {
// Toast.makeText(FirstActivity.this, "臭鱼!",Toast.LENGTH_SHORT).show();
// //通过静态方法makeText() 创建出一个Toast对象
// //并通过show()将Toast显示出来
//
// // makeText() 方法需要传入3个参数。
// // 第一个参数是Context ,也就是Toast要求的上下文,由于活动本身就是一个Context 对象,因此这里直接传入FirstActivity.this 即可。
// // 第二个参数是Toast显示的文本内容,
// // 第三个参数是Toast显示的时长,有两个内置常量可以选择Toast.LENGTH_SHORT 和Toast.LENGTH_LONG
//
// }
// });
}
}
package com.example.activitytest;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_layout);
Intent intent = getIntent();//getIntent() 方法获取到用于启动SecondActivity的Intent
String data = intent.getStringExtra("extra_data");//调用getStringExtra() 方法,传入相应的键值,就可以得到传递的数据了
//是整型数据,则使用getIntExtra() 方法
// 如果传递的是布尔型数据,则使用getBooleanExtra()方法,
Log.d("SecondActivity", data);
}
}
通过log.d来显示
返回数据给上一个活动
既然可以传递数据给下一个活动,那么也可以返回数据给上一个活动呢
不过不同的是,返回上一个活动只需要按一下Back键就可以了,并没有一个用于启动活动的Intent来传递数据
通过按键button2来返回数据
使用了startActivityForResult() 方法来启动SecondActivity,请求码只要是一个唯一值就可以了,这里传入了1。
package com.example.activitytest;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class FirstActivity extends AppCompatActivity {
//重写onCreateOptionsMenu方法,将菜单显示出来
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
//通过getMenuInflater() 方法能够得到MenuInflater 对象
//再调用它的inflate() 方法就可以给当前活动创建菜单了
//inflate() 方法接收两个参数,
//第一个参数用于指定我们通过哪一个资源文件来创建菜单,这里当然传入R.menu.main 。
//第二个参数用于指定我们的菜单项将添加到哪一个Menu 对象当中,这里直接使用onCreateOptionsMenu() 方法中传入的menu 参数。
return true;
//返回true ,表示允许创建的菜单显示出来
//若返回了false ,创建的菜单将无法显示。
}
//重写onOptionsItemSelected方法,定义菜单的相应事件
@Override
public boolean onOptionsItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()){ //通过调用item.getItemId() 来判断我们点击的是哪一个菜单项
case R.id.add_item:
Toast.makeText(FirstActivity.this, "你点了add!",Toast.LENGTH_SHORT).show();
break;
case R.id.remove_item:
Toast.makeText(FirstActivity.this, "你点了remove!",Toast.LENGTH_SHORT).show();
break;
default:
break;
}
return true;
}
////////////////////////////////////////************************************///////
//在seconactivity被销毁后,回调上一个活动的onActivityResult()方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//三个参数
//1、requestCode ,即我们在启动活动时传入的请求码。
//2、resultCode ,即我们在返回数据时传入的处理结果
//3、data ,即携带着返回数据的Intent
switch (requestCode) {
//由于在一个活动中有可能调用startActivityForResult() 方法去启动很多不同的活动
// 每一个活动返回的数据都会回调到onActivityResult() 这个方法中
//因此先通过 requestCode来检测数据的来源
case 1:
if (resultCode == RESULT_OK) {//resultCode判断处理结果是否成功
String returnedData = data.getStringExtra("data_return");//从data中取值
Log.d("FirstActivity", returnedData);
}
break;
default:
}
}
//定义布局
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.first_layout);//通过文件名字来调用,加载布局
//setContentView方法用于加载布局
//项目中添加的任何资源都会在R文件中生成一个相应的资源id
// 因此,所创建的layout文件会自动将id添加到R文件中
// 只需要调用R.layout.first_layout 就可以得到first_layout.xml 布局的id
///////////**********************///////////////
Button button1=(Button) findViewById(R.id.button_1);
//通过findViewById() 方法获取到在布局文件中定义的元素
//在first_layout文件中,通过android:id="@+id/button_1"定义了按钮
//findViewById() 方法返回的是一个View 对象,我们需要向下转型将它转成Button 对象
button1.setOnClickListener(new View.OnClickListener() {
@Override //表示重写
public void onClick(View v) {
//**************************传递消息
String data = "传输了一条数据哈哈哈";
Intent intent=new Intent(FirstActivity.this, SecondActivity.class);//采用显式启动
intent.putExtra("extra_data", data);//传递了data这个字符串。第一个参数是键,第二参数是值
// startActivity(intent);//启动活动
startActivityForResult(intent,1);//方法接收两个参数,第一个参数还是Intent,
// 第二个参数是请求码,用于在之后的回调中判断数据的来源。
///////////////////////*****************启动其他活动
// Intent intent=new Intent(Intent.ACTION_VIEW);//首先指定了Intent的action 是Intent.ACTION_VIEW(android内部动作)
// //构建出intent的“意图”
// intent.setData(Uri.parse("http://www.baidu.com"));
// //通过Uri.parse() 方法,将一个网址字符串解析成一个Uri对象,
// //再调用Intent的setData() 方法将这个Uri 对象传递进去
// //setData()接收一个Uri 对象,主要用于指定当前Intent正在操作的数据,
// // 而这些数据通常都是以字符串的形式传入到Uri.parse() 方法中解析产生的
//
// //电话
// Intent intent=new Intent(Intent.ACTION_DIAL);//Intent的action 是Intent.ACTION_DIAL
// intent.setData(Uri.parse("tel:10086"));
//
// startActivity(intent);//启动活动
}
});
// button1.setOnClickListener(new View.OnClickListener() {
// @Override //表示重写
// public void onClick(View v) {
// Intent intent=new Intent("com.example.ActivityTest.ACTION_START");
// //构建出intent的“意图”
// intent.addCategory("com.example.ActivityTest.MY_CATEGORY");
// //调用Intent中的addCategory() 方法来添加一个category
//
// startActivity(intent);//启动活动
// }
// });
// button1.setOnClickListener(new View.OnClickListener() {
// @Override //表示重写
// public void onClick(View v) {
// Intent intent=new Intent(FirstActivity.this, SecondActivity.class);
// //构建出intent的“意图”
// startActivity(intent);//启动活动
// }
// });
// button1.setOnClickListener(new View.OnClickListener() {
// //通过调用setOnClickListener() 方法为按钮注册一个监听器
// //点击按钮时就会执行监听器中的onClick() 方法。
// @Override //表示重写
// public void onClick(View v) {
// Toast.makeText(FirstActivity.this, "臭鱼!",Toast.LENGTH_SHORT).show();
// //通过静态方法makeText() 创建出一个Toast对象
// //并通过show()将Toast显示出来
//
// // makeText() 方法需要传入3个参数。
// // 第一个参数是Context ,也就是Toast要求的上下文,由于活动本身就是一个Context 对象,因此这里直接传入FirstActivity.this 即可。
// // 第二个参数是Toast显示的文本内容,
// // 第三个参数是Toast显示的时长,有两个内置常量可以选择Toast.LENGTH_SHORT 和Toast.LENGTH_LONG
//
// }
// });
}
}
而对于secondactivity,给按钮注册点击事件,并在点击事件中添加返回数据的逻辑。
package com.example.activitytest;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_layout);
Intent intent = getIntent();//getIntent() 方法获取到用于启动SecondActivity的Intent
String data = intent.getStringExtra("extra_data");//调用getStringExtra() 方法,传入相应的键值,就可以得到传递的数据了
//是整型数据,则使用getIntExtra() 方法
// 如果传递的是布尔型数据,则使用getBooleanExtra()方法,
Log.d("SecondActivity", data);
//按钮点击操作
Button button2=(Button) findViewById(R.id.button_2);//定义按钮2
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent2= new Intent();//构建一个intent用于传递数据
intent2.putExtra("data_return","Hello, I am second activity!");//把要传的数据防御intent中
setResult(RESULT_OK,intent2);//专门用于向上一个活动返回数据的
finish();//销毁当前活动
}
});
}
}
结果如下所示
通过back来返回数据
通过在SecondActivity中重写onBackPressed() 方法来解决这个问题。如下所示
package com.example.activitytest;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_layout);
Intent intent = getIntent();//getIntent() 方法获取到用于启动SecondActivity的Intent
String data = intent.getStringExtra("extra_data");//调用getStringExtra() 方法,传入相应的键值,就可以得到传递的数据了
//是整型数据,则使用getIntExtra() 方法
// 如果传递的是布尔型数据,则使用getBooleanExtra()方法,
Log.d("SecondActivity", data);
//按钮点击操作
Button button2=(Button) findViewById(R.id.button_2);//定义按钮2
button2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent2= new Intent();//构建一个intent用于传递数据
intent2.putExtra("data_return","Hello, I am second activity!");//把要传的数据防御intent中
setResult(RESULT_OK,intent2);//专门用于向上一个活动返回数据的
finish();//销毁当前活动
}
});
}
//通过back按键来返回数据
@Override
public void onBackPressed() {
Intent intent2= new Intent();//构建一个intent用于传递数据
intent2.putExtra("data_return","Hello, I am second activity!");//把要传的数据防御intent中
setResult(RESULT_OK,intent2);//专门用于向上一个活动返回数据的
finish();//销毁当前活动
}
}
通过按back键也可以实现上面的操作了~