开发人员都知道,使用隐式intent可以获取目标activity并以列表的形式展示。而如果想要实现用户点击任一列表项时,启动对应的activity,那我们就需要使用显式intent来启动activity。要创建启动activity的显式intent,则需要从ResolveInfo对象中获取activity的包名与类名。这些信息可以从ResolveInfo对象的ActivityInfo中获取。
更新ActivityHolder类实施一个点击看听器。然后,使用ActivityInfo对象中的数据信息,创建一个显式intent并启动目标activity,如下代码所示。
启动目标activity(NerdLauncherFragment.java)
...
private class ActivityHolder extends RecyclerView.ViewHolder
implements View.OnClickListener {
private ResolveInfo mResolveInfo;
private TextView mNameTextView;
public ActivityHolder(View itemView) {
super(itemView);
mNameTextView = (TextView) itemView;
mNameTextView.setOnClickListener(this);
}
public void bindActivity(ResolveInfo resolveInfo) {
...
}
@Override
public void onClick(View v) {
ActivityInfo activityInfo = mResolveInfo.activityInfo;
Intent i = new Intent(Intent.ACTION_MAIN)
.setClassName(activityInfo.applicationInfo.packageName,
activityInfo.name);
startActivity(i);
}
}
从以上代码可以看到,作为显式intent的一部分,我们还发送了ACTION_MAIN操作。发送的intent是否包含操作,对于大多数应用来说没有什么差别。不过,有些应用的启动行为可能会有所不同。取决于不同的启动要求,同样的activity可能会显示不同的用户界面。建议南昌APP开发时先明确启动意图,以便让activity完成它应该完成的任务。
在以上代码中,使用包名和类名创建显式intent时,我们使用了以下Intent方法:
public Intent setClassName(String packageName, String className)
这不同于以往创建显式intent的方式。之前,我们使用的是接受Context和Class对象的Intent构造方法:
public Intent(Context packageContext, Class> cls)
该构造方法使用传入的参数来获取Intent需要的ComponentName。ComponentName由包名和类名共同组成。传入Activity和Class创建Intent时,构造方法会通过Activity类自行确定全路径包名。
也可以自己通过包名和类名创建ComponentName,然后使用下面的Intent方法创建显式intent:
public Intent setComponent(ComponentName component)
不过,setClassName(...)方法能够自动创建组件名,所以使用该方法需要的实现代码相对较少。运行NerdLauncher应用并尝试启动一些应用。