ZetCode

Android Intents

最后修改于 2012年11月11日

在本章 Android 开发教程中,我们将讨论 Intents。

根据 Android 开发者文档,一个 Intent 是一个异步消息。它是对要执行的操作的抽象描述。Intents 用于在活动之间导航。活动、服务和广播接收器通过 intents 激活。Intents 实现了应用程序中代码的松耦合。一个 Intent 被传递给一些方法,如 Context.startActivity()Context.startService() 来执行某些操作。

Intents 有两种类型:显式和隐式。在显式 intents 中,您提供 Activity 类的名称。在隐式 intents 中,您告诉系统要做什么,而不是命名要启动的 Activity 类。

隐式 Intent

显示网页可以通过隐式 intent 来完成。它将启动一个默认的网页浏览器来打开指定的网页。在示例中,我们将显示网页内容。清单文件没有修改。

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
 
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:onClick="onClicked"
        android:text="@string/btn_title" />
 
</LinearLayout>

main.xml 布局文件中,我们只有一个简单的按钮控件。点击按钮将显示网页。

strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Url</string>
    <string name="btn_title">Visit</string>
</resources>

字符串资源。

MainActivity.java
package com.zetcode.url;

import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
import android.net.Uri;
import android.view.View;

public class MainActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    public void onClicked(View view)
    {
        Intent intent =  new Intent(Intent.ACTION_VIEW, 
            Uri.parse("http://www.google.com"));
        startActivity(intent);        
    }
}

这是 MainActivity.java 源文件。

public void onClicked(View view)
{
    Intent intent =  new Intent(Intent.ACTION_VIEW, 
        Uri.parse("http://www.google.com"));
    startActivity(intent);        
}

onClicked() 方法中,我们创建一个 Intent 对象并启动一个新的活动。通过这个隐式 intent,我们告诉 Android 启动一个默认的网页浏览器并打开 google.com 网页。

Web page in Android emulator
图:Android 模拟器中的网页

显式 Intent

在显式 intents 中,我们提供要运行的确切类。

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.zetcode.explicit"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:label="@string/app_name" 
            android:icon="@drawable/ic_launcher">
        <activity android:name="MainActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <activity android:name=".NextActivity"></activity>
        
    </application>
</manifest>

在清单文件中,我们将新活动注册为 NextActivity。前面的点是我们当前包名(在本例中是 com.zetcode.explicit)的简写。

main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:onClick="onClicked"
        android:text="@string/btn_title" />        
</LinearLayout>

main.xml 文件中,我们有一个按钮。点击此按钮将启动一个新的显式活动。

strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Explicit</string>
    <string name="btn_title">Next</string>
</resources>

这是 strings.xml 资源文件。

$ ls src/com/zetcode/explicit/
MainActivity.java  NextActivity.java

在 src/com/zetcode/explicit 子目录中,我们有两个活动源文件。

MainActivity.java
package com.zetcode.explicit;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.content.Intent;

public class MainActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    public void onClicked(View view)
    {
        Intent intent =  new Intent(this, NextActivity.class);
        startActivity(intent);        
    }
}

这是主活动的源代码。在 onClicked() 方法中,我们启动一个新的显式 intent。

public void onClicked(View view)
{
    Intent intent =  new Intent(this, NextActivity.class);
    startActivity(intent);        
}

Intent 构造函数的第二个参数是要调用的类名。该活动通过 startActivity() 方法启动。

NextActivity.java
package com.zetcode.explicit;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.LinearLayout;

public class NextActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        initUI();
    }

    public void initUI()
    {
        LinearLayout lay = new LinearLayout(this);
        
        TextView tv = new TextView(this);
        tv.setText("Next screen");
        lay.addView(tv);

        setContentView(lay);
    }
}

这是 NextActivity.java 的源代码。在此活动中,我们在屏幕上显示一个 TextView。它通过编程方式放置在一个线性布局中。

