Intent显式启动和隐式启动

众所周知 Android组件的启动模式有两种 显式调用和隐式调用,这两种调用方式从字面意思就很好理解,显式调用需要指定被启动的组件比如:

Intent i= new Intent();
i.setClass(this,SecondActivity.class);
startActivity(i);

隐式调用则不需要。那么隐式调用是怎么匹配找到被启动的组件呢?答案是IntentFilter,在Manifest.xml中注册组件的时候可以加上这个我们来看下IntentFilter包含那些信息:

<activity android:name=".ipc.IpcActivity">    
    <intent-filter>        
        <action android:name="com.ipc">action>        
        <category android:name="111">category>     
        <category android:name="111">category>
        <data android:scheme="http" android:host="123"android:mimeType="image/*">data>    
     intent-filter>
 activity>

那么想要隐式启动这个组件就需要匹配这个组件的IntentFilter,一个IntentFilter包含有action,category,和data。action指的是动作就是说你需要启动是哪个组件,categray和data则是需要携带什么类型的数据,
首先来说action的匹配规则:Android系统已经包含了一些action,我们还可以自己定义一个action。如果需要action匹配成功则需要我们Intent里的action和IntentFilter里的action里的某一个相同即可,换句话说 只要我们Intent里的action出现在了IntentFilter里则匹配成功。这里需要注意的是 如果Intent里没有action则匹配失败,也就是说action是必须有,而且还区分大小写。
接下来说下category匹配规则。catefgory的匹配规则和data不同,只要你在Intent中添加了category则需要你添加的category必须出现在IntentFilter中,也就是说 IntentFilter中的category是完全包括Inten里的category才能匹配成功,举个例子:我们需要匹配上面的IntentFilter,我们可以在Intent添加category = “111”或者category = “222”或者category = “111”,category = “111”但是我们不能添加这样的category category = “111”,category = “333”如果这样则匹配失败。
这里需要提出的一点,当我们没有写category的时候系统会默认给我们分配一个
所以在一般在隐式启动组件的时候不指定category也是可以启动成功的 因为不Itent里不指定category的时候系统也会默认给我们分配一个

所以一般建议在IntnetFilter里加上一个默认的category确保隐式启动成功
最后说说 datad 匹配规则。data匹配规则比较麻烦。因为data的结构本身就比较复杂
我们先来说说data的数据格式:一个data用xml可以表示成如下形式

<data android:scheme="http" android:host="123" android:port="8080" android:path="/abc" android:pathPrefix="/abc" android:mimeType="image/*">
data>

ata有两部分组成 URI 和mimeType。mimeType指媒体类型如image/,video/等 URI 则又比较复杂(蛋疼)一个完整的URI 的格式如scheme://host:port/[path|pathPrefix|pathPattern]上面的中括号部分可以是没有最常见的一个URL :http://www.google.com:80/search
URI中的scheme 指的是URL的类型或者说模式比如 http,file,content必写项没有的话则此URI没有意义
URI中的host主机名 必写项,
URI中的port 只有URI中的scheme和host都存在且有意思时候才是必写项。
后面的几个参数主要是路径信息 大家可以自己去查查相关资料。
介绍完URI的结构后我们来说说data的匹配规则,data的匹配规则和action差不多也要求必须有并且Intent里的data必须出现在IntentFilter中比如我们想匹配下面的一个IntentFilter中的data则我们必须在我们的Intent添加intent.setType(“img/jepg”)这里很奇怪没有URI ,其实没有URI的时候 系统会默认给我们分配一个默认的URI 一般都是 file或者是content,但是如果指定了URI则代码这样写就不能匹配成功比如我们匹配:
则我们不能写intent.setType("img/jepg"),intent.setData(Uri.parser(""http://))因为setType或者setData的时候都会把另外一个置空,我们需要intent.setDataAndType(Uri.paser("http://"),“img/*”)
好了到此我们就写完成了 隐式启动组件的基本原理了.
下面结合个小例子总结下:我们要隐式启动

<activity android:name=".ipc.IpcActivity">    
    <intent-filter>        
        <action android:name="com.ipc">action>        
        <action android:name="com.111">action>        
        <category android:name="com.ipc222">category>        <category android:name="22222">category>        
        <category android:name="android.intent.category.DEFAULT">category>        
        <data android:host="abc"            android:mimeType="image/*"            android:scheme="http">data>        
        <data android:host="abc"            android:mimeType="image/*" android:scheme="abc">data>    
intent-filter>
activity>

这个IpcActivity 则我们的Intent可以这样写

Intent intent = new Intent();                intent.setAction("com.111");//                intent.setAction("com.ipc");                intent.addCategory("com.ipc222");                intent.setDataAndType(Uri.parse("http://abc:80"), "image/*");                startActivity(intent);

这样我们就可以隐式启动IPC了,文中有可能有错误或者没讲到的地方请多多指正,多谢~

你可能感兴趣的:(Android成长历)