NoClassDefFoundError只有一些设备,只来自playstore?这有可能吗?

时间:2013-08-30 22:35:10

标签: java android classloader google-play noclassdeffounderror

这个问题就像一个逻辑谜题。你被警告了。

我正在开发一个集成到其他应用程序的库。一个人抱怨说他们只看到了一些用户的崩溃:

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)

发生崩溃的代码行位于:

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

并且在同一个包中,有......

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

以下是我被告知或我知道的事情:

  1. 此崩溃只发生在某些用户身上。 (但是基于Google Play崩溃报告。那么是不准确?还是生成的样本太慢?)

  2. 即使使用签名版本,开发人员也无法在内部重现此错误。 (我已经检查了签名的构建并对其进行了dedexed以查看该类存在于src中,所以我相信他)

  3. 但当应用程序在Play商店上线,并且人们下载了他的新版本时,他突然看到一些人的崩溃报告,据信主要是设备2.3.x,虽然这是未经证实的)

  4. 他声称他更新为“api 17”。当人们这么说时,他们是否意味着建立目标17?或者人们是指更新到ADT 17?因为我知道ADT搞砸了lib / libs文件夹问题。

  5. 他好像正在使用eclipse。

  6. 他通过c handler.post()

  7. 从cocos2d-x为Android调用我的代码

    这怎么可能?

    我很困惑为什么只有一些用户看到NoClassDefFoundError?这是一个巨大的谷歌游戏崩溃报告问题?比如,所有用户都看到了它,但谷歌播放说只有部分用户看到了这个问题? (我还没有与开发人员确认,但我相当肯定他通过从Play商店下载实时版本进行测试,他没有看到任何错误,并且这段代码是公平运行的。)

    据我所知,NoClassDefFoundError只有当类通过三个类加载器之一存在时,但是在运行时,没有一个类加载器可以找到特定的类。

    这是一个问题吗?我读过proguard只在发布时运行。

    这是一个AsyncTask问题吗?我已经读过AsyncTasks必须首次在UI线程上实例化。虽然,我不确定为什么会导致NoClassDefFoundError

    有什么想法吗?

3 个答案:

答案 0 :(得分:1)

可能有多种原因导致您的应用中出现 //Get the correct screen size even if the device has a hideable navigation bar (e.g. the Samsung Galaxy S8) View decorView = getWindow().getDecorView(); //if you use this in a fragment, use getActivity before getWindow() Rect r = new Rect(); decorView.getWindowVisibleDisplayFrame(r); int screenHeight = r.bottom; // =2220 on S8 with hidden NavBar and =2076 with enabled NavBar int screenWidth = r.right; // =1080 on S8 ,例如:

  • 您的APK中有超过65536种方法。解决方案是启用NoClassDefFoundError,您可以关注此官方Android资源https://developer.android.com/studio/build/multidex#mdex-gradle
  • 在某些情况下,启用MultiDEX是不够的,您需要在主DEX文件中声明一些类。基本上你只需要将缺少的类添加到文件中,因此它们会在应用程序启动时加载,如Dean Wild指出的那样。这是因为有时构建工具可能会在计算要添加的类时遇到麻烦。官方文件:https://developer.android.com/studio/build/multidex#keep
  • 如果您已覆盖MultiDEX类以使用某些自定义代码对其进行扩展,那么您可能必须从Application类继承,而不是从MultiDexApplication类继承。
  • 在测试时,如果您使用ApplicationMonitoringInstrumentation工具,则不会招致AndroidJUnitRunner,但您可能会得到它们。如果是这种情况,那么只需在NoClassDefFoundError方法中添加以下代码:

onCreate()方法内容:

onCreate()

答案 1 :(得分:0)

针对SDK ICS或更高版本构建您的项目。

他们已经在ICS +中自动加载了AsyncTask。这就是问题所在。

答案 2 :(得分:0)

启用multidex会导致我出现此问题。我需要multidex,因为我包括整个Google Play服务库。通过仅包含我需要的组件(在我的情况下为GCM),我能够禁用multidex并防止出现此问题。

我知道这不是一个真正的修复,但我认为如果可能的话,我应该避免使用multidex。