Android应用将会根据Intent来启动指定组件,至于到底启动哪个组件,则取决于Intent的各属性。本期将详细介绍Intent的各属性值,以及 Android如何根据不同属性值来启动相应的组件。
Intent 对象大致包含 Component、Action、Category、Data、Type、Extra 和 Flag 这 7 种属性,其中Component用于明确指定需要启动的目标组件,而Extra则用于携带需要交换的数据。
一、Component属性
Intent 的 Component 属性需要接受一个 ComponentName 对象,ComponentName 对象包含如下几个构造器。
-
ComponentName(String pkg, String cls):创建pkg所在包下的cls类所对应的组件。
-
ComponentName(Context pkg, String cls):创建pkg所对应的包下的cls类所对应的组件。
-
ComponentName(Context pkg, Class<?> cls):创建 pkg 所对应的包下的 cls 类所对应的组件。
上面几个构造器的本质是相同的,这说明创建一个ComponentName需要指定包名和类名。这样就可以唯一地确定一个组件类,这样应用程序即可根据给定的组件类去启动特定的组件。
除此之外,Intent还包含了如下三个方法。
-
setClass(Context packageContext, Class<?> cls):设置该 Intent 将要启动的组件对应的类。
-
setClassName(Context packageContext, String className):设置该 Intent 将要启动的组件对应的类名。
-
setClassName(String packageName, String className):设置该 Intent 将要启动的组件对应的类名。
指定Component属性的Intent已经明确了它将要启动哪个组件,因此这种Intent也被称为显式Intent,没有指定Component属性的Intent被称为隐式Intent。
下面的示例程序示范了如何通过显式Intent (指定了 Component属性)来启动另一个 Activity。该程序的界面布局很简单,界面中只有一个按钮,用户单击该按钮将会启动第二个Activity。此处不再给出该程序的界面布局文件。该程序的Java代码如下:
package com.jinyu.cqkxzsxy.android.intent.componentattr;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button startBtn = (Button) findViewById(R.id.start_btn);
// 为bn按钮绑定事件监听器
startBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// 创建一个ComponentName对象
ComponentName comp = new ComponentName(MainActivity.this, SecondActivity.class);
Intent intent = new Intent();
// 为Intent设置Component属性
intent.setComponent(comp);
startActivity(intent);
}
});
}
}
上面程序中的onClick回调方法里面的代码用于创建ComponentName对象,并将该对象设置成Intent 对象的Component属性,这样应用程序即可根据该Intent的意图去启动指定组件。 实际上,这几行关键代码完全可以简化为如下形式:
// 根据指定组件类来创建Intent
Intentintent=newIntent(MainActivity.this,SecondActivity.class);
startActivity(intent);
从上面的代码可以看出,当需要为Intent设置Component属性时,实际上Intent己经提供了一个简化的构造器,这样方便程序直接指定启动其他组件。
当程序通过Intent的Component属性(明确指定了启动哪个组件)启动特定组件时,被启动组件几乎不需要使用<intent-filter.../>进行配置。
程序的SecondActivity也很简单,它的界面布局中只包含一个简单的文本框,用于显示该 Activity对应的Intent的Component属性的包名、类名。该Activity的Java代码如下:
package com.jinyu.cqkxzsxy.android.intent.componentattr;
import android.content.ComponentName;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
public class SecondActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
TextView showTv = (TextView) findViewById(R.id.show_tv);
// 获取该Activity对应的Intent的Component属性
ComponentName comp = getIntent().getComponent();
// 显示该ComponentName对象的包名、类名
showTv.setText("组件包名为:" + comp.getPackageName()
+ "\n组件类名为:" + comp.getClassName());
}
}
运行上面的程序,通过第一个Activity中的按钮进入第二个Activity中,将可以看到下图所示的界面。
二、Action属性