简体   繁体   English

NoClassDefFoundError仅某些设备,仅来自playstore? 这有可能吗?

[英]NoClassDefFoundError only some devices, only from playstore? is this even possible?

This problem is like a logic puzzle. 这个问题就像一个逻辑难题。 you have been warned. 你被警告了。

I'm working on a library that is integrated to other apps. 我正在与其他应用程序集成的库中工作。 One person complained that they are seeing crashes from only SOME of their users: 一个人抱怨说,他们只看到部分用户的崩溃:

java.lang.NoClassDefFoundError: com.somecompany.subpackage.SomeAsyncTaskSubclass
at com.somecompany.subpackage.ClassA.instantiateInstanceOfSomeAsyncTaskSubclass(ClassA.java:105)
at
com.somecompany.subpackage.Blah.loadsomedata(MyController.java:180)
at com.somecompany.subpackage.Blah.loadsomemoredata(MyController.java:164)
at com.somecompany.subpackage.SomeView.loadsomemoredata(SomeView.java:213)
com.other.blah.Blah.preloadstuff(Blah.java:118)
at
com.other.blah.Controller.loadSomething(Controller.java:100)
at
com.other.blah.Controller.preloadSomething(Controller.java:144)
at org.cocos2dx.lib.Cocos2dxRenderer.nativeRender(Native Method)
at org.cocos2dx.lib.Cocos2dxRenderer.onDrawFrame(Cocos2dxRenderer.java:94)
at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1332)
at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1116)

and the line of code where the crash is happening is at: 发生崩溃的代码行位于:

public class ClassA {
    public void instantiateInstanceOfSomeAsyncTaskSubclass(){
        SomeAsyncTaskSubclass crashHere = new SomeAsyncTaskSubclass(); //<--- this is where it crashes
    }
}

and in the same package, there is... 在同一个包装中,有...

class SomeAsyncTaskSubclass extends AsyncTask<String, Void, SomeCustomObject> {
// some code here...
}

Here is what I've been told or i know: 这是我被告知或我知道的:

  1. this crash only happens on some users. 此崩溃仅发生在某些用户上。 (but based on Google Play crash reporting. so is that just not accurate? or is the sample generated too slowly?) (但基于Google Play崩溃报告。那是不准确吗?还是样本生成太慢?)

  2. the developer cant reproduce this error in house, even with a signed build. 即使使用已签名的版本,开发人员也无法在内部重现此错误。 (i've checked the signed build and dedexed it to see that the class exists in the src, so i believe him) (我检查了签名的构建并对其进行了删除处理,以查看该类存在于src中,因此我相信他)

  3. but when the app was live on the play store, and people downloaded his new version, he suddenly saw crash reports from some people, believed to be mostly devices 2.3.x though this is unconfirmed) 但是当该应用程序在Play商店中上线并且人们下载了他的新版本时,他突然看到了一些人的崩溃报告,据信主要是设备2.3.x,尽管尚未证实)

  4. he claims he updated to "api 17". 他声称自己已更新为“ api 17”。 when people say that, do they mean build target 17? 当人们这么说时,是指建立目标17吗? or do people mean updating to ADT 17? 还是人们意味着要更新到ADT 17? because i've known ADT mucking up the lib/libs folder issue. 因为我知道ADT会处理lib / libs文件夹问题。

  5. he seems to be using eclipse. 他似乎正在使用日食。

  6. he is calling my code from cocos2d-x for Android, by doing a handler.post() 他正在通过执行handler.post()从Android的cocos2d-x调用我的代码

How is this even possible? 这怎么可能?

I'm confused on why only SOME of the users are seeing NoClassDefFoundError ?? 我对为什么只有部分用户看到NoClassDefFoundError感到困惑? Is that a huge google play crash reporting issue? 那是一个巨大的Google Play崩溃报告问题吗? like, were all users seeing it, but then google play says only some of the users were seeing this issue? 例如,所有用户都看到了此问题,但随后Google Play说只有部分用户看到了此问题? (i haven't verified with the developer, but im fairly certain he tested by downloading a live version from the Play store and he didn't see any errors, and that piece of code is run fairly ). (我尚未与开发人员进行验证,但是可以肯定地说,他通过从Play商店下载实时版本进行了测试,并且他没有看到任何错误,并且该代码段运行得很好)。

