前面课程已经多次演示了显式调用和隐式调用,本节我们集中对这两种调用方式进行讲解。
1、显式调用
我们通过Intent调用组件时,可以直接指定组件类,这种方式称为显式调用,下面给出一段代码,显式调用一个Activity
Intent intent = new Intent(LoginActivity.this, HomeActivity.class); startActivity(intent); |
显式调用通常用于访问应用程序本身的组件,但也不尽其然,也就是说一个应用程序同样可以直接指定另一个应用程序的组件。下面先给出一个跨应用程序访问Activity的样例代码。
Intent intent = new Intent(); intent.setClassName("com.practise.salary.hello","com.practise.salary.hello.ViewCallActivity"); startActivity(intent); |
注意:ViewCallActivity必须声明属性android:exported="true"(该属性将在后面的课程详细介绍),如下图所示:
在Android中,包名称唯一标示一个应用,所以我们可以在Intent中指定要调用的包名称和类名称来启动其他应用中的组件。除了指定包名名外,我们还可以通过createPackageContext来创建包名对应的Context,完成对其他应用程序组件的调用。
代码如下:
try { Intent intent = new Intent(); Context viewContext = createPackageContext("com.practise.salary.hello", Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY); intent.setClassName(viewContext, "com.practise.salary.hello.ViewCallActivity"); startActivity(intent); }catch (PackageManager.NameNotFoundException exp){ Log.v(this.getClass().getName(), "异常", exp); } |
createPackageContext方法定义在ContextWrapper中,ContextWrapper是Context的一个子类。Activity与ContextWrapper之间的关系如下图所示:
createPackageContext的方法签名如下所示:
Context createPackageContext (String packageName, int flags) |
其中:
- packageName:包名,要得到Context的包名
- flags:标志位,有CONTEXT_INCLUDE_CODE和CONTEXT_IGNORE_SECURITY两个选项。CONTEXT_INCLUDE_CODE的意思是包括代码,也就是说可以执行这个包里面的代码。CONTEXT_IGNORE_SECURITY的意思是忽略安全警告,如果不加这个标志的话,有些功能是用不了的,会出现安全警告。
除了上述两种外,我们观察CompomentName构造函数,会发现,也可以通过ComponentName对象实现对其他应用程序组件的调用
Intent intent = new Intent(); intent.setComponent(new ComponentName("com.practise.salary.hello", "com.practise.salary.hello.FirstActivity")); startActivity(intent); |
2、隐式调用
我们可以通过指定Action,Category,Data,由系统根据条件,过滤选择满足条件的组件进行调用,这种调用方式称为隐式调用,下面给出隐式调用Activity的代码。
Intent intent = new Intent(); intent.setAction("com.practise.salary.hello.CALL"); intent.addCategory("com.practise.salary.hell.VIEW"); startActivity(intent); |
我们可以对某个Activity配置过滤条件,系统会调用对应的Activity。配置如下图所示:
我们通常通过隐式调用,调用系统Activity,例如下面代码,调用发送短信的Activity。
Intent intent = new Intent(); intent.setAction(Intent.ACTION_SENDTO); intent.setData(Uri.parse("smsto:10086")); intent.putExtra("sms_body","The SMS text"); startActivity(intent); |
关于系统调用,后面会有专门的章节进行讲解,此处只是做一个介绍。
(张伟:2018年9月27日)
(转载时请注明来源)