数据传输

Intents 用于在活动之间传输数据。我们使用 putExtra() 方法向 intent 添加额外数据。在下面的示例中,我们将一个名字写入编辑文本框,然后点击“发送”按钮。我们将跳转到另一个屏幕,在那里我们将看到对我们输入的姓名的问候。

$ ls res/layout/
screen1.xml  screen2.xml
$ ls src/com/zetcode/switch2/
FirstScreen.java  SecondScreen.java

res/layout 目录中,我们有两个 XML 布局文件。在 src/com/zetcode/switch2 中,我们有两个活动的源文件。

AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.zetcode.switch2"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:label="@string/app_name"
                    android:icon="@drawable/ic_launcher">
        <activity android:name=".FirstScreen">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <activity android:name=".SecondScreen"></activity>
        
    </application>
</manifest>

在清单文件中,我们定义了两个活动:FirstScreenSecondScreen 活动。FirstScreen 是主活动。

screen1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  <EditText android:id="@+id/editId"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:layout_marginTop="10dip"
          android:layout_marginBottom="10dip"
          android:hint="@string/etHint" />    
          
  <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@string/btn_send" 
          android:onClick="sendMessage" />      
</LinearLayout>

screen1.xml 布局文件由 FirstScreen 活动加载。它显示一个 EditText 和一个 Button 控件。android:hint 属性在 EditText 中显示默认的灰色文本。

screen2.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  <TextView
      android:id="@+id/tvId"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      />
</LinearLayout>

screen2.xml 文件中,我们有一个 TextView 控件。它将显示我们从一个屏幕传输到另一个屏幕的文本。它由 SecondScreen 活动加载。

strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Switch</string>
    <string name="etHint">Enter your name</string>
    <string name="btn_send">Send</string>
</resources>

这是 strings.xml 资源文件。

FirstScreen.java
package com.zetcode.switch2;

import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
import android.view.View;
import android.widget.EditText;

public class FirstScreen extends Activity
{
    private EditText iname;
 
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        setTitle("First screen");
        setContentView(R.layout.screen1);

        iname = (EditText) findViewById(R.id.editId);
    }

    public void sendMessage(View view) 
    {
        Intent switchTo = new Intent(this, SecondScreen.class);        
        switchTo.putExtra("name", iname.getText().toString());        
        startActivity(switchTo); 
    }
}

FirstScreen 是主活动。点击按钮时会调用 sendMessage() 方法。

public void sendMessage(View view) 
{
    Intent switchTo = new Intent(this, SecondScreen.class);        
    switchTo.putExtra("name", iname.getText().toString());        
    startActivity(switchTo); 
}

sendMessage() 方法中,我们创建了一个 Intent 的实例。它将引导我们到 SecondScreen 活动。使用 putExtra() 方法,我们将 EditText 中的数据添加到 intent。第一个参数是我们用来引用数据的名称。第二个参数是要传输的数据。

SecondScreen.java
package com.zetcode.switch2;

import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
import android.widget.TextView;

public class SecondScreen extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.screen2);

        setupUI();
    }

    void setupUI()
    {
        setTitle("Second screen");

        TextView tv = (TextView) findViewById(R.id.tvId);
        
        Intent i = getIntent();
        String name = i.getStringExtra("name");        
        tv.setText("You have entered: " + name);
    }
}

这是 SecondScreen.java 源文件。它由 FirstScreen 活动调用。

setupUI();

setupUI() 方法中,我们设置了屏幕的用户界面。

setTitle("Second screen");

我们使用 setTitle() 方法为屏幕设置标题。

Intent i = getIntent();
String name = i.getStringExtra("name");        
tv.setText("You have entered: " + name);

getIntent() 方法返回启动该活动的 intent。我们使用 getStringExtra() 方法获取额外数据。数据被设置为 TextView

在本章 Android 开发教程中,我们已经介绍了 Intents。