Android学习笔记(四)

时间:2022-06-20 08:58:59

一个应用程序是有很多活动构成的,使用Intent在活动间移动。

Intent分为显式和隐式两种:

1.显示Intent:

新建一个布局文件,命名为second_layout.xml,代码如下

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

<Button
    android:id="@+id/button_2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/app_button_2"
    />
</LinearLayout>

然后新建一个后动SecondActivity继承于Activity,代码如下:

package com.gui.activitytest;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;

public class SecondActivity extends Activity {

    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.second_layout);
    }
}

最后在AndroidManifest.xml中注册SecondActivity,注册代码如下:

<activity
    android:name=".SecondActivity">
</activity>

因为SecondActivity不是主活动,所以不需要配置<intent-filter>标签里的内容。

从第一个活动启动第二个活动,需要引入一个Intent。

Intent是Android程序中各组件之间进行交互的一种重要方式,它可以指明当前
      * 组件想要执行的动作,也可以在不同的组件之间传递参数。
      * 用途:Intent被用于启动活动、启动服务、以及发送广播等场景。
      * 用法:Intent大致分为两种:显式Intent和隐式Intent
      * 实例:Intent有多个构造函数的重载,其中一个是
      * Intent(Context packageContext,Class<?>cls)。
      * 这个构造函数接收两个参数:第一个参数Context要求提供一个启动活动
      * 上下文,第二个参数Class则是指定想要启动的目标活动。
      * 使用:Activity类中提供一个startActivity()方法,这个方法用来启动活动
      * 它接收一个Intent参数。将构建好的Intent传入startActivity()方法就可以启动目标活动了

如何启动第二个活动呢?修改FirstActivity中按钮的点击事件,代码如下:

        //显式的调用Intent
    Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
    startActivity(intent);

上面代码的含义是首先构建一个Intent,传入FirstActivity.this作为上下文,传入SecondActivity.class作为目标活动。然后通过startActivity()方法

来执行定义的Intent。

2.隐式Intent

隐式Intent不明确指出想要启动哪一个活动,而是指定了一系列抽象的action和category等信息,然后交由系统来判断启动哪一个活动。

通过<activity>标签下配置<intent-filter>的内容,可以指定当前活动能够响应的action和category,比如打开AndroidManifest.xml,添加如下代码:

<activity
        android:name=".SecondActivity">
        <intent-filter>
           <action android:name="com.example.activitytest.ACTION_START"/>
           <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
        </activity>

* 在<action>标签中指明了当前活动可以响应com.example.activitytest.ACTION_START
* 这个action。<category>标签中包含一些附加信息,精确指明了当前的活动能够
* 响应的Intent中还可能带有的category。
* 只有<action>和<category>中的内容同时能够匹配Intent中指定的action和category时这个活动才能响应Intent。

配置好<intent-filter>标签中的内容后,然后修改FirstActivity中按钮的点击事件,代码如下:

Intent intent = new Intent("com.example.activitytest.ACTION_START");
startActivity(intent);

使用Intent的另一个构造函数,直接将action的字符串传了进去,表明想要启动能够响应com.example.activitytest.ACTION_START这个action的活动。
android.intent.category.DEFAULT是一种默认的category,在调用startActivity()方法的时候会自动将这个category添加到Intent中。

每个Intent中只能指定一个action,但却能指定多个category。

比如修改FirstActivity中按钮的点击事件,代码如下:

//隐式使用Intent
Intent intent = new Intent("com.example.activitytest.ACTION_START");
intent.addCategory("com.example.activitytest.MY_CATEGORY");
startActivity(intent);

代码中,可以使用Intent中的addCategory()方法来添加一个category,这里自定义了一个category,值为com.example.activitytest.MY_CATEGORY。

代码中添加category后,必须要在AndroidManifestxml文件中的SecondActivity的<intent-filter>标签中添加代码中所声明的category的内容。

隐式Intent来启动活动有很多用法,使用隐式活动也可以启动其它程序的活动。

比如修改FirstActivity中按钮的点击事件,代码如下所示:

    //使用隐式Intent,不仅可以启动自己内部的活动,还可一启动其他程序的活动
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(Uri.parse("http://www.baidu.com"));
    startActivity(intent);

上述的代码中首先指定Intent的action是Intent.ACTION_VIEW,这是一个Android系统内置的动作,其常量值为android.intent.action.VIEW。

然后通过Uri.parse()方法,将网址字符串解析成一个Uri对象,在调用Intent的setData()方法将这个Uri对象传递进去。重新运行程序会得到下图的

事例:

Android学习笔记(四)

setData()方法接收一个Uri对象,主要用于指定当前的Intent正在操作的数据,而这些数据通常都是以字符串的形式传入到Uri.parse()方法中解析产生的。

而且还可以在<intent-filter>标签中再配置一个<data>标签,更精确的指定当前活动能够响应什么类型的数据。

<data>标签中主要可以配置一下的内容:

(1)android:scheme  用于指定数据的协议部分,如上面的http部分。

(2)android:host       用于指定数据的主机名部分,如上面的www.baidu.com部分。

(3)android:port       用于指定数据的端口部分,一般紧随主机名后。

(4)android:path      用于指定主机名和端口之后的部分,如一段网址跟在域名之后的内容。

(5)android:mimeType  用于指定可以处理的数据类型,允许使用通配符的方式进行指定。

只有<data>标签中指定的内容和Intent中携带的Data完全一致时,当前活动才可以响应该Intent。

例如,新建一个布局文件,命名为third_layout.xml,代码如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:id="@+id/button_3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/app_button_3"
        />

</LinearLayout>

然后新建活动ThirdActivity并继承于Activity,代码如下:

package com.gui.activitytest;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;

public class ThirdActivity extends Activity {

    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.third_layout);
    }
}

最后在AndroidManifest.xml中注册ThirdActivity,代码如下:

<activity
            android:name=".ThirdActivity" >
            <intent-filter >
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT" />
                <data android:scheme="http" />
            </intent-filter>
</activity>

上面的代码,在ThirdActivity的<intent-filter>中配置了当前活动能够响应的action是Intent.ACTION_VIEW的常量值,而category是默认值,<data>

标签中通过android:scheme指定了数据的协议必须是http协议,这样的话ThirdActivity应该和浏览器一样,能够响应打开一个网页的Intent了。

重新运行程序,点击FirstActivity中的按钮,结果如下图所示:

Android学习笔记(四)

从图片中可以看到,系统自动弹出了一个列表,显示了目前能够响应这个Intent的所有程序。