25

Google と stackoverflow の両方でこれに対する答えを探してみましたが、私が抱えている問題とまったく同じ問題を抱えている人を見つけることができませんでした。誰かがソース管理に変更を加えるたびに APK を更新、ビルド、およびエクスポートするために、継続的インテグレーション サーバー (具体的には、Bamboo) をセットアップしようとしています。すべての手順を手動で行うときのローカル マシンと、設定したジョブを使用するときのサーバーの両方で、同じエラーが発生します。ビルドの dex ステップに到達すると、エラーが発生します。これまでのところ、ant debugant releaseant 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

コンテキストとして、私は Windows マシンで Ant v1.9.2 と Android build-tools v18.0.1 を使用しており、ビルド スクリプトをまったく編集していません。アプリ用に 1 つandroid update project --path .、2 つのディレクトリを使用するライブラリ用に 1 つ生成しました。また、署名に適切なキーストアを自動的に使用するように設定することはまだ試していませんが、少なくとも 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 部分をそのままにしておく場合にも当てはまります。だから…ここで途方に暮れています。この特定のファイルでは、 if ステートメントと本文の間の相互作用に関する何かが、DEBUGfalse の場合に問題を引き起こしています。もう 1 つの奇妙な点は、アプリ内の別のファイルにまったく同じ if ブロックがあることです (これはアクティビティですが、これはサービスです)。

4

3 に答える 3

39

リリース用のプロジェクトをコンパイルしているときに、同じ例外がありました。私のコードは次のとおりです。

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

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

BuildConfig.DEBUGは値がfalseの定数であるため、ブロック内のコードはデッド コードとして認識され、最適化されると削除されます。

CfTranslator (Classfile Translator) は、ブロック内の無名クラス( 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
        }
    });
}
于 2014-02-25T09:41:58.683 に答える
10

この正確な問題と何ヶ月も戦った後、私はついに自分に合った解決策を見つけました. それはあなたの場合ではないかもしれません。参照しているクラス (おそらく設定? AndroidUncaughtExceptionHandler?) がプライベートでないことを確認してください。Gradle はそれを処理できず、クラス内でメソッドを見つけることができません。それをパブリックに変更するだけです(または、クラスがネストされている場合は、フラグを削除してデフォルトのままにします)。

于 2014-01-17T15:42:32.437 に答える