From what i understand, NoClassDefFoundError is only when the class exists via one of the three classloaders, but then at runtime, none of the classloaders can find the particular class. 据我了解, NoClassDefFoundError仅在通过三个类加载器之一存在该类时出现,但是在运行时,没有一个类加载器找不到特定的类。

is this a proguard issue? 这是一个保卫问题吗? i've read that proguard is only run at release time. 我已经了解到proguard仅在发布时运行。

is this an AsyncTask issue? 这是AsyncTask问题吗? i've read that AsyncTasks have to be instantiated the very first time on a UI Thread. 我读过AsyncTasks必须在UI线程上第一次实例化。 although, i'm not sure why that would cause a NoClassDefFoundError . 虽然,我不确定为什么会导致NoClassDefFoundError

any thoughts? 有什么想法吗?

There could be a number of reasons why NoClassDefFoundError could occur in your app like: 导致NoClassDefFoundError出现在您的应用中的原因可能有多种,例如:

  • Having more than 65536 methods in your APK. APK中包含超过65536个方法。 The solution is to enable MultiDEX , which you can following this official Android resource https://developer.android.com/studio/build/multidex#mdex-gradle 解决方案是启用MultiDEX ,您可以按照此官方Android资源https://developer.android.com/studio/build/multidex#mdex-gradle
  • In some cases, enabling MultiDEX is not enough, and you need to declare some of your classes in the primary DEX file. 在某些情况下,仅启用MultiDEX是不够的,您需要在主DEX文件中声明一些类。 Basically you just need to add the missing classes into a file, so they are loaded on app startup as Dean Wild pointed out. 基本上,您只需要将缺少的类添加到文件中,如Dean Wild指出的那样,它们会在应用程序启动时加载。 This is because sometimes the build tools might have troubles doing the calculations of which classes to add. 这是因为有时构建工具在计算要添加的类时可能会遇到麻烦。 Official documentation: https://developer.android.com/studio/build/multidex#keep 官方文档: https : //developer.android.com/studio/build/multidex#keep
  • If you have overridden the Application class to extend it with some custom code, then you might have to inherit from MultiDexApplication class and not from the Application class. 如果您重写了Application类以使用一些自定义代码扩展它,则可能必须从MultiDexApplication类而不是从Application类继承。
  • While testing, if you use the either MonitoringInstrumentation or an AndroidJUnitRunner instrumentation, you won't incur into NoClassDefFoundError , but you might get them otherwise. 在测试过程中,如果您使用MonitoringInstrumentationAndroidJUnitRunner工具,则不会发生NoClassDefFoundError ,但是您可能会得到它们。 If that's the case, then just add the following code in the onCreate() method: 如果是这种情况,则只需在onCreate()方法中添加以下代码:

onCreate() method content: onCreate()方法的内容:

public void onCreate(Bundle arguments) {
    MultiDex.install(getTargetContext());
    super.onCreate(arguments);
}

Build your project against SDK ICS or above. 根据SDK ICS或更高版本构建项目。

they've automatically loaded AsyncTask in ICS+. 他们已经在ICS +中自动加载了AsyncTask。 this was the issue. 这就是问题。

Enabling multidex caused this issue to arise for me. 启用multidex对我来说会引起这个问题。 I needed multidex because I was including the entire google play services library. 我需要multidex,因为我包括了整个Google Play服务库。 By only including the components I needed (GCM in my case), I was able to disable multidex and prevent this issue. 通过仅包含所需的组件(在我的情况下为GCM),我可以禁用multidex并防止出现此问题。

Not a real fix I know, but I think multidex should be avoided if possible from what I have read. 我知道这不是一个真正的解决办法,但我认为,如果可能的话,应该避免阅读多义词。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM