9

C ++では、通常、2つのビルドをセットアップします。デバッグとリリースで、それぞれDEBUGRELEASE事前定義されたものがあります。次に、これらの定義を使用して、ログの有効化/無効化、サーバーURLなどの定数値を決定します。

現在、Java / Androidでは、リリースをビルドする前にいくつかコメントします。それは良い方法ではありません、私は言うことができます。私は何かを忘れるかもしれません。

リリースバージョン(署名付き)またはデバッグバージョン(署名なし)をビルドするときに何も忘れられないようにするための一般的な方法は何ですか?

4

5 に答える 5

18

Eclipse からアプリケーションを実行している場合は、常にデバッグになります。

アプリケーションをエクスポートする場合 (Android Tools -> Export (un)signed Application Package)

リリースかデバッグかを動的に知りたい場合は、BuildConfig.DEBUG を使用できます (これは gen フォルダーにあります。これがすべての API レベルでサポートされているかどうかはわかりません)。

次のように:

if (BuildConfig.DEBUG) {
    Log.d(TAG, "Text");
}

生成されたバイトコードを見ると、次のように表示されます (デバッグ モード)。

public class Sample{

    private static final boolean LOG_ENABLED = true;

    public static void main(String args[]){
        if (BuildConfig.DEBUG){
            System.out.println("Hello World");
        }
    }
}

次のバイトコードを生成します。

public class Sample extends java.lang.Object{
    public Sample();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   return

    public static void main(java.lang.String[]);
      Code:
       0:   getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
       3:   ldc #3; //String Hello World
       5:   invokevirtual   #4; //Method Java/io/PrintStream.println(Ljava/lang/String;)V
       8:   return

}

BuildConfig.DEBUG が false の場合

public class Sample extends java.lang.Object{
    public Sample();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   return

    public static void main(java.lang.String[]);
      Code:
       0:   return
}
于 2012-09-17T12:12:19.310 に答える
8

(デフォルトでは) Java 用のプリプロセッサがないため#ifdef、コンパイル時には何もありません。ただし、アプリにデバッグ コードを残すことを気にしない場合は、次のコードを使用して、実行時にアプリがリリースまたはデバッグされているかどうかを確認できます。

Boolean release = (getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE);

debuggableフラグ値をチェックします。そして、flad はfalse、リリース ビルドとtrueデバッグ ビルドに対して自動的に設定されます。

デバッグ コードを削除したい場合は、ProGuard を使用して特定のクラスまたはメソッドを削除してみてください。デフォルトでは、ProGuard はリリース ビルドのみのビルド プロセスに関与します。

于 2012-09-17T12:17:18.603 に答える
0

私は通常、静的なDEBUG変数を設定する別のログクラスを作成します。これで、本番ビルドを取得する前に行う必要があるのは、そのDEBUG変数をfalseに設定することだけです。

public class Log {
     public final static String LOGTAG = "APP NAME";

      public static final boolean DEBUG = true;

      public static void v(String msg) {
        android.util.Log.v(LOGTAG, msg);
      }

      public static void e(String msg) {
        android.util.Log.e(LOGTAG, msg);
      }

      public static void d(String msg) {
          android.util.Log.d(LOGTAG, msg);
      }
}

ロギング用-

if(Log.DEBUG) Log.v("In some function x. Doing y.");
于 2012-09-17T12:14:15.127 に答える
0

前処理ディレクティブを適切にエミュレートする方法を見つけました。

私の Gradle では、次のbuildTypesように定義します。

release {
    buildConfigField "boolean", "isDebug", "false"
    ...
}

debug {
    buildConfigField "boolean", "isDebug", "true"
    ...
}

次に、私のコードでは、次のようにします。

if (BuildConfig.isDebug) {
    ... do debug stuff ...
}

もちろん、必要に応じて:

else {
    ... do release stuff ...
}

両方のブロックがdebugAPK に存在しますが、releaseバージョンをビルドするとき、 Proguard はブロックが に依存しているため(結果のコードからも削除されます) 、ブロックを削除できると判断するのに十分賢いです。debugif (false)

いくつかのデバッグ固有のクラスをdebugブロックから呼び出し、そこからのみ呼び出した場合、それらは未使用と見なされるため、結果の APK から削除されます。これも興味深い点です。コードは、それを使用する方法で調整することはできません。コード。

dumpmappingおよびusageProguard の出力ファイルを確認することで、すべてを判断できました。

于 2016-03-04T11:25:25.413 に答える