尝试使用Ant构建Android应用程序时会抛出ExceptionWithContext

Ale*_*lex 22 ant android dex

我已经尝试在谷歌和stackoverflow上搜索这个问题的答案,但我一直无法找到任何有我确切问题的人.每次有人在源代码管理中进行更改时,我都会尝试设置一个持续集成服务器(特别是Bamboo)来更新,构建和导出APK.当我使用我设置的工作时,当我每一步手动操作时,我在本地机器上遇到同样的错误.当我到达构建的dex步骤时会发生错误.到目前为止,与我已经得到了相同的输出ant debug,ant release,ant clean debug,和ant clean release.整个dex步骤的输出完成有错误,如下所示:

-dex:
      [dex] input: C:\Users\...\Android\bin\classes
      [dex] input: C:\Users\...\google-play-services_lib\bin\classes.jar
      [dex] input: C:\Program Files (x86)\Android\android-sdk\tools\support\annotations.jar
      [dex] input: C:\Users\...\Android\libs\FlurryAgent.jar
      [dex] input: C:\Users\...\Android\libs\gcm.jar
      [dex] input: C:\Users\...\Android\libs\android-support-v4.jar
      [dex] input: C:\Users\...\google-play-services_lib\libs\google-play-services.jar
      [dex] Pre-Dexing C:\Users\...\google-play-services_lib\bin\classes.jar -> classes-64c0adfe92ddc950c7ab8c5002ceabf2.jar
      [dex] Pre-Dexing C:\Program Files (x86)\Android\android-sdk\tools\support\annotations.jar -> annotations-62bab95d6948a2db17bbc7976160b014.jar
      [dex] Pre-Dexing C:\Users\...\Android\libs\FlurryAgent.jar -> FlurryAgent-499d43756a3ce626a64773e6dfd5eaec.jar
      [dex] Pre-Dexing C:\Users\...\Android\libs\gcm.jar -> gcm-ae2640f44640eb4fd7b13964b65d2d70.jar
      [dex] Pre-Dexing C:\Users\...\Android\libs\android-support-v4.jar -> android-support-v4-fa30b373a3e3ba9f2cf94900a9eb42fe.jar
      [dex] Pre-Dexing C:\Users\...\google-play-services_lib\libs\google-play-services.jar -> google-play-services-9efad6e9178399c185fae6c0b6bdc4c6.jar
      [dex] Converting compiled files and external libraries into C:\Users\...\Android\bin\classes.dex...
       [dx]
       [dx] UNEXPECTED TOP-LEVEL EXCEPTION:
       [dx] com.android.dx.util.ExceptionWithContext
       [dx]     at com.android.dx.util.ExceptionWithContext.withContext(ExceptionWithContext.java:46)
       [dx]     at com.android.dx.dex.cf.CfTranslator.processMethods(CfTranslator.java:344)
       [dx]     at com.android.dx.dex.cf.CfTranslator.translate0(CfTranslator.java:134)
       [dx]     at com.android.dx.dex.cf.CfTranslator.translate(CfTranslator.java:87)
       [dx]     at com.android.dx.command.dexer.Main.processClass(Main.java:487)
       [dx]     at com.android.dx.command.dexer.Main.processFileBytes(Main.java:459)
       [dx]     at com.android.dx.command.dexer.Main.access$400(Main.java:67)
       [dx]     at com.android.dx.command.dexer.Main$1.processFileBytes(Main.java:398)
       [dx]     at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:135)
       [dx]     at com.android.dx.cf.direct.ClassPathOpener.processDirectory(ClassPathOpener.java:191)
       [dx]     at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:123)
       [dx]     at com.android.dx.cf.direct.ClassPathOpener.processDirectory(ClassPathOpener.java:191)
       [dx]     at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:123)
       [dx]     at com.android.dx.cf.direct.ClassPathOpener.processDirectory(ClassPathOpener.java:191)
       [dx]     at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:123)
       [dx]     at com.android.dx.cf.direct.ClassPathOpener.processDirectory(ClassPathOpener.java:191)
       [dx]     at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:123)
       [dx]     at com.android.dx.cf.direct.ClassPathOpener.processDirectory(ClassPathOpener.java:191)
       [dx]     at com.android.dx.cf.direct.ClassPathOpener.processOne(ClassPathOpener.java:123)
       [dx]     at com.android.dx.cf.direct.ClassPathOpener.process(ClassPathOpener.java:109)
       [dx]     at com.android.dx.command.dexer.Main.processOne(Main.java:422)
       [dx]     at com.android.dx.command.dexer.Main.processAllFiles(Main.java:333)
       [dx]     at com.android.dx.command.dexer.Main.run(Main.java:209)
       [dx]     at com.android.dx.command.dexer.Main.main(Main.java:174)
       [dx]     at com.android.dx.command.Main.main(Main.java:91)
       [dx] Caused by: java.lang.NullPointerException
       [dx]     at com.android.dx.cf.code.ConcreteMethod.<init>(ConcreteMethod.java:87)
       [dx]     at com.android.dx.cf.code.ConcreteMethod.<init>(ConcreteMethod.java:75)
       [dx]     at com.android.dx.dex.cf.CfTranslator.processMethods(CfTranslator.java:247)
       [dx]     ... 23 more
       [dx] ...while processing <init> (Lcom/.../android/LocationService;)V
       [dx] ...while processing com/.../android/LocationService$1.class
       [dx]
       [dx] 1 error; aborting
