1. 什么是Intent(意图)
Intent是一种运行时绑定(runtime binding)机制,它能在程序运行的过程中连接两个不同的组件。通过Intent,你的程序可以向Android表达某种请求或者意愿,Android会根据意愿的内容选择适当的组件来请求。
在这些组件之间的通讯中,主要是由Intent协助完成的。 Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。
因此,Intent在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦。
例如,在一个联系人维护的应用中,当我们在一个联系人列表屏幕(假设对应的Activity为listActivity)上,点击某个联系人后,希望能够跳出此联系人的详细信息屏幕(假设对应的Activity为detailActivity)
为了实现这个目的,listActivity需要构造一个 Intent,这个Intent用于告诉系统,我们要做“查看”动作,此动作对应的查看对象是“某联系人”,然后调用startActivity (Intent intent), 将构造的Intent传入,系统会根据此Intent中的描述,到ManiFest中找到满足此Intent要求的Activity,系统会调用找到的 Activity,即为detailActivity,最终传入Intent,detailActivity则会根据此Intent中的描述,执行相应的操作。
2. 在Activity之间传递数据
在我们的实际应用开发中,不同的Activity之间进行切换的时候不可避免的进行数据传递。
下面我们来介绍4种最常用的意图传递方式,这4种方式如下:
1、通过Intent传递数据
2、通过静态变量传递数据
3、通过剪切板传递数据
4、通过全局变量传递数据
3 通过Intent传递数据
可以通过Intent类中的putExtra方法可以将简单的数据类型和序列化对象保存到Intent对象中,然后在目标的Activity中使用getXxx方法取出对应的数据。
使用Intent可以很方便在不同的Activity之间传递数据,这个也是官方推荐的方式,但是也有一定的局限性,就是Intent无法传递不能序列化的对象。我们可以使用静态变量来解决这个问题。
在Activity之间数据传递还可以利用一些技巧,不管是Windows还是Linux操作系统,都会支持一种叫剪切板的技术,也就是某一个程序将一些数据复制到剪切板上,然后其他的任何程序都可以从剪切板中获取数据。
在Activity之间数据传递中还有一种比较实用的方式,就是全局对象,实用J2EE的读者来说都知道Java Web的四个作用域,这四个作用域从小到大分别是Page、Request、Session和Application,其中Application域在应用程序的任何地方都可以使用和访问,除非是Web服务器停止,Android中的全局对象非常类似于Java Web中的Application域,除非是Android应用程序清除内存,否则全局对象将一直可以访问。
7 从Activity中返回数据
在实际的应用中,我们不仅仅要向Activity传递数据,而且要从Activity中返回数据,虽然返回数据和传递数据类似,也可以采用前面4种方法,但是一般建议采用Intent对象的方式来返回数据,使用这种方式返回数据,需要使用startActivityForResult方法来显示Activity。
可以参考这篇文章: startActivityForResult与onActivityResult
Intent是一种运行时绑定(runtime binding)机制,它能在程序运行的过程中连接两个不同的组件。通过Intent,你的程序可以向Android表达某种请求或者意愿,Android会根据意愿的内容选择适当的组件来请求。
在这些组件之间的通讯中,主要是由Intent协助完成的。 Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。
因此,Intent在这里起着一个媒体中介的作用,专门提供组件互相调用的相关信息,实现调用者与被调用者之间的解耦。
例如,在一个联系人维护的应用中,当我们在一个联系人列表屏幕(假设对应的Activity为listActivity)上,点击某个联系人后,希望能够跳出此联系人的详细信息屏幕(假设对应的Activity为detailActivity)
为了实现这个目的,listActivity需要构造一个 Intent,这个Intent用于告诉系统,我们要做“查看”动作,此动作对应的查看对象是“某联系人”,然后调用startActivity (Intent intent), 将构造的Intent传入,系统会根据此Intent中的描述,到ManiFest中找到满足此Intent要求的Activity,系统会调用找到的 Activity,即为detailActivity,最终传入Intent,detailActivity则会根据此Intent中的描述,执行相应的操作。
2. 在Activity之间传递数据
在我们的实际应用开发中,不同的Activity之间进行切换的时候不可避免的进行数据传递。
下面我们来介绍4种最常用的意图传递方式,这4种方式如下:
1、通过Intent传递数据
2、通过静态变量传递数据
3、通过剪切板传递数据
4、通过全局变量传递数据
3 通过Intent传递数据
可以通过Intent类中的putExtra方法可以将简单的数据类型和序列化对象保存到Intent对象中,然后在目标的Activity中使用getXxx方法取出对应的数据。
MainActivity///
Intent intent = new Intent();
intent.putExtra("name", "张三疯");
intent.putExtra("age", 23);
intent.putExtra("address", "无名地");
intent.setClass(Main.this, OtherActivity.class);
startActivity(intent);
OtherActivity///
Intent intent = getIntent();
int age = intent.getIntExtra("age", 0);
String name = intent.getStringExtra("name");
String address = intent.getStringExtra("address");
textView.setText("age--->>" + age + "\n" + "name-->>" + name + "\n" + "address->>" + address);
4、通过静态变量传递数据
使用Intent可以很方便在不同的Activity之间传递数据,这个也是官方推荐的方式,但是也有一定的局限性,就是Intent无法传递不能序列化的对象。我们可以使用静态变量来解决这个问题。
MainActivity///
Intent intent = new Intent();
intent.setClass(Main.this, OtherActivity.class);
OtherActivity.age = 23;
OtherActivity.name = "jack";
startActivity(intent);
OtherActivity///
public class OtherActivity extends Activity {
private TextView textView;
public static String name; //声明静态变量
public static int age;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.other);
textView = (TextView)this.findViewById(R.id.msg);
textView.setText("-name->>"+name+"\n"+"-age-->>"+age);
}
}
5 通过剪切板传递数据
在Activity之间数据传递还可以利用一些技巧,不管是Windows还是Linux操作系统,都会支持一种叫剪切板的技术,也就是某一个程序将一些数据复制到剪切板上,然后其他的任何程序都可以从剪切板中获取数据。
****************************MainActivity**************************///
public void onClick(View v) {
// 声明剪切板
//ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
//String name = "jack";
//clipboardManager.setText(name);
//Intent intent = new Intent(Main.this, OtherActivity.class);
//startActivity(intent);
MyData myData = new MyData("jack", 23);
//将对象转换成字符串
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
String base64String = "";
try {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(myData);
//Base64 是一个编解码的类,下面是将字节数组转换成String
base64String = Base64.encodeToString(byteArrayOutputStream.toByteArray(), Base64.DEFAULT);
objectOutputStream.close();
} catch (Exception e) {
// TODO: handle exception
}
ClipboardManager clipboardManager = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
clipboardManager.setText(base64String);
Intent intent =new Intent(Main.this,OtherActivity.class);
startActivity(intent);
}
****************************otherActivity**************************///
textView = (TextView) this.findViewById(R.id.msg);
//得到剪切板对象
ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
String msgString = clipboardManager.getText().toString();
//将string 转换成 byte[]
byte[] base64_byte = Base64.decode(msgString, Base64.DEFAULT);
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(
base64_byte);
try {
ObjectInputStream objectInputStream = new ObjectInputStream(
byteArrayInputStream);
//返回一个MyData对象,这个对象中就包含了数据
MyData myData = (MyData) objectInputStream.readObject();
textView.setText(myData.toString());
} catch (Exception e) {
// TODO: handle exception
}
****************************MyData**************************///
public class MyData implements Serializable {
private String name;
private int age;
public MyData(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "MyData [name=" + name + ", age=" + age + "]";
}
}
6 通过全局变量传递数据
在Activity之间数据传递中还有一种比较实用的方式,就是全局对象,实用J2EE的读者来说都知道Java Web的四个作用域,这四个作用域从小到大分别是Page、Request、Session和Application,其中Application域在应用程序的任何地方都可以使用和访问,除非是Web服务器停止,Android中的全局对象非常类似于Java Web中的Application域,除非是Android应用程序清除内存,否则全局对象将一直可以访问。
****************************MainActivity**************************///
public class Main extends Activity {
private Button button;
private MyApp myApp;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button = (Button)this.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
myApp = (MyApp)getApplication();
myApp.setName("jack");//��֮������
Intent intent = new Intent(Main.this,OtherActivity.class);
startActivity(intent);
}
});
}
}
//****************************otherActivity**************************
private MyApp myApp;
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.other);
textView = (TextView)this.findViewById(R.id.msg);
myApp = (MyApp)getApplication();
textView.setText("-appname-->>"+myApp.getName());
}
//****************************MyApp**************************
public class MyApp extends Application {
public String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void onCreate() {
super.onCreate();
setName("张三疯");
}
}
在AndroidManifest.xml中<Application> 中加入<application android:name=".MyApp" ....> 把这个App变量定为全局的。
7 从Activity中返回数据
在实际的应用中,我们不仅仅要向Activity传递数据,而且要从Activity中返回数据,虽然返回数据和传递数据类似,也可以采用前面4种方法,但是一般建议采用Intent对象的方式来返回数据,使用这种方式返回数据,需要使用startActivityForResult方法来显示Activity。
****************************MainActivity**************************///
public class Main extends Activity {
private Button button;
private final static int REQUESTCODE = 1;//返回的结果码
private EditText one,two,result;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button = (Button) this.findViewById(R.id.button);
one = (EditText)this.findViewById(R.id.one);
two = (EditText)this.findViewById(R.id.two);
result = (EditText)this.findViewById(R.id.result);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
int a = Integer.parseInt(one.getText().toString());//String转int
int b = Integer.parseInt(two.getText().toString());
Intent intent = new Intent(Main.this, OtherActivity.class);
intent.putExtra("a", a);
intent.putExtra("b", b);
startActivityForResult(intent, REQUESTCODE);//表示可以返回结果
}
});
}
@Override
//当第2个Activity返回时,会调用这个函数
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
if(resultCode==2){
if(requestCode==REQUESTCODE){
int three = data.getIntExtra("three", 0);
result.setText(String.valueOf(three));//把int转成String
}
}
}
}
//****************************otherActivity**************************
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.other);
button = (Button)this.findViewById(R.id.button2);
textView = (TextView)this.findViewById(R.id.msg);
editText = (EditText)this.findViewById(R.id.three);
Intent intent = getIntent();
int a = intent.getIntExtra("a", 0);//默认值是0
int b = intent.getIntExtra("b", 0);
textView.setText(a+" + "+b+" = "+" ? ");
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//声明一个新的Intent
Intent intent = new Intent();
int three = Integer.parseInt(editText.getText().toString());
intent.putExtra("three", three);
//通过Intent对象返回结果,setResult方法
setResult(2, intent);
//结果码定义为2。resultCode表示OtherActivity返回到Main的标志位,该标志位要与onActivityResult中的resultCode一致。
finish();//结束当前的Activity的生命周期。
}
});
}
第一个Activity中输入 3 + 4 = ?按按钮,跳到第二个Activity,输入 7 按按钮返回,在第一个Activity 显示结果。可以参考这篇文章: startActivityForResult与onActivityResult