`
寻梦者
  • 浏览: 637706 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

android中的隐式intent跟显式intent的使用

 
阅读更多

    显式启动Activity指的是在Intent内部直接声明要启动的activity所对应的class

    隐式启动Activity的intent到底发给哪个activity,需要进行三个匹配,一个是action, 一个是category,一个是data,可以是全部或部分匹配,同样适用于Service和BroadcastReceiver,下面是以Activity为例

MainActivity.java --主Activity

TestActivity.java --需要隐式启动的Activity

(1) 根据Action和Category来进行匹配

         <activity android:name=".TestActivity"  android:label="TestActivity">

        <intent-filter >

         <action android:name="cc.android/myaction.leo"/>

         <category android:name="android.intent.category.DEFAULT"/>

        </intent-filter>

        </activity>

在MainActivity.java里启动它:

intent.setAction( "cc.android/myaction.leo");

//不加下面这行也行,因为intent的这个属性默认值即系Intent.CATEGORY_DEFAULT

intent.addCategory(Intent.CATEGORY_DEFAULT);

startActivity( intent );

总结:

a.在某个Activity里用startActivity()方法发送一个intent,这个intent设定了一些条件,比如用方法 setAction(),addCategory()设定了两个属性,发送了这个intent之后,android会去系统里保存的MainManifest.xml清单(假设这个系统存放全部apk清单的文件为 MainManifest.xml)里查找符合这两个属性的activity,然后启动它。

         查找过程是怎样的呢?

  我猜测:在安装某个apk的时候,android系统会把这个apk的清单文件里内容复制一份至系统的某个清单文件里(假如这个系统存放全部apk清单的 文件为MainManifest.xml)

         当某个Activity用startActivity(intentOther)方法向系统发送了一个intent(假如为intentOther),那 么 android系统会去查找这个MainManifest.xml里注册的<intent-filter >属性, 查找到符合这个 intentOther 的就启动这个Activity,如果有多个这样的Activity符合条件的话,就跳出一个对话框让用户选择究竟要启动哪一个

上面那个自定义的Action字符串("cc.android/myaction.leo",当然也可以写成这 样"cc.android.myaction.leo",同时AndroidManifest.xml里也要写成这样)是系统唯一的, 所以系统很容易就能匹配到。

b.任何一个需要隐式启动的Activity都必须要有这项:<category android:name="android.intent.category.DEFAULT"/>

例外情况是:android.intent.category.MAIN和android.intent.category.LAUNCHER的 filter中没有必要加入android.intent.category.DEFAULT,当然加入也没有问题

c.假如有两个Activity,它们的在AndroidManifest.xml里配置如下:

<activity android:name="MyActivityOne" android:label="@string/activityOne">

<intent-filter>

<action android:name="hello.leo.liao" />

<action android:name="hello.leo.leo" />

<category android:name="android.intent.category.DEFAULT" />

</intent-filter>

</activity>

<activity android:name=".MyActivityTwo" android:label="@string/activityTwo">

<intent-filter>

<action android:name="hello.leo.liao" />

<category android:name="android.intent.category.DEFAULT" />

</intent-filter>

</activity>

在MainActivity.java里发送一个intent:

intent.setAction( "hello.leo.liao");

//不加下面这行也行,因为intent的这个属性默认值即系Intent.CATEGORY_DEFAULT

intent.addCategory(Intent.CATEGORY_DEFAULT);

startActivity( intent );

这样的话,android系统会跳出一个对话框让你选择启动哪一个Activity(MyActivityOne还是MyActivityTwo)

就是说如果category和action都相同的话,会跳出一个对话框让用户选择要启动哪一个activity;

如果category相同,而action不相同,就可以匹配到相应的activity

d.单单靠添加addCategory属性不能匹配,如:

e.当匹配不上任何Activity的话,会发生异常,跳出对话框:很抱歉...某某应用程序意外停止,请重试。

f.Service和BroadcastReceiver 同理

(2) 根据Action和Data匹配

<activity android:name=".MyActivityTwo" android:label="@string/activityTwo">

<intent-filter>

             <action android:name="android.intent.action.leo"></action>

                <category android:name="android.intent.category.DEFAULT"></category>

                <data android:scheme="x-id"></data>

</intent-filter>

</activity>

//Uri uri = Uri.parse("x-id://www.google.com/getDetails?id=123");//这个也可以

//Uri uri = Uri.parse("x-id");//这个不行

//Uri uri = Uri.parse("x-id://");这个可以

Uri uri = Uri.parse("x-id:");//这个可以

            Intent in = new Intent();

            in.setAction("android.intent.action.leo");//去掉这行不行,单靠data不能匹配

            in.addCategory(Intent.CATEGORY_DEFAULT);//可以去掉这行,intent的默认category值

            in.setData(uri);//去掉这行不行

            startActivity(in);

总结:如果在AndroidManifest.xml里面指定了<data>这行,那么,需要匹配到它的话,在代码里必须要设置 intent的data,如上面的in.setData(uri)   

Data的语法:

<data android:host="string"

      android:mimeType="string"

      android:path="string"

      android:pathPattern="string"

      android:pathPrefix="string"

      android:port="string"

      android:scheme="string" />

Uri的格式:scheme://host:port/path or pathPrefix or pathPattern

如果scheme没有指定,那其它的属性均无效;

如果host没有指定,那么port,path,pathPrefix,pathPattern均无效;

如果在manifest里这样写:<data android:scheme="something" android:host="project.example.com" />

那么Uri uri = Uri.parse("something://project.example.com"); 才可以匹配

再如:

<data android:scheme="something" android:host="project.example.com" android:port="80"/>

等同于这样写:

<data android:scheme="something"/>

<data android:host="project.example.com"/>

<data android:port="80"/>

那么Uri uri = Uri.parse("something://project.example.com:80"); 才可以匹配

可以有多个data,只需匹配其中一个即可

<activity android:name=".MyActivityTwo" android:label="@string/activityTwo">

<intent-filter>

             <action android:name="android.intent.action.leo"></action>

                <category android:name="android.intent.category.DEFAULT"></category>

                <data android:scheme="x-id"/>

                <data android:scheme="something"/>

</intent-filter>

</activity>

           Intent in = new Intent();

            in.setAction("android.intent.action.leo");

            in.addCategory(Intent.CATEGORY_DEFAULT);

            in.setData(Uri.parse("something:"));//或者用这个亦可in.setData(Uri.parse("x- id:"));           

            startActivity(in);     

(3)  根据action和data的mimeType属性匹配         

<activity android:name=".MyActivityTwo" android:label="@string/activityTwo">

<intent-filter>

<action android:name="android.intent.action.VIEW"></action>

<data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />

<category android:name="android.intent.category.DEFAULT"></category>

</intent-filter>

</activity>

在java代码里这样写就可以匹配到这个activity:

            Intent in = new Intent();

            in.setAction("android.intent.action.VIEW");

            in.addCategory(Intent.CATEGORY_DEFAULT);//可去掉,Category默认值

            in.setType("vnd.android.cursor.dir/vnd.google.note");

            startActivity(in);            

  单靠data的mimeType属性不能匹配,就算这个mimeType是唯一的也不行,需要有一个action配合,可以有多个 mimeType,在java代码里只需匹配其中一个即可:

  <activity android:name=".MyActivityTwo" android:label="@string/activityTwo">

<intent-filter>

  <intent-filter>

<action android:name="android.intent.action.VIEW"></action>

<data android:mimeType="leo.android.cursor.dir/vnd.google.leo" />

<data android:mimeType="leo.android.cursor.dir/vnd.google.liao" />

<category android:name="android.intent.category.DEFAULT"></category>

</intent-filter>

</activity>

这样可以启动MyActivityTwo这个Activity:

Intent in = new Intent();

            in.setAction("android.intent.action.VIEW");

            in.addCategory(Intent.CATEGORY_DEFAULT);//可去掉,因为Category默认值即系 Intent.CATEGORY_DEFAULT

            in.setType("leo.android.cursor.dir/vnd.google.liao");

            startActivity(in);

      或者这样也可以启动MyActivityTwo这个Activity:  

      Intent in = new Intent();

            in.setAction("android.intent.action.VIEW");

            in.addCategory(Intent.CATEGORY_DEFAULT);//可去掉,因为Category默认值即系 Intent.CATEGORY_DEFAULT

            in.setType("leo.android.cursor.dir/vnd.google.leo");

            startActivity(in);

  scheme和mimeType只能有其中一个,下面这样通不过

  AndroidManifest.xml里:

  <data android:scheme="something" android:host="project.example.com"

android:port="80"

android:mimeType="leo.android.cursor.dir/vnd.google.leo" /> 

<data android:scheme="something" android:host="project.example.com"

android:port="80" />

 <data android:mimeType="leo.android.cursor.dir/vnd.google.leo" />

java代码里:

匹配不上:

Intent in = new Intent();

            in.setAction("android.intent.action.VIEW");

            Uri uri = Uri.parse("something://project.example.com:80");

            in.setData(uri);

            in.setType("leo.android.cursor.dir/vnd.google.leo");

            startActivity(in);                 

            这样还是匹配不上:

            Intent in = new Intent();

            in.setAction("android.intent.action.VIEW");

//            Uri uri = Uri.parse("something://project.example.com:80");

//            in.setData(uri);

            in.setType("leo.android.cursor.dir/vnd.google.leo");

            startActivity(in);

            这样还是匹配不上:

            Intent in = new Intent();

            in.setAction("android.intent.action.VIEW");

            Uri uri = Uri.parse("something://project.example.com:80");

            in.setData(uri);

//            in.setType("leo.android.cursor.dir/vnd.google.leo");

            startActivity(in);

 (4)   一个Activity里可以有多对<intent-filter></intent-filter>  只要匹配其中一对,即可启动这个Activity

全部总结:

1.  <action/>包含在 <intent-filter></intent-filter> 标签对里,而且是必不可少的!不管以哪一种方式来匹配,都不可缺少这个<action/> ,可以有多个,至少要有一个。

如有多个的,话只需要匹配其中一个即可找到这个activity

<action>里的属性值大多数是在Intent里定义的,比如<action android:name="android.intent.action.VIEW"/>里的属性值就等于 Intent.ACTION_VIEW,

在这个Intent类里以ACTION开头定义的常量都是。当然,也可以自定义。 

2.  任何一个需要隐式启动的Activity都必须要有这项:<category android:name="android.intent.category.DEFAULT"/>

例外情况是:android.intent.category.MAIN和android.intent.category.LAUNCHER的 filter中没有必要加入android.intent.category.DEFAULT,当然加入也没有问题 

<category> 里的属性值大多数是在Intent里定义的,比如  <category android:name="android.intent.category.DEFAULT"/>里的属性值就等于 Intent.CATEGORY_DEFAULT,

在这个Intent类里以CATEGORY开头定义的常量都是。当然,也可以自定义。  

3.一个Activity里可以有多对<intent-filter></intent-filter>  只要匹配其中一对,即可启动这个Activity

4.在<intent-filter></intent-filter>里可以有多个<data android:mimeType="xxxx"/>,只需匹配其中一个即可.注意:不可以同时出现第5点的标签对,即下面这条。

5. 在<intent-filter></intent-filter>里可以有多个<data android:scheme="xxxx" android:host="yyyy" android:port="uuu"/>,只需匹配其中一个即可。

语法:

<data android:host="string"

      android:mimeType="string"

       android:path="string"

       android:pathPattern="string"

       android:pathPrefix="string"

       android:port="string"

       android:scheme="string" />

       可以分开写,如:

       <data android:scheme="something" android:host="project.example.com" android:port="80"/>

 等同于这样写:

 <data android:scheme="something"/>

 <data android:host="project.example.com"/>

 <data android:port="80"/>

 在java代码里,Uri的格式:scheme://host:port/path or pathPrefix or pathPattern

 注意:不可以同时出现第4点的标签对,即上面那条。

 6.在<intent-filter></intent-filter>里可以有多个<action android:name="xxxx"> ,只需匹配其中一个即可。

 7.当匹配不上任何Activity的话,会发生异常,跳出对话框:很抱歉...某某应用程序意外停止,请重试。

 8. 上面所说的全部适用于Service和BroadcastReceiver,只需把<activity ...></activity>换成<service ...></service>或<receiver ...></receiver>即可。

 9.刚参考了一下packages\apps\HTMLViewer\AndroidManifest.xml,第4和第5条应该是不冲突才对, 但是实际测试中却是冲突,暂时未到找原因。匹配方式请看:用于打开HTML文件的intent

  在被启动的Activity(本例为MyActivityTwo)里接收数据:

 Intent intent = getIntent();

 String intentCategories = intent.getCategories()

 String intentType = intent.getType();

 Uri uri = intent.getData();

String uriScheme = uri.getScheme();

 String uriPath = uri.getPath();

 String uriHost = uri.getHost();

 String uriEncodedPath = uri.getEncodedPath();

分享到:
评论

相关推荐

    android中隐式intent的使用说明2022优秀文档.pptx

    在 Android 中使用隐式 Intent 需要在 AndroidManifest.xml 文件中,首先被调用的 Activity 要有一个带有 `&lt;intent-filter&gt;` 并且包含 `&lt;action&gt;` 的 Activity,设定它能处理的 Intent,并且 category 设为默认值。...

    android中隐式intent与activity的匹配原则2022优秀文档.pptx

    Android中隐式Intent与Activity的匹配原则2022优秀文档 Android中隐式Intent与Activity的匹配原则是Android系统中的一种机制,用于在Activity之间进行通信和交互。隐式Intent是一种非显式的Intent,可以不指定具体...

    2011.09.07(2)——— android 跨进程通信之隐式intent

    文件列表中的"HelloWorld2"、"HelloWorld"和"HelloWorld3"可能是示例代码的项目,用于演示如何在实际应用中使用隐式Intent进行跨进程通信。这些项目可能包含了一些简单的Activity或Service,展示如何定义Intent过滤...

    android中使用隐式intent完成应用的步骤及核心代码2022优秀文档.pptx

    Android 中使用隐式 Intent 完成应用的步骤及核心代码 Android 中的 Intent 机制是一种在不同组件之间传递请求消息的机制。Intent 可以分为显式 Intent 和隐式 Intent 两种。显式 Intent 是指明确指出了目标组件...

    显式和隐式、过滤器intent的使用

    例如,当你需要从一个Activity启动另一个Activity时,你会使用显式Intent,并指定目标Activity的ComponentName。 ```java Intent intent = new Intent(FirstActivity.this, SecondActivity.class); startActivity...

    android中隐式intent的传递方法2022优秀文档.pptx

    android中隐式intent的传递方法2022优秀文档.pptx

    android中使用显式intent完成应用的步骤及核心代码2022优秀文档.pptx

    "Android中使用显式Intent完成应用的步骤及核心代码" Android中使用显式Intent完成应用的步骤及核心代码是指在Android应用程序中使用显式Intent来实现应用程序之间的交互和跳转。显式Intent是一种明确指出了目标...

    Android中使用隐式Intent完成界面切换的任务说明.pdf

    显式Intent直接指定要启动的组件(Activity或Service)的类名,而隐式Intent则不直接指定目标组件,而是通过设置Action、Data、Category等属性来匹配系统中能够处理该Intent的组件。 在上述任务中,我们需要创建两...

    Android中Intent的详解(显式,隐式,系统,startActivityForResult);

    Intent分为四种主要类型:显式Intent、隐式Intent、系统Intent和使用`startActivityForResult`的Intent。下面将对这四个部分进行详细介绍。 ### 1. 显式Intent 显式Intent是最直接的Intent类型,它们明确地指定要...

    Android中使用隐式Intent完成界面切换的代码清单.pdf

    通过这个简单的示例,我们可以了解如何在Android应用中使用隐式Intent进行界面间的切换。实际开发中,隐式Intent还常用于启动其他组件如Service、BroadcastReceiver,或者执行系统提供的操作如打开网页、发送短信等...

    android中显式intent的使用说明2022优秀文档.pptx

    本篇将详细讲解Android中显式Intent的使用。 首先,显式Intent的定义在于它直接指定了要调用的组件名称。在开发过程中,当开发者确切知道要启动哪个Activity时,会使用显式Intent。这通常发生在同一应用的不同...

    显示Intent和隐式Intent启动Activity的示例

    本示例主要关注如何使用显示Intent和隐式Intent来启动Activity。 1. **显示Intent**: 显示Intent是明确指定目标Activity的Intent,通常在我们知道确切要启动的组件(Activity)时使用。创建显示Intent的代码如下...

    隐式Intent

    在Android开发中,正确理解和使用隐式Intent至关重要,它不仅能帮助开发者实现各种功能,还能促进应用间的协作,提升整体用户体验。而在这个例子中,我们看到隐式Intent如何使简单的任务如发送短信和选择联系人变得...

    Android中intent的使用

    本篇文章将深入探讨Intent的基本概念、类型、构造方法以及如何在Android中有效地使用Intent。 Intent是一种意图声明,表达了应用程序想要执行的操作。在Android系统中,Intent分为显式Intent和隐式Intent两种类型。...

    android----intent

    Intent主要有两种类型:显式Intent和隐式Intent。显式Intent通过指定组件的完整类名来直接启动特定的Activity或Service。而隐式Intent则是通过设定Action、Data、Category等元数据,让系统根据这些信息寻找能够处理...

    android用于打开各种文件的intent.pdf

    Android 中使用 Intent 打开各种文件类型 Android 操作系统提供了 Intent 机制,允许应用程序之间进行交互和通信。Intent 是一个异步的消息机制,用于在应用程序之间请求或提供服务。通过使用 Intent,可以实现打开...

    android中intent使用示例

    显式Intent通过指定组件的全名(包括包名和类名)来直接启动目标组件,而隐式Intent则是通过设置Action、Data、Category等元数据来匹配能够处理该Intent的组件。 1. 显式Intent的使用: 在创建显式Intent时,我们...

    安卓Android源码——Intent_DataSample.rar

    1. **Intent的基本构造**:创建Intent对象时,通常需要指定目标组件(如果使用显式Intent)或者动作和数据类型(如果使用隐式Intent)。 2. **数据传递**:Intent 提供了putExtra()方法来添加键值对数据,如字符串...

    Android中使用隐式Intent完成猜数游戏的代码清单.pdf

    下面我们将详细讨论如何在Android中使用隐式Intent来完成这个游戏。 首先,我们来看MainActivity的代码。MainActivity是游戏的起点,用户在这里点击数字图片进行猜数。每个图片(img_1到img_9)都有一个对应的点击...

    Android 隐式Intent的实例详解

    Android 隐式Intent 的实例详解还可以帮助我们更好地理解隐式Intent 的机制和应用场景,从而更好地使用隐式Intent 来实现我们的需求。 Android 隐式Intent 的实例详解还可以帮助我们更好地理解 Android 的意图...

Global site tag (gtag.js) - Google Analytics