【问题标题】:ExceptionWithContext gets thrown when trying to build an Android app with Ant尝试使用 Ant 构建 Android 应用程序时抛出 ExceptionWithContext
【发布时间】:2013-09-01 03:12:21
【问题描述】:

我已尝试在 Google 和 stackoverflow 上搜索此问题的答案,但我一直无法找到与我遇到的确切问题相关的任何人。我正在尝试设置一个持续集成服务器(特别是 Bamboo),以在每次有人更改源代码控制时更新、构建和导出 APK。当我手动执行每一步时,我在本地机器上和使用我设置的作业时在服务器上都遇到了同样的错误。当我到达构建的 dex 步骤时会发生错误。到目前为止,我使用ant debugant releaseant clean debugant 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

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

这就是事情变得奇怪的地方。当Settings.DEBUG 标志为true 时,这与ant 配合得很好。当它是false 时,它会失败,给我上面显示的错误。当我将整件事评论出来时,它适用于 DEBUG 设置。 if (Settings.DEBUG) 行及其花括号注释但主体保持不变,以及注释主体并单独留下 if 部分也是如此。所以......我在这里不知所措。当 DEBUG 为 false 时,在这个特定文件中,关于 if 语句和正文之间的交互的某些事情会导致问题。另一个奇怪的部分是我们在应用程序的另一个文件(一个活动,而这个是一个服务)中拥有 完全相同的 if 块

【问题讨论】:

  • 您使用的是哪个版本的构建工具?我正在使用构建工具 18.0.1。和 ant 1.8.4 在 mac 上并且不会出错
  • 我正在使用 build-tools 版本 18.0.1 并且正在 Windows 机器上执行此操作。我会更新问题以包含该信息。
  • 可能只是创建一个 hello world 并尝试使用 ant 构建它
  • 一个简单的 Hello World 应用程序有效。我在 Eclipse 中创建了一个新项目(有趣的是,它为您创建的默认活动只显示“Hello World!”)并通过相同的过程运行它(android update project path -- .ant clean debug)。构建成功,我可以在手机上安装和运行它,没有问题。

标签: android ant dex


【解决方案1】:

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

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

        @Override
        public void onClick(View v) {
            // Do something
        }
    });
}

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

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

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

if (BuildConfig.DEBUG) {
    myView.setOnClickListener(lClickListener);
}

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

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

...

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

        @Override
        public void onClick(View v) {
            // Do something
        }
    });
}

【讨论】:

  • 这是一个非常有说服力的解释,我真的接受它作为答案,但还有一点无法解释。在一个单独的文件中,我们实际上有完全相同的代码块(将处理程序设置为 Settings.DEBUG 条件内的匿名类实现),尽管 uncaughtException() 覆盖的主体略有不同,并且不会导致任何问题。你能想出一个为什么会起作用而另一个不起作用的任何原因吗?
  • 也为我工作。奇怪的是,直到 gradle 2.1 对我来说这不是问题
  • 哇,这正是我想要的——if(BuildConfig.DEBUG) 后面的匿名类。使用 Android Gradle 插件 1.0.1
  • 太棒了。为我工作。
  • 我想知道它是否是 gradle 2.1,但我们在其他人中有完全相同的类型块,它只是在那里很好,除了具有内联方法的组件是第三方库,Apptimize 里面有一些东西可能会引发异常。
【解决方案2】:

在解决这个确切问题数月之后,我终于找到了适合我的解决方案。这可能不是你的情况。确保您所指的所有类(可能是设置?可能是 AndroidUncaughtExceptionHandler?)都不是私有的。 Gradle 无法处理它并且无法在类中找到方法。只需将其更改为 public (或删除标志以保持默认,如果类是嵌套的),你应该很高兴。

【讨论】:

【解决方案3】:

@Albert-Jan 提出的其他解决方案是在方法中“包装”该常量。像

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

在这种情况下,gradle 不会将其“解析”为常量,并且在构建期间不会出现问题。

这种方法最著名的“利用”可能是 Android SDK 中 UserManager 类的 isUserAGoat() 方法。有very popular discussion here关于这种方法的可能用途..享受;)

希望这对有类似问题的人有用

【讨论】:

  • 我有一个类似的常数,这样做解决了这个问题。谢谢。
猜你喜欢
  • 2019-04-02
  • 2022-07-30
  • 1970-01-01
  • 2015-07-15
  • 1970-01-01
  • 2012-01-14
  • 1970-01-01
  • 2018-08-12
  • 1970-01-01
相关资源
最近更新 更多