无法获取提供程序:ClassNotFoundException

时间:2012-10-10 17:10:18

标签: android android-contentprovider proguard

我的应用程序中有MyContentProvider,当我在调试模式下开发和运行时,它可以正常工作。

<provider android:name=".MyContentProvider"
        android:authorities="com.contactcities"
        android:exported="false">
</provider>

但是当我导出应用程序,下载并运行它时,它会立即崩溃:

10-10 18:24:37.682 E/AndroidRuntime(10428): FATAL EXCEPTION: main
10-10 18:24:37.682 E/AndroidRuntime(10428): java.lang.RuntimeException: Unable to get provider com.contactcities.MyContentProvider: java.lang.ClassNotFoundException: com.contactcities.MyContentProvider in loader dalvik.system.PathClassLoader[/system/framework/com.google.android.maps.jar:/data/app/com.contactcities-1.apk]
10-10 18:24:37.682 E/AndroidRuntime(10428): at android.app.ActivityThread.installProvider(ActivityThread.java:4509)
10-10 18:24:37.682 E/AndroidRuntime(10428): at android.app.ActivityThread.installContentProviders(ActivityThread.java:4281)
10-10 18:24:37.682 E/AndroidRuntime(10428): at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4237)
10-10 18:24:37.682 E/AndroidRuntime(10428): at android.app.ActivityThread.access$3000(ActivityThread.java:125)
10-10 18:24:37.682 E/AndroidRuntime(10428): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2071)
10-10 18:24:37.682 E/AndroidRuntime(10428): at android.os.Handler.dispatchMessage(Handler.java:99)
10-10 18:24:37.682 E/AndroidRuntime(10428): at android.os.Looper.loop(Looper.java:123)

我可以在我的所有设备上重现它,2.2,4.0,4.1

我今天阅读了很多帖子。其中一些人指责ProGuard。 我试过添加

-keep public class com.contactcities.MyContentProvider

但没有运气。

当我停用proguard时,不要将proguard.config=proguard.cfg放入我的project.properties。它仍然在发布版本中提供相同的错误。调试再次没问题。 也许它不足以像那样禁用proguard?

也许暗示是它在这次崩溃中引用了maps.jar。我不知道为什么会这样做

in loader dalvik.system.PathClassLoader[/system/framework/com.google.android.maps.jar

非常感谢任何线索

5 个答案:

答案 0 :(得分:3)

Argh,以为我试过了,但似乎我没有。

Project - &gt; clean让它发挥作用

面掌

答案 1 :(得分:1)

我收到同样的错误,结果我在 AndroidManifest.xml 中的提供者标记的android:name属性值错误:

<provider
    android:authorities="com.example.ProviderClass"
    android:name=".ProviderClass"
    android:exported="false" >
</provider>

因此请仔细检查此值是否高于.ProviderClass或类别名称(以点为前缀)。然后做Project&gt;干净,它会工作。

答案 2 :(得分:1)

authority属性需要匹配内容权限,而name属性需要与Custom Provider类的类名匹配。

例如:

      <provider
         android:authorities="com.richa.myapp"
         android:name=".data.CustomProvider"/>

答案 3 :(得分:0)

也许我的缺乏经验会帮助其他人解决这个问题。这对我来说是完全神秘的,但是就像你知道的那样,计算机中的一切都很明显。

我正在学习本教程,这总体上非常好: http://www.vogella.com/tutorials/AndroidSQLite/article.html

早些时候,他说要创建一个名为&#34; contentprovider&#34;然后是其中的一个课程&#34; MyTodoContentProvider&#34;。现在任何熟悉Java风格命名约定的人都会看到这应该是相对于主包的。但我对这一切都很陌生,所以我在某处创造了它。

通过构建代码,一切正常。 Eclipse找到并包含此包,并且没有显示任何错误。然后崩溃和神秘的&#34;无法获得提供者&#34;信息。错误消息中的路径,我现在理解的是代码正在寻找类的不存在的路径,它是如此之长并包含了很多迭代的内容提供者&#34;很难看出它所指的是什么或它有什么问题。

我怀疑问题出在清单文件中,但我确信它出现在&#34; android:authority&#34;中。这有点不直观。清单中此元素中的字符串对应于您在提供程序类中公开的公共成员。该成员名为&#34; CONTENT_URI&#34;。但两者并不完全匹配。例如:

private static final String AUTHORITY = "com.vegnab.provider";
private static final String BASE_PATH = "todos";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH);

这最终得到:

CONTENT_URI = "content://com.vegnab.provider/todos"

(请注意,AUTHORITY本身是私人会员,不在外部。)

相应的清单行将是:

android:authorities="com.vegnab.provider"

这是方案&#34; content://&#34;之间的中间部分。和基本路径。

问题实际上在清单行中:

android:name=".contentprovider.MyTodoContentProvider"

我有一个名为&#34; MyTodoContentProvider&#34;的错误类。在名为&#34; contentprovider&#34;的软件包中,问题是什么?问题是包裹在错误的地方。它应该是相对于主要包裹。这就是名字中的第一个点,意思是什么。它应该遵循与&#34; android:name&#34;相同的语法。活动的各个部分,在清单的各个部分。

如果您觉得这很有用,请一次性使用。一旦你解决了这个问题,很容易忘记它是多么神秘。

答案 4 :(得分:0)

在Android 5.0(API级别21)将ART替换为DEX运行时之前,您可能已经在旧版操作系统上传递了类限制。如果您处于限制的边缘,则可以通过编译,但在启动期间会出现此错误。

尝试按照Android Enable Multidex for Apps with Over 64K Methods文档中的说明启用multi-dex。