Intent详细解释:
Intent是一种意图,用于启动Activity、Service、BroadcastReceiver
类型 方法
Activity startActivity(Intent intent)
startActivityForResult(Intent intent, int requestCode)
Service ComponentName startService(Intent service)
boolean bindService(Intent service, ServiceConnection conn, int flags)
BroadcastReceiver sendBroadcast(Intent intent)
sendOrderedBroadcast(Intent intent, String receiverPermission)
右侧的方法都是在Context中(除了startActivityForResult),而且Activity和Service都是Context的子类,就是在Activity和Service中都能启动三大组件
Intent有7个属性:Action、Category、Data、Type、Extra、Flag、Compontent
Intent有两种启动方式:显示启动(指定找XXX)、隐式启动(指定条件,比如是一个大美女)
七大属性
[Compontent]
适用于显示启动,表示来源(就是上下文参数)和启动的目的地(要启动的组件)
三个构造函数:
ComponentName(String pkg, String cls)
ComponentName(Context pkg, String cls)
ComponentName(Context pkg, Class> cls)
启动另外一个App中的Activity
第一个可以用来启动第二个APP中的Activity:
//指定另外一个APP的包名和类名
ComponentName name = new ComponentName("com.summer.test", "com.summer.test.MainActivity");
Intent intent = new Intent();
intent.setComponent(name);
startActivity(intent);
注意第二个参数要写全名,这样可以启动包名是com.summer.test中的MianActivity
启动本App中的Activity
指定上下文和对应的组件名:
ComponentName name = new ComponentName(MainActivity.this, "com.summer.test.Main2Activity");
//两种方法一个是直接写出全名,一个是写出class
// ComponentName name = new ComponentName(MainActivity.this, Main2Activity.class);
Intent intent = new Intent();
intent.setComponent(name);
startActivity(intent);
简化写法
Intent intent = new Intent(MainActivity.this, Main2Activity.class);
startActivity(intent);
[Category和Action]
Action表示一个具体的动作,Categoey是Action增加的额外信息。在隐式启动中要给三个组件添加子标签而intent-filter子标签可以有action、category、data。Data和Type属性都在data标签内。
即使没有指定特定的Category系统会默认添加一个的标签。
在intent-filter中可以有多个action和category,但是最多只能有一个data标签,action和category的本质就是一个字符串,用name属性表示,比如主启动Activity:
隐式启动
启动Mian3Activity的代码:
Intent intent = new Intent();
intent.setAction("com.summer");
startActivity(intent);
这时会报错:
No Activity found to handle Intent {act=com.summer}
这是因为系统默认会给intent添加值是android.intent.category.DEFAULT的category,更改注册文件,可以启动
当两个Activity的注册文件当Action相同,但是category不同,那么只要action和intent匹配就可以启动,AndroidManifest文件:
Activity的启动代码:
Intent intent = new Intent();
intent.setAction("com.summer");
startActivity(intent);
[Extra]
Intent额外携带的数据,用putXXX来携带各种类型的数据,用getXXXX来获得数据,更改上面的案例,Activty1的发送代码:
Intent intent = new Intent();
intent.putExtra("hello","你好啊");
intent.setAction("com.summer");
startActivityForResult(intent,0);
Activity2的处理代码,就是给原有数据添加一句话:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
String hello = getIntent().getStringExtra("hello");
hello += "-----这时来自Activity2的问候";
Intent result = getIntent().putExtra("hello", hello);
// 打印Activity2正在处理
System.out.println(getLocalClassName()+"正在处理数据-------"+hello);
setResult(1,result);
}
Activity1的回调代码:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode,resultCode,data);
// 打印结果码
System.out.println(resultCode);
// 打印处理之后的结果
System.out.println(getLocalClassName()+"处理之后的数据是------"+data.getStringExtra("hello"));
}
[Data和Type]
Intent的Data属性是执行动作的URI和MIME类型,不同的Action有不同的Data数据指定。比如:ACTION_EDIT Action应该和要编辑的文档URI Data匹配,ACTION_VIEW应用应该和要显示的URI匹配。
Intent的Type属性显式指定Intent的数据类型(MIME)。一般Intent的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行判定。只要Type负责abc/xyz格式的字符串都可以。
Data和Type在单独指定的时候会相互覆盖,同时指定来两个值使用:setDataAndType方法
Data的匹配规则
Data的参数类型是Uri,例如content://win.hao.ty/data/1
Uri对应的名称是scheme://host/path 三个部分,在host后面可能有port相当于端口号
scheme、host、path是一个范围递减的三个属性(从大到小),就是某一个注册Activity只是指定了scheme属性,那么所有的Intent的Data属性只要以对应字段开头都会匹配
具体匹配实例
有这样三个Activity
对应的Intent如下,分别注释掉不同的赋值语句在启动的时候就会打开几个Activity
Intent intent = new Intent("com.summer");
// 只是启动一个Activity
intent.setData(Uri.parse("[hao://](hao://)"));
// 启动了两个Activity
intent.setData(Uri.parse("[hao://tianyi](hao://tianyi)"));
// 启动了三个Activity
intent.setData(Uri.parse("[hao://tianyi/datas/1](hao://tianyi/datas/1)"));
startActivity(intent);
[Flag]
Flag经常和Activity的启动模式一起来玩,Activity的四种启动模式:
默认模式
standard:不管这个Activity是否在栈中,都执行new操作,假如:栈中顺序是A B C D ,此时D通过Intent跳转到A,那么栈中结构就变成 A B C D A ,点击返回按钮的 显示顺序是 D C B A,依次摧毁。
对应的flag:Intent.FLAG_ACTIVITY_NEW_TASK
当目标Activity的affinity的属性和这个Activity相同时,就完全是默认模式,否则就是在一个新栈的默认模式
SingleTop
singleTop:永远在栈顶,当前Activity D位于栈顶的时候,如果通过Intent跳转到它本身的Activity (即D),那么不会重新创建一个新的D实例,所以栈中的结构依旧为A B C D,如果跳转到B,那么由于B不处于栈顶,所以会新建一个B实例并压入到栈中,结构就变成了A B C D B。
对应flag:FLAG_ACTIVITY_SINGLE_TOP
SingleTask
singleTask:也是永远在栈顶,不过当要启动的D不再栈顶时,会把上面的Activity全部干掉
对应flag:FLAG_ACTIVITY_CLEAR_TOP
SingleInstance
singleInstance:所有栈内只有一个实例,当启动D时,会先新建一个栈,然后再把D入栈
其他flag
FLAG_ACTIVITY_NO_HISTORY 一旦退出,它不会在栈内,比如:原来是A,B,C这个时候再C中以这个FLAG启动D的,D再启动E,这个时候栈中情况为A,B,C,E。