启动新的Activity

作者: wxyass 分类: Android 发布时间: 2015-04-22 01:38

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);
            }
        });  

源码下载: http://oss.wxyass.com/wxyass/demo/ActivityTest.rar

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

邮箱地址不会被公开。 必填项已用*标注