启动新的Activity
Activity是Android组件中最基本也是最为常见用的四大组件(Activity,Service服务,Content Provider内容提供,BroadcastReceiver广播接收器)之一.
几乎所有的Activity都是用来与用户交互的,Activity主要关注与视图窗体的创建,一个应用程序可以包含零个或者多个Activity,但是包含零个Activity的应用比较少。
其实通俗来说,我们可以把手机当做一个浏览器,而Activity就是其中的一个个网页,在Activity上面,我们可以添加不同的控件View,并且可以执行一些操作逻辑。
通过Intent,启动新的Activity
Intent 是 Activity程序中各组件之间进行交互的一种重要方式,它不仅可以指明当前组件想要执行的动作,还可以在不同组件之间传递数据. Intent 一般可被用于启动 Activity, 启动服务以及发送广播等场景.
Intent 大致可分为两种: 显式 Intent 和 隐式 Intent
1.1 显式 Intent 启动 Activity
Button button3 = (Button) findViewById(R.id.button3);
button3.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
// 跳转到第二个Activity
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
startActivity(intent);
}
});
通过上面代码中 Intent 构造可看出,是在 FirstActivity 这个 Activity 的基础上打开 SecondActivity.
(第一个参数是上下文,第二个参数是目标Activity.)
1.2 隐式 Intent 启动 Activity
想要隐式启动某个Activity,
首先,需要在清单文件中对这个Activity添加响应声明,即在<activity>
标签下配置<intent-filter>
的内容
通常<intent-filter>
包含以下几个方面:
- action activity对应的动作。 可以用任意一个字符串描述(最好,顾名思义)
- category 额外的类别参数。 指定工作的设备(车载电脑,机顶盒,默认的手机) 通常指定的参数
android.intent.category.DEFAULT
- data 指定数据和数据的类型
- scheme 数据前缀
- host 主机名
- port 端口号
- path 路径 记得在前面加上 /
- mimeType 数据类型 从tomcat里面查找常见的数据类型
下面代码中:在清单文件中注册两个Activity,并都配置<intent-filter>
<activity android:name="com.yassblog.SecondActivity">
<intent-filter>
<action android:name="com.yassblog.activitytest.ACTION_START"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity android:name="com.yassblog.CeshiActivity" >
<intent-filter>
<action android:name="com.yassblog.a1" />
<data android:scheme="youyiyi1" />
<action android:name="com.yassblog.a3" />
<data android:scheme="youyiyi3" />
<data android:mimeType="text/name" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<intent-filter>
<action android:name="com.yassblog.a2" />
<data android:scheme="youyiyi2" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
接着,修改按钮点击事件,隐式启动新的Activity
Button button4 = (Button) findViewById(R.id.button4);
button4.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
// 隐式跳转到第二个Activity
Intent intent = new Intent("com.yassblog.activitytest.ACTION_START");
startActivity(intent);
}
});
public void click41(View v){
Intent intent = new Intent();
intent.setAction("com.yassblog.a1");
//匹配mimetype
//intent.setType("text/name");
//匹配scheme,注意setData()会将上面的setType清除
//intent.setData(Uri.parse("youyiyi3:xiaoming"));
//匹配scheme和mimetype
intent.setDataAndType(Uri.parse("youyiyi3:xiaoming"), "text/name");
//如果没有指定category,则自动添加以下代码
//intent.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(intent);
}
public void click42(View v) {
Intent intent = new Intent();
// 匹配动作
intent.setAction("com.yassblog.a2");
// 匹配scheme
intent.setData(Uri.parse("youyiyi2:xiaoming"));
startActivity(intent);
}
注意:
设置参数时setType()会清除setData(),而setData()会清除setType(), 两者不能共存,所以通过setDataAndType(Uri.parse("youyiyi3:xiaoming"), "text/name")
; 一并将两者全部设置了.
intent-filter节点及其子节点都可以同时定义多个,隐式启动时只需与任意一个匹配即可
下面是对隐式 Intent 启动 Activity的解释:
我们通过将一系列更为抽象的 action 和 category 等信息封装到 Intent 中,然后交由系统去分析这个 Intent ,并帮我们找出合适的 Activity 去启动的方式,称为隐式 Intent 启动.
从上面代码可以看到,我们使用了 Intent的另一种构造函数,
通过直接将 action 的字符串传了进来,表明我们想要启动能够响应 com.yassblog.activitytest.ACTION_START 的 Activity. 那前面不是说要 action 和 category 同时匹配上才能响应吗? 这里怎么没看到有指定 category 呢? 这是因为 android.intent.category.DEFAULT 是一种默认的 category,在调用 startActivity() 方法时已经自动将这个 category 封装到 Intent 中了,所以这个Intent 既有 action 也有 category . 当我们在FirstActivity 的界面点击按钮,就成功启动 SecondActivity 了.
启动Activity时,每个Intent中只能封装一个 action ,但是却能封装多个 category.比如下面的例子,
1 先在清单文件中添加category
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="com.yassblog.activitytest.ACTION_START"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="com.yassblog.activitytest.MY_CATEGORY"/>
</intent-filter>
</activity>
2 再在Intent中添加一个category,并启动Activity
Button button5 = (Button) findViewById(R.id.button5);
button5.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
// 添加category,隐式跳转Activity
Intent intent = new Intent("com.yassblog.activitytest.ACTION_START");
intent.addCategory("com.yassblog.activitytest.MY_CATEGORY");
startActivity(intent);
}
});
1.3 很多系统应用界面,可以通过隐式 Intent 启动
1.3.1 打开浏览器网页
Button button6 = (Button) findViewById(R.id.button6);
button6.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
// 打开网页
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
}
});
1.3.2 打开拨号界面
Button button7 = (Button) findViewById(R.id.button7);
button7.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
// 打开拨号界面
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:10086"));
startActivity(intent);
}
});