Run Code Online (Sandbox Code Playgroud)

对于上下文,我在Windows机器上使用Ant v1.9.2和Android build-tools v18.0.1,我没有以任何方式编辑构建脚本.我android update project --path .在他们的两个目录中为app生成了一个,为库生成了一个.我还没有尝试过将其设置为自动使用正确的密钥库进行签名,尽管我的(有限的)理解不应该是必要的,至少不是用于使用Ant的调试构建.

以前有人见过这个特别的问题吗?这是生成的.class文件的问题吗?构建文件?这是我第一次尝试使用Ant进行构建(我通常只是让Eclipse为我做了所有艰苦的工作),所以我很少继续.任何帮助将非常感激.

更新:如果有人关注这个问题,我的问题似乎已经解决了.怎么以及为什么,我不知道.我今天早上尝试更新了源代码(我们进行了一些更改),重新android update project -p .尝试了ant clean debug,然后尝试了,看,它有效.就像那样ant release,甚至用我给它的钥匙正确签名.我最好的猜测是,在LocationService类文件中有一些奇怪的东西,尽管它超出了我的范围.

更新2:我在第一次更新中说的任何内容现在都无效.我已经解决了这个问题,但我并没有更接近理解它.这段代码是罪魁祸首:

if (Settings.DEBUG) {
    Thread.currentThread().setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
        @Override
        public void uncaughtException(Thread thread, Throwable ex) {
            storeDebugNotification(AndroidUncaughtExceptionHandler.getStackTraceString(ex));
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

事情变得奇怪了.当Settings.DEBUG标志是true,这与蚂蚁建立良好.什么时候false,它失败了,给我上面显示的错误.当我评论整个事情时,它适用于任何DEBUG设置.对于if (Settings.DEBUG)线条及其花括号进行注释但身体保持完整,以及对身体进行评论并单独留下if部分也是如此.所以......我在这里不知所措.关于if语句和正文之间的交互,在这个特定的文件中,当DEBUG为false时会导致问题.另一个奇怪的部分是,如果在应用程序中的另一个文件中的(一个活动,而这个是服务),我们就完全相同.

Alb*_*ees 36

在编译项目以供发布时,我遇到了同样的异常.我的代码是:

if (BuildConfig.DEBUG) {
    myView.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // Do something
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

因为BuildConfig.DEBUG是一个值为false的常量,所以块中的代码被识别为死代码并在优化时被删除.

CfTranslator(文件转换器)想要为块内的匿名类创建一个单独的文件(SomeClass $ 1.class),但由于它已被优化,因此会发生错误.我把花括号外面的匿名类解决了问题:

View.OnClickListener lClickListener = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        // Do something
    }
};

if (BuildConfig.DEBUG) {
    myView.setOnClickListener(lClickListener);
}
Run Code Online (Sandbox Code Playgroud)

更新:解决此问题的另一种方法(@Ewoks在下面的答案中描述)是:

public boolean isInDeveloperMode() {
    return BuildConfig.DEBUG;
}

...

if (isInDeveloperMode()) {
    myView.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // Do something
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个非常引人注目的解释,我真的希望接受它作为答案,但仍有一块未解释.在一个单独的文件中,我们实际上是完全相同的代码块(将处理程序设置为`Settings.DEBUG`条件中的匿名类实现),尽管`uncaughtException()`覆盖的主体略有不同,并且不会造成任何问题.你能想出为什么那个人会工作而另一个没有的原因吗? (2认同)
  • 也为我工作过.奇怪的是,在Gradle 2.1之前,它对我来说并不是一个问题 (2认同)

小智 9

经过几个月的斗争这个确切的问题,我终于找到了一个适合我的解决方案.可能不是你的情况.确保您所引用的类(可能是设置?也许是AndroidUncaughtExceptionHandler?)都不是私有的.Gradle无法处理它,也无法在类中找到该方法.只需将其更改为public(或者只是删除标志以保持默认,如果类是嵌套的),那么你应该好好去.