之前学android时,隐式Intent感觉挺简单的,于是就没有深究。最近在看第三方登陆时,突然想到隐式Intent的作用,就来研究了下用法,没想到踩了很多的坑,用了一个上午的时间才找出问题所在。不管怎么说,把这些问题记下来,以后少走点弯路!
先给出一个讲隐式Intent的博客地址:https://blog.csdn.net/qq_32059827/article/details/53819775,博主讲的很好很全面,没有使用过隐式Intent的同学可以参考参考,我踩得坑很多都在这里找到了答案,这里有的,我就不详细说了。直接进正题!
1.只要你想通过Intent隐式启动活动(以活动为例),就必须在<intent-filter.../>元素内添加<action.../>和<category.../>元素,不管你是通过setAction()和addCategory()方法设置隐式启动还是setData()方法启动还是setType()方法启动!这个血的教训啊!!下面提供两个错!误!示!例!
<activity android:name=".DataTest">
<intent-filter>
<data android:scheme="cam"
android:host="cam.cam.cam"
android:port="8888"
/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="cam"/>
<data android:mimeType="cam/cam"/>
</intent-filter>
</activity>
这个活动设置了两个<intent-filter.../>元素,所以我们有两种隐式启动这个Activity的方法,但是第一个<intent-filter.../>元素缺少了<action.../>元素,第二个<intent-filter.../>元素缺少了<category.../>元素,稍后我们将看到,尽管我们的代码中并没有用到setAction()方法和addCategory()方法,但这两个子元素却并不能省略。
首先,我们用setData()方法隐式启动对应第一个<intent-filter.../>,代码如下:
Intent intent=new Intent();
intent.setData(Uri.parse("cam://cam.cam.cam:8888"));
startActivity(intent);
运行闪退,报错如下:
android.content.ActivityNotFoundException: No Activity found to handle Intent { dat=cam://cam.cam.cam:8888 }
这是最坑的,异常提示的是找不到该Intent对应的活动,但是我们的<data.../>明明能完美对应,对着这几行代码干瞪眼却不知道该怎么办。
然后,我们用setType方法隐式启动对应第二个<intent-filter.../>,代码如下:
Intent intent=new Intent();
intent.setType("cam/cam");
startActivity(intent);
运行结果如下:
根本没有我们想要打开的活动,当然,你的程序没有报错,但是不对,而你连问题在哪都不知道。
正确的<intent-filter.../>如下:
<activity android:name=".DataTest">
<intent-filter>
<action android:name="你可以瞎写,反正没用到"/>
<data android:scheme="cam"
android:host="cam.cam.cam"
android:port="8888"
/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="cam"/>
<data android:mimeType="cam/cam"/>
<!--默认的category,每个filter都必须要有-->
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
使用上面的启动代码可以打开这个活动(ps:本来启动方式和错误方式的排列组合应该有四条的,但是结果大同小异,读者自行实验吧)。总之,只要你想用隐式的Intent打开活动,<action.../>元素和<category.../>元素必不可少!
2.只要使用隐式Intent,<intent-filter.../>元素中,<category android:name="android.intent.category.DEFAULT"/>这行代码必不可少,不管你有没有定义自己的category,原因在推荐的博客中已经讲过了,源码中会自动给Intent添加这个category。相信这个坑很多人都踩过,就不提供错误示范了。
3.setData()和setType()互相覆盖,推荐的博客中讲的很详细,在此略过。
暂时就这么多,以后还有坑就再补充。