Intent的概念与使用
关于Intent,目前只用在启动activity上,通常启动一个activity时需要传递一个intent参数给指定的activity,同时也可以在这个Intent中夹带一些参数进行传递。
用显示Intent启动Activity
显示intent就是指定了要启动的activity的类的intent,这种intent通常是用在app内activity之间的交互。接下来就来在一个项目里注册两个activity来看一看如何用intent启动。
如果不直接新建activity,就要新建一个java类,并令它继承Activity类,还要在res文件夹中新建layout文件定义其ui。之后在java文件中实现Activity的各个方法,通常在onCreate方法中进行layout与activity的绑定:
1 |
|
之后为了使用这个activity中,我们还需要在AndroidManifest文件中进行注册,注意activity的name会与manifest的package组合起来作为Activity类的名称,所以在这里注册时可以使用简写,也可以在name中写全包名.类名
1 | <manifest ... |
到这里,我们就已经新建了一个activity,并且可以绑定它对应的java和res文件了。如果直接在AS中新建activity的话,ide会自动帮我们完成这些配置工作。
到这里,我们就可以试着用显示intent启动activity了,这里选择用一个按钮来触发新activity的启动:
1 | findViewById(R.id.button).setOnClickListener( |
java允许传new出来的参数,而new抽象类需要实现抽象方法,这种嵌套方式写出来的代码非常紧凑,不过通常我们会把findViewById的结果声明为private变量保存下来方便以后调用。
查看Intent构造器可知Intent可以用一个Context类型对象和一个class泛型来构造,这就是我们的显示Intent要传递的包名和类名。
1 | public Intent(Context packageContext, Class<?> cls) |
隐式Intent
Intent除了用显式指定的包名和类名构造之外,也可以先通过一个标记构造,之后再寻找标记对应的类。最常见的方法是使用action,也就是一个字符串。如果用action构造了一个intent,那么就可以直接用这个字符串搜索到注册了这个action的类。(小疑惑,如果有两个一样的action会怎样呢?)
注册action
在androidmanifest文件中,activity下加入intent-fliter标签:
1 | <intent-filter> |
注意,新版Android可能会报错,要求指定activity是否exported,直接用快速修复功能设置为true即可。下文会讲到。
category的name暂时选择default就可以,而action的name则要注册为对应的字符串,标准的action格式是<package_name>.action.start.<class_name>
,不过这个格式实在过于复杂,我们也可以把action的名字放在要启动的类中,作为一个常量
1 | public class MyAty extends Activity { |
这样在使用Intent时,就不需要直接输入长长的字符串,使用MyAty.ACTION
就可以了
用隐式Intent启动同一个app内的另一个Activity
基本的方法和之前都是相同的,区别就是构造intent时调用了另一种构造器:
1 | findViewById(R.id.button).setOnClickListener( |
1 | public Intent(String action) |
当然,隐式Intent最主要的作用并不是用来启动同一个应用内的activity,因为此时我们是可以直接获得这个activity的类的定义的。而在跨应用通讯时,隐式Intent就有用处了。
用Intent跨应用启动activity
还记得之前AS可能会要求我们添加的exported属性吗:
1 | <activity android:name=".MyAty" |
这是安卓权限管理引入的机制:只有设置为exported的activity对其他应用才是可见的,现在我们可以把它改为true,然后在project中新建一个package(app),并且在另一个app中启动这个app的activity
1 | findViewById(R.id.btn_start_myaty).setOnClickListener( |
这里使用了try结构来捕获可能的异常,如果前面没有正确的设置exported的话,就可能导致异常的出现。捕获到异常之后,用Toast组件打印一条提示信息。