Intent学习笔记

Intent学习笔记

一、intent作用

intent是一个消息对象,用来启动app组件,其使用上主要分为三类:
1. 用于启动activity。建立Intent对象,将其作为参数传递到startActivity或StartActivityforResult()中来启动相应的activity。
2. 用于开启服务。将intent作为参数传递给startService或者bindService来开启服务.
3. 用于发送广播。将Intent作为参数传递给sendBroadcast(), sendOrderedBroadcast(),sendStickyBroadcast()来发送广播。

二、Intent

可以定义两种形式Intent:
1. 显式的Intent。通过这种方式,可以显示的指定要启动的Activity或Service,也就是说此时知道要启动的组件名称。
2. 隐式的Intent。通过这种方式,指定Intent的参数,action,data等,然后这些参数匹配组件的intentfliter来启动相应的组件。
需要说明的一点是,为了安全考虑,不要采用隐式的方式启动Service,因为你这样做,并不能确定会启动哪个Service;并且当你为自己的Service设置intentfliter后,其它app有可能启动该Service。从andriod 5.0(api 21)开始,当通过隐式的Intent传递给bindservice时,系统会抛出异常


下图展示了隐式Intent传递的流程
隐式Intent传递的流程
首先Activity A创建一个隐式Intent,并将其作为参数传递给StartActivity;andriod系统基于该Intent,匹配各Activity的intentfliter,找到匹配该Intent的Activity;然后通过调用该Activity的oncreate方法启动该Activity,并将Intent作为参数传递给onCreate。

有一点非常重要: 当采用隐式Intent来启动Activity时,可能没有找到可以匹配的Activity,此时app就会crash,所以在执行StartActivity之前通过Intent调用resolveActivity()来判断是否有可匹配的Activity。如果返回结果不为null,则至少存在一个可以启动的Activity。代码如下:

if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(sendIntent);
}

三、Intent中应该传递的内容

一个Intent对象应该包含系统用于判断启动哪个组件的信息 以及 组件启动后一些辅助信息。

Component name。

组件名称,该信息是一个可选项,包不包括该信息是决定Intent类型的关键:如果传递了组件名称,则为显示的Intent;否则为隐式的Intent。
可以通过Intent的构造函数、setComponent(), setClass(), setClassName()来设置该信息。

// 通过构造函数
Intent intent = new Intent(aActivity.this, bActivity.class);
startActivity(intent);
// 通过setComponent
Intent intent = new Intent();
intent.setComponent(new ComponentName(getApplicationContext(), bActivity.class));
startActivity(intent);
// 通过setClass来设置该信息
Intent intent = new Intent();
intent.setClass(aAvtivity.this, bActivity.class);
startActivity(intent);
// 通过setClassName来设置该信息
Intent intent = new Intent();
intent.setClassName(aAvtivity.this, bActivity.class.getName());
startActivity(intent);

Action。

启动组件完成的动作,在对应的Activity中的intentFliter中进行配置。可以用过setAction或者构造函数来制定Action参数。当设置自定义的action时,最好加上app的包名,如:

static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";

Data。

设置要启动组件要处理的数据,比如当设置Action为ACTION_EDIT时,就可以通过设置data来制定要编辑的文件。另外,当设置了data之后,可能需要设置数据类型,因为一个Activity能够处理图片但不一定能够处理视频。(但是一般可以通过设置的数据来推断出类型)。可以通过setData (接受一个uri对象)来单独设置数据,也可以通过setType来单独设置数据类型,还可以通过setDataAndType来设置数据和类型。
需要注意的是,当需要及设置数据又设置类型的时候,不要分别调用setData及setType函数,而是调用setDataAndType。

Category

分类。用来定义要启动的组件的分类,可以定义多个分类;其实大多数情况下这个参数是不要设定的。 设定分类的方法的是setCategory().


通过上述的几类信息,Android系统可以得到intent想要启动的组件。在上述基础上,Intent还可以携带一些附加信息

Extras

可以用过putExtra的各种重载方法来传递信息;同时也可以新建Bubble对象,在将该对象传递到putExtras中来传递信息。具体方法:

// 通过putExtra设置信息
Intent intent = new Intent(activity.this, bActivity.class);
intent.putExtra("valueKey", "nihao");
startActivity(intent);
// 在目的Activity中的onCreate中接收传递信息
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_b);
    Intent intent = this.getIntent();
    Log.e("tag", "b--" + intent.getStringExtra("valueKey"));
}
// 通过Bubble的方式来传递信息
Intent intent = new Intent(aActivity.this, cActivity.class);
Bundle bundle = new Bundle();
bundle.putString("valueKey", "你好");
intent.putExtras(bundle);
startActivity(intent);
// 在目的Activity获取信息
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_c);
    Intent intent = this.getIntent();
    Bundle bundle = intent.getExtras();
    Log.e("tag", bundle.getString("valueKey"));
}

Flag

用来定义Activity该以何种方式启动,以及启动之后该如何处理该Activity。该参数通过setFlag来进行设置。

四、intentFliter

通过配置文件,设置Activity的intentFliter,可以起到过滤的作用,从而启动相应的Activity。
举例来说明如何配置:

<activity android:name="MainActivity">
    <!-- This activity is the main entry, should appear in app launcher -->
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

<activity android:name="ShareActivity">
    <!-- This activity handles "SEND" actions with text data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
    <!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <action android:name="android.intent.action.SEND_MULTIPLE"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="application/vnd.google.panorama360+jpg"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="video/*"/>
    </intent-filter>
</activity>

需要说明以下几点:
1. 一个activity可以有多个intent-fliter标签,形成action,category,data等不同的组合形式
2. 每个intent-fliter标签内可以有0个或多个action,category标签,可以有0个或多个data标签。如果某个Activity不属于任何一个category,则应该属于 CATEGORY_DEFAULT,即<category android:name="android.intent.category.DEFAULT"/>
3. 在MainActivity中设置action为ACTION_MAIN,则表示该Activity为app入口,并且不用为此Activity传入参数。设置CATEGORY_LAUNCHER 类别,则说明该Activity设置的icon应该作为app的icon;如果没有设置icon属性,则在 application标签中寻找该属性。这两个必须要设置在一起才能起作用
4. 对于所有的Activity来说,都要在配置文件中设置intent fliter。但是,对于broadcast来说,应该在执行registerReceiver方法时动态的注册filter属性,然后可以在registerReceiver取消注册。这样做允许你的app只在运行的特定一段时间内可以监听到这个广播。
5. 如果不想某个activity被其它app打开,可以设置它的属性exported为false,即:

<activity android:name=".aAvtivity"
            android:exported="false">
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值