Intent是一种消息传递机制,可以在同个应用程序内使用,也可以在不同应用程序间使用。其功能可用于:
1. 启动一个特定的Service或Activity。
2. 启动Activity或Service来执行特定动作。
3. 广播某个事件的发生。
Intent显式启动Activity
显式Intent:即通过指定具体的组件类,通知应用启动对应组件。
1、直接设定要启动的Activity:
private void startNextAct(){
Intent intent=new Intent();
intent.setClass(this, NextActivity.class);
startActivity(intent);
}
2、通过intent-filter来设定Intent的Action:
在Manifest里如下设置NextActivity:
<activity android:name=".NextActivity">
<intent-filter>
<action android:name="showNextActivity"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
在原Activity中使用Intent打开NextActivity:
private void startNextAct(){
Intent intent=new Intent();
intent.setAction("showNextActivity");
startActivity(intent);
}
Intent传递数据
原Activity传递数据代码如下:
private void startNextAct(){
Intent intent=new Intent();
intent.setClass(this, NextActivity.class);
// 绑定数据
intent.putExtra("name", myName);
intent.putExtra("age", myAge);
/* 也可使用Bundle传送数据
* Bundle data=new Bundle();
* data.putString("name", myName);
* data.putInt("age", myAge);
* intent.putExtras(data);*/
startActivity(intent);
}
NextActivity中接收数据:
private void getValue(){
Intent intent = getIntent();
// 接受数据
String name=intent.getStringExtra("name");
int age=intent.getIntExtra("age", 0);
/* intent.getIntExtra(name, defaultValue)
* 第一个参数为int的key值,第二个参数为未接收到值时的默认值*/
/* 使用Bundle
* Bundle bundle=intent.getExtras();
* name=bundle.getString("name");
* age=bundle.getInt("age");*/
}
从Activity返回结果
从原Activity调用startActivityForResult()方法启动NextActivity,和之前的显式启动一个Activity差不多,多了一个整形的标识值:
//声明一个请求码,用于唯一标识返回了结果的NextActitivy
private static final int myRequestCode=1;
private void startForResult(){
Intent intent=new Intent();
intent.setClass(this, NextActivity.class);
startActivityForResult(intent, myRequestCode);
}
在NextActivity中返回数据:
//声明要返回的值
String myData="thisForResult";
private void mySetResult(){
Intent intent=new Intent();
intent.putExtra("myData", myData);
/*setResult(int resultCode, data);
* 第一个参数为任意整数,做标识,第二个参数为要返回的数据*/
setResult(Activity.RESULT_OK, intent);
}
回到原Activity中,覆写onActivityResult()方法,获得返回的数据:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch(requestCode){
case myRequestCode:
if(resultCode==Activity.RESULT_OK){
String myData=data.getStringExtra("myData");
//下面开始处理数据***
}
}
}
Intent传递对象
前面介绍了使用Intent传递基本类型的值,其实Intent还可以直接传递对象。Android通过实现两种接口都可以传递对象。
1、实现Serializable接口传递对象
Serializable的作用是将对象数据存入字节流中,在需要时重新生成对象,实现该接口的作用是给对象做好标记,系统会自动对其序列化。
先创建一个User类实现Serializable接口,以便实例化要传递的对象,单独创建User类,不要写成原Activity的内部类,User.java代码如下:
package com.example.test007;
import java.io.Serializable;
public class User implements Serializable{
private String userName;
private String passWord;
public User(String userName,String passWord){
this.userName=userName;
this.passWord=passWord;
}
public void setName(String name){
this.userName=name;
}
public String getName(){
return this.userName;
}
public void setWord(String word){
this.passWord=word;
}
public String getWord(){
return this.passWord;
}
}
然后在原Activity里创建Intent传递User实现的一个对象:
public void sendObject(){
User user=new User("admin","123456");
Intent intent=new Intent();
Bundle bundle=new Bundle();
bundle.putSerializable("myUser", user);
intent.setClass(this, NextActivity.class);
intent.putExtras(bundle);
startActivity(intent);
}
在NextActivity里接收传递的对象,流程跟传递基本类型差不多:
public void getObject(){
User user=(User)getIntent().getSerializableExtra("myUser");
String name=user.getName();
String word=user.getWord();
//下面开始处理对象数据***
}
2、实现Parcelable接口传递对象
Parcelable类同样可以完成序列化,Serializable是JavaSE本身支持的,Parcelable接口由Android特别提供。两者的选择原则如下:
在使用内存时,Parcelable比Serializable效率要高。
Serializable在序列化时会产生大量的临时变量,引起频繁的GC。
Parcelable不能使用在要将数据写到存储盘的情况,在外界有变化时,Parcelable不能很好的保证数据的持续性,建议使用Serializable。
而相比较于Serializable,Parcelable的使用要稍微复杂一些:
1、类User要实现Parcelable接口。
2、覆写describeContents()方法,该方法为内容接口描述,默认返回0就可以。
3、覆写writeToParcel()方法,该方法用于把要传递的对象数据打包成Parcel,使其可以序列化传输。
4、实例化静态内部对象 CREATOR,使其实现Parcelable.Creator接口。该对象名大小写不可更改。
5、覆写createFromParcel()方法,从Parcel中取回要传递的数据。(需要创建输入为Parcel的构造函数)User.java代码如下:
package com.example.test007;
import android.os.Parcel;
import android.os.Parcelable;
public class User implements Parcelable{
private String userName;
private String passWord;
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(userName);
dest.writeString(passWord);
}
public static final Parcelable.Creator<User> CREATOR=new Parcelable.Creator<User>() {
@Override
public User createFromParcel(Parcel source) {
return new User(source);
}
@Override
public User[] newArray(int size) {
return new User[size];
}
};
public User(String name,String word){
this.userName=name;
this.passWord=word;
}
public User(Parcel source) {
userName=source.readString();
passWord=source.readString();
}
public void setName(String name){
this.userName=name;
}
public String getName(){
return this.userName;
}
public void setWord(String word){
this.passWord=word;
}
public String getWord(){
return this.passWord;
}
}
在原Activity中传递对象,与Serializable类似:
public void sendObject(){
User user=new User("admin","123456");
Intent intent=new Intent();
Bundle bundle=new Bundle();
bundle.putParcelable("myUser", user);
intent.setClass(this, NextActivity.class);
intent.putExtras(bundle);
startActivity(intent);
}
在NextActivity中接收对象:
public void getObject(){
User user=(User)getIntent().getParcelableExtra("myUser");
String name=user.getName();
String word=user.getWord();
nameView.setText(name);
ageView.setText(word);
}