Intent是对一个可能执行的操作的抽象描述,例如可以通过Intent来启动一个Activity、Service和发送广播等。它最常用于启动其他Activty。
Intent有两种形式:显式和隐式。显式即直接指定具体的的组件类,而隐式则是通过Manifest文件activity节点的intent-filter来过滤出符合条件的意图,通对action、data和category等属性来进行过滤。
实例一:通过显示Intent启动一个Activity
新建一个MainActivity和一个SecondActivity,MainActivty中的Button点击操作
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent(MainActivity.this,
SecondActivity.class); // 直接指明要跳转的Activity
startActivity(intent);
}
});
点击button后直接跳转到
SecondActivity,非常简单,因为意图非常明显~~
实例二:通过隐式Intent启动一个Activity
①修改实例一的程序,在Manifest中为SecondActivity添加一个intent-filter节点
<activity
android:name=".SecondActivity"
android:label="@string/title_activity_second" >
<intent-filter>
<action android:name="leelit.intent.MyAction" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
②修改MainActivity里的button代码
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent("leelit.intent.MyAction");
startActivity(intent);
}
});
点击button后依然会跳转到
SecondActivity,这是因为意图过滤器通过leelit.intent.MyAction这条信息将意图过滤出来了。系统会自动过滤出符合条件的意图,但是当多个意图都符合时,例如,再增加一个ThirdActivity,它的intent-filter同样是
<intent-filter>
<action android:name="leelit.intent.MyAction" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
那么我们点击button后会产生如下的效果:
这是因为有两个隐式Intent都完全符合条件,系统无法决定要启动哪个一个Activity,所以就询问一下用户啦。假设我们为SecondActivity的intent-filter再加一些其他的category信息。
<activity
android:name=".SecondActivity"
android:label="@string/title_activity_second" >
<intent-filter>
<action android:name="leelit.intent.MyAction" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="leelit.intent.MyCategory" />
</intent-filter>
</activity>
修改一下button代码
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setAction("leelit.intent.MyAction");
intent.addCategory("leelit.intent.MyCategory"); // 增加了一个category信息
startActivity(intent);
}
});
这样点击后就会跳转到SecondActivity,因为只有
SecondActivity的intent-filter完全符合这时的隐式Intent。
注意:Intent只可以含有一个action,但是可以有多个category信息。除了action和category外,intent-filter还包含data、type、componet、extras等信息,总之都是为了过滤出符合条件的Intent。另外,假设我们安装的某个程序里某个Activity里同样有上述的intent-filter,执行该程序也可以跳转到那个程序的Activity,这在平常使用还是很常见的,例如点击某个控件就打开浏览器电话本什么的。
实例三:通过Intent传递数据给启动的Activity
①继续沿用上面的代码,在intent里面添加一些数据
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setAction("leelit.intent.MyAction");
intent.addCategory("leelit.intent.MyCategory"); // 增加了一个category信息
intent.putExtra("data", "Message from MainActivity"); // 添加数据
startActivity(intent);
}
});
②同时我们在SecondActivity中获取数据
TextView textView = (TextView) findViewById(R.id.textview);
Intent intent = getIntent(); // 获得意图
String data = intent.getStringExtra("data"); // 取出数据
textView.setText(data); // TextView显示取出的数据
点击button后显示
实例四:通过Intent返回数据给原来的Activity
①先在SecondActivty中设置返回的数据
Intent resultIntent = new Intent();
resultIntent.putExtra("data", "Message from SecondActivity"); // 带返回数据的Intent
setResult(1, resultIntent); // 设置返回结果,第一个参数是resultCode
②在MainActivity中获取返回的数据,注意MainActivity中必须用startActivityForResult方法来启动SecondActivity,另外重写一个onActivityResult方法来获取返回的数据。
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
Intent intent = new Intent();
intent.setAction("leelit.intent.MyAction");
intent.addCategory("leelit.intent.MyCategory"); // 增加了一个category信息
intent.putExtra("data", "Message from MainActivity"); // 添加数据
startActivityForResult(intent, 1); // 第二个参数是requestCode
}
});
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if (requestCode == 1) {
if (resultCode == 1) {
String string = data.getStringExtra("data");
System.out.println(string); // 打印出返回的数据
}
}
}
当我们从SecondActivty返回到MainActivity时就可以获取数据
注意:上面的requestCode为了区别不同的Activity,resultCode是则为了区别返回的不同结果。
---------------------------------------------------------------------华丽的分割线-------------------------------------------------------------------------
因为出现了两个Activity,所以可以分析Activity的完整生命周期,继续沿用上面的代码,在MainActivity和SecondActivity的onCreate、onStart等生命方法中设置Log。妈的一直上传不了图片,那就文字打印吧。
①首先进入MainActivity,打印:
11-22 08:59:35.958: I/Life(9971): ==>> MainActivity onCreate
11-22 08:59:35.958: I/Life(9971): ==>> MainActivity onStart
11-22 08:59:35.958: I/Life(9971): ==>> MainActivity onResume
②启动SecondActivty
11-22 09:01:07.718: I/Life(9971): ==>> MainActivity onPause
11-22 09:01:07.828: E/Life(9971): ==>> SecondActivity onCreate
11-22 09:01:07.828: E/Life(9971): ==>> SecondActivity onStart
11-22 09:01:07.828: E/Life(9971): ==>> SecondActivity onResume
11-22 09:01:08.298: I/Life(9971): ==>> MainActivity onStop
③退出SecondActivity
11-22 09:01:59.448: E/Life(9971): ==>> SecondActivity onPause
11-22 09:01:59.468: I/Life(9971): ==>> MainActivity onRestart
11-22 09:01:59.468: I/Life(9971): ==>> MainActivity onStart
11-22 09:01:59.468: I/Life(9971): ==>> MainActivity onResume
11-22 09:01:59.858: E/Life(9971): ==>> SecondActivity onStop
11-22 09:01:59.858: E/Life(9971): ==>> SecondActivity onDestory
④退出MainActivity
11-22 09:02:21.828: I/Life(9971): ==>> MainActivity onPause
11-22 09:02:22.518: I/Life(9971): ==>> MainActivity onStop
11-22 09:02:22.518: I/Life(9971): ==>> MainActivity onDestory
通过以上以上四步我们可以知道一个Activity的完整生命周期是:onCreate、onStart、onResume,当启动SecondActivity时onPause,SecondActivity则执行onCreate、onStart、onResume,当SecondActivity获得焦点后,MainActivity才onStop,当从SecondActivity返回到MainActivity时,依然是等到MainActivity获取焦点后,SecondActivity才onStop,因为是完全退出所以还要onDestory。另外,当从SecondActivity返回MainActivity时,MainActivity并非重新创建,所以是onRestart。相信这一轮下来,对于Activity的生命周期可以很了解了。