是否需要覆盖ContentProvider的getType方法?
2012-10-05 09:15
288 查看
是否需要覆盖ContentProvider的getType方法?
不少关于android的书籍都谈到了ContentProvider,而且给了例子,但是对ContentProvider的getType方法则是寥寥数语带过,以至于读者对其作用始终有种雾里看花的感觉。本文从一个侧面谈谈getType的作用,希望对大家有所帮助。本文不再另写例子程序,具体例子可以参考android自带的sample程序notepad。
在notepad app中大家可以看到NotePadProvider覆盖了getType方法,让其返回相应的类型。那么他的作用是什么呢?让我们来看看吧!
首先,改写NotePadProvider的getType方法,让其返回null;然后编译后启动,按下menu key,出现含有add note的menu,点击之。哦哦!出错了,提示“android.content.ActivityNotFoundException: No Activity found to handle Intent”!为什么呢?
且听我从头道来。
首先,大家知道android app的安装是由PM(package manager)负责的,在安装android app时,PM将app中的activities,services,broadcasts和content providers记录下来且为他们建立相应的intent filter,以便后面启动他们时使用。关于intent filter的建立,大家可以参见IntentResolver.java文件的addFilter函数,从此处可以看到它建立了关于scheme,type,action和typedAction的列表。
其次,在点击add note菜单项后,notepad app的处理是startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData()));对应framework的处理是instrumentation.java中的execStartActivity,在其中,大家可以看到
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
null, 0, token, target != null ? target.mEmbeddedID : null,
requestCode, false, false);
哦哦!这里有对intent.resolveTypeIfNeeded(who.getContentResolver())的调用,具体过程不再详述,大家有兴趣的话,可以参考intent.java,代码还是比较简单的。该函数的作用是返回intent对应的MIME type,这个MIME type就是通过调用NotePadProvider的getType方法得来的。
接着来,下面framework将继续调用ActivityManagerService.java中的
startActivity –> startActivityMayWait,这里有很重要的一行代码:
ResolveInfo rInfo =
ActivityThread.getPackageManager().resolveIntent(
intent, resolvedType,
PackageManager.MATCH_DEFAULT_ONLY
| STOCK_PM_FLAGS);
这里就用到了上面PM建立的scheme,type,action和typedAction的列表,由于我们修改了NotePadProvider的getType方法,让其返回null,所以这里参数resolvedType值为null,以至于PM无法为其找到匹配的ResolverInfo,那么下面的代码:
if (aInfo != null) {
// Store the found target back into the intent, because now that
// we have it we never want to do this again. For example, if the
// user navigates back to this point in the history, we should
// always restart the exact same activity.
intent.setComponent(new ComponentName(
aInfo.applicationInfo.packageName, aInfo.name));
// Don't debug things in the system process
if (debug) {
if (!aInfo.processName.equals("system")) {
setDebugApp(aInfo.processName, true, false);
}
}
}
将无法执行,所以intent不能设置与其相应的Component(也就是和intent相关的activity的信息),因此“android.content.ActivityNotFoundException: No Activity found to handle Intent”出现了!
结论:覆盖ContentProvider的getType方法对于用new Intent(String action, Uri uri)方法启动activity是很重要的,如果它返回的MIME type和activity在<intent filter>中定义的data的MIME type不一致,将造成activity无法启动。
来源:http://blog.csdn.net/imyfriend/article/details/6589917
不少关于android的书籍都谈到了ContentProvider,而且给了例子,但是对ContentProvider的getType方法则是寥寥数语带过,以至于读者对其作用始终有种雾里看花的感觉。本文从一个侧面谈谈getType的作用,希望对大家有所帮助。本文不再另写例子程序,具体例子可以参考android自带的sample程序notepad。
在notepad app中大家可以看到NotePadProvider覆盖了getType方法,让其返回相应的类型。那么他的作用是什么呢?让我们来看看吧!
首先,改写NotePadProvider的getType方法,让其返回null;然后编译后启动,按下menu key,出现含有add note的menu,点击之。哦哦!出错了,提示“android.content.ActivityNotFoundException: No Activity found to handle Intent”!为什么呢?
且听我从头道来。
首先,大家知道android app的安装是由PM(package manager)负责的,在安装android app时,PM将app中的activities,services,broadcasts和content providers记录下来且为他们建立相应的intent filter,以便后面启动他们时使用。关于intent filter的建立,大家可以参见IntentResolver.java文件的addFilter函数,从此处可以看到它建立了关于scheme,type,action和typedAction的列表。
其次,在点击add note菜单项后,notepad app的处理是startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData()));对应framework的处理是instrumentation.java中的execStartActivity,在其中,大家可以看到
int result = ActivityManagerNative.getDefault()
.startActivity(whoThread, intent,
intent.resolveTypeIfNeeded(who.getContentResolver()),
null, 0, token, target != null ? target.mEmbeddedID : null,
requestCode, false, false);
哦哦!这里有对intent.resolveTypeIfNeeded(who.getContentResolver())的调用,具体过程不再详述,大家有兴趣的话,可以参考intent.java,代码还是比较简单的。该函数的作用是返回intent对应的MIME type,这个MIME type就是通过调用NotePadProvider的getType方法得来的。
接着来,下面framework将继续调用ActivityManagerService.java中的
startActivity –> startActivityMayWait,这里有很重要的一行代码:
ResolveInfo rInfo =
ActivityThread.getPackageManager().resolveIntent(
intent, resolvedType,
PackageManager.MATCH_DEFAULT_ONLY
| STOCK_PM_FLAGS);
这里就用到了上面PM建立的scheme,type,action和typedAction的列表,由于我们修改了NotePadProvider的getType方法,让其返回null,所以这里参数resolvedType值为null,以至于PM无法为其找到匹配的ResolverInfo,那么下面的代码:
if (aInfo != null) {
// Store the found target back into the intent, because now that
// we have it we never want to do this again. For example, if the
// user navigates back to this point in the history, we should
// always restart the exact same activity.
intent.setComponent(new ComponentName(
aInfo.applicationInfo.packageName, aInfo.name));
// Don't debug things in the system process
if (debug) {
if (!aInfo.processName.equals("system")) {
setDebugApp(aInfo.processName, true, false);
}
}
}
将无法执行,所以intent不能设置与其相应的Component(也就是和intent相关的activity的信息),因此“android.content.ActivityNotFoundException: No Activity found to handle Intent”出现了!
结论:覆盖ContentProvider的getType方法对于用new Intent(String action, Uri uri)方法启动activity是很重要的,如果它返回的MIME type和activity在<intent filter>中定义的data的MIME type不一致,将造成activity无法启动。
来源:http://blog.csdn.net/imyfriend/article/details/6589917
相关文章推荐
- 是否需要覆盖ContentProvider的getType方法?
- 是否需要覆盖ContentProvider的getType方法?
- Linux安装MySQL的两种方法{linux系统mysql安装之前需要先检查是否已经安装,把已经有的库文件卸载掉,否则会出现覆盖错误}
- jaxp使用初级入门(只需要两个步骤,覆盖五个方法)
- C#中判断一个方法是否覆盖(override)了父类的方法
- 是否需要主动调用Bitmap的recycle方法?
- 是否需要手动执行DataContext的Dispose方法?
- C# 在两个不同的方法里面Lock同一个锁对象,是否需要线程等待?
- Struts2中Action中是否需要实现Execute方法
- 第一次安装android sdk后进行开发包的更新,你应该了解到需要的时间会很长,那么是否有办法提升安装的进度呢?办法自然是有的,这里提供一个取巧的方法,不会太麻烦,又能加快android开发环境的部
- 重写函数的Equals方法,来确定需要比较类是否相同的条件
- oc经常提到的静态方法中返回的对象,是否需要进行reless操作。
- C# 检查网络是否连通 判断远程文件是否存在 C#获取程序路径的方法中需要注意的地方
- static关键字是什么意思?java中是否可以覆盖一个private方法或者static方法
- ContentProvider onCreate()方法及ContentProvider.getContext()需要注意
- 被PrintStream包装的FileOutputStream在PrintStream调用close()后是否需要单独调用自己的close()方法关闭
- 是否需要手动执行DataContext的Dispose方法?
- 是否需要手动执行DataContext的Dispose方法?
- 实时数据库的历史数据是否需要进行压缩?可用什么方法压缩?
- SQLiteDatabase 是否需要调用close()方法?什么时候调用?