【Android应用开发技术:应用组件】Intent基本原理

作者:郭孝星
微博:郭孝星的新浪微博
邮箱:[email protected]
博客:http://blog.csdn.net/allenwells
Github:https://github.com/AllenWells

【Android应用开发技术:应用组件】章节列表

一个App通常都会有好几个Activity。每一个Activity的界面都扮演者用户接口的角色,允许用户执行一些特殊任务,例如查看地图或者是开始拍照等。如何让用户从一个Activity跳到另外一个Activity呢,这便是今天要介绍的Intent。

Intent来定义App的意图。当使用startActivity()的方法,且参数是intent时,系统会使用这个Intent来定义并启动合适的App组件。使用intents甚至还可以从一个App启动另一个App里面的Activity。

如下图所示:

【Android应用开发技术:应用组件】Intent基本原理_第1张图片

如何一个隐含的意图是通过系统传递再掀活动:[1]活动A创建与动作说明的意图,并将其传递给startActivity()。[2]Android系统的搜索意图过滤器意图匹配所有的应用程序。当找到一个匹配,[3]通过调用它的onCreate()方法,并传递给它的意图在系统启动的配套活动(活动B)。

Intent可以显式的指明需要启动的模块。用一个指定的Activity实例,也可以隐式的指明自己可以处理哪种类型的动作,例如拍一张照等。

一 Intent类型

Intent分为显式Intent和隐式Intent。

1.1 显式Intent

显式Intent:明确指定了它将要启动的组件。

1.2 隐式Intent

?隐式Intent并不会声明需要启动的组件的类名,而是声明一个需要执行的Action。该Action指定了需要做的事情。

例如,如果我们想要使用ACTION_VIEW的intent来显示一张图片,这个时候还应该指定MIME type为image/*,这样能够阻止其他能够 “查看” 其他数据类型的App,比如一个地图App,被这个
intent唤起。

举例1

带有指定电话号码的intent

Uri number = Uri.parse("tel:5551234");
Intent callIntent = new Intent(Intent.ACTION_DIAL, number);

举例2

查看地图

// Map point based on address
Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
// Or map point based on latitude/longitude
// Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level
Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);

举例3

查看网页

Uri webpage = Uri.parse("http://www.android.com");
Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);

举例4

发送一个带附件的email

Intent emailIntent = new Intent(Intent.ACTION_SEND);
// The intent does not have a URI, so declare the "text/plain" MIME type
emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"[email protected]"}); // recipients
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject");
emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text");
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"));
// You can also attach multiple items by passing an ArrayList of Uris

举例5

创建一个日历事件

Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);
Calendar beginTime = Calendar.getInstance().set(2012, 0, 19, 7, 30);
Calendar endTime = Calendar.getInstance().set(2012, 0, 19, 10, 30);
calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());
calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());
calendarIntent.putExtra(Events.TITLE, "Ninja class");
calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");

一 Intent属性

Intent代表了Android应用的启动意图,Android应用将会根据Intent来启动指定组件,至于启动哪个组件,则取决于Intent的各种属性。

1.1 Component属性

Intent的Component属性需要接受一个ComponentName对象,ComponentName的构造方法如下所示:

(1) public ComponentName(String pkg, String cls)

/**
 * Create a new component identifier.
 * 
 * @param pkg The name of the package that the component exists in.  Can
 * not be null.
 * @param cls The name of the class inside of pkg that
 * implements the component.  Can not be null.
 */
public ComponentName(String pkg, String cls) {
    if (pkg == null) throw new NullPointerException("package name is null");
    if (cls == null) throw new NullPointerException("class name is null");
    mPackage = pkg;
    mClass = cls;
}

(2) public ComponentName(Context pkg, String cls)

/**
 * Create a new component identifier from a Context and class name.
 * 
 * @param pkg A Context for the package implementing the component,
 * from which the actual package name will be retrieved.
 * @param cls The name of the class inside of pkg that
 * implements the component.
 */
public ComponentName(Context pkg, String cls) {
    if (cls == null) throw new NullPointerException("class name is null");
    mPackage = pkg.getPackageName();
    mClass = cls;
}

(3) public ComponentName(Context pkg, Class

/**
 * Create a new component identifier from a Context and Class object.
 * 
 * @param pkg A Context for the package implementing the component, from
 * which the actual package name will be retrieved.
 * @param cls The Class object of the desired component, from which the
 * actual class name will be retrieved.
 */
public ComponentName(Context pkg, Class cls) {
    mPackage = pkg.getPackageName();
    mClass = cls.getName();
}

上述构造函数本质上说明了包名和类名可以唯一的确定一个组件类。

1.2 Action属性

Action属性:代表该Intent所要完成的一个抽象的动作。

Action属性完成了只是一个抽象的动作,这个动作具体由谁来完成,Action本身并不管。

举例

Action:Intent.ACTION_VIEW,它只表示一个抽象的查看操作,但具体查看什么,由谁去查看,它并不知道,这些都取决于Activity的的配置,只要某个Activity的配置中包含了该ACTION_VIEW,该Activity就有可能被启动。

主Activity

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

public class ActionAttr extends Activity
{
    public final static String CRAZYIT_ACTION =
        "org.crazyit.intent.action.CRAZYIT_ACTION";

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        Button bn = (Button) findViewById(R.id.bn);
        // 为bn按钮绑定事件监听器
        bn.setOnClickListener(new OnClickListener()
        {
            @Override
            public void onClick(View arg0)
            {
                // 创建Intent对象
                Intent intent = new Intent();
                // 为Intent设置Action属性(属性值就是一个普通字符串)
                intent.setAction(ActionAttr.CRAZYIT_ACTION);
                startActivity(intent);
            }
        });
    }
}

被启动的Activity

import android.app.Activity;
import android.os.Bundle;
import android.widget.EditText;

public class SecondActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.second);
        EditText show = (EditText) findViewById(R.id.show);
        // 获取该Activity对应的Intent的Action属性
        String action = getIntent().getAction();
        // 显示Action属性
        show.setText("Action为:" + action);
    }
}

被启动的Activity在AndroidMainfest.xml文件中的配置。


<activity android:name=".SecondActivity"
                android:label="@string/app_name">
    <intent-filter>
        
        <action android:name="org.crazyit.intent.action.CRAZYIT_ACTION" />
        
        <action android:name="helloWorld" />
        
        <category android:name="android.intent.category.DEFAULT" />   
    intent-filter>
activity>

1.3 Category属性

Category属性:为Action属性增加了额外的附加类别信息。

1.4 Data属性

Data属性:向Action属性提供操作的数据。

Data属性接受一个Uri对象,一个Uri对象通常通过如下形式的字符串表示:

scheme://host:port/path

1.5 Type属性

Type属性:用于指定该Data所指定Uri对应的MIME类型,这种MIME类型可以是任何自定义的MIME类型,只要符合abc/xyz格式的字符串即可。

1.6 Extra属性

Extra属性:该属性通常用于在多个Action之间进行数据交换,它通常是一个Bundle对象,可以存入多组key-value对。

1.7 Flag属性

Flag属性:该属性为Intent添加额外的控制旗标。

你可能感兴趣的:(安卓技术,-,应用开发)