私はこれを与えるためにどのようなタイトルがわからない、それはとても奇妙です。私はARGB整数形式で色の値を使用する少しAndroid logic puzzleを構築しました。あなたがレベルを完了すると、アニメーションの色をブレンドするために、私は次の関数があります。最も奇妙なAndroidのバグ - おそらくProGuardの問題?
public static int blend(int color1, int color2, double position) {
if (position<0) position=0;
if (position>1) position=1;
int a = (color1 >>> 24) & 0xFF;
int r = (color1 >>> 16) & 0xFF;
int g = (color1 >>> 8) & 0xFF;
int b = color1 & 0xFF;
int da = ((color2 >>> 24) & 0xFF) - a;
int dr = ((color2 >>> 16) & 0xFF) - r;
int dg = ((color2 >>> 8) & 0xFF) - g;
int db = (color2 & 0xFF) - b;
a += da * position;
r += dr * position;
g += dg * position;
b += db * position;
return (a<<24) | (r<<16) | (g<<8) | b;
}
は、私は(デバッグprint文を含んでいる)このコードでアニメーション中にこの関数を呼び出す:
int color = blend(START_COLOR, END_COLOR, pos*pos*pos*pos*pos);
System.out.println(Integer.toHexString(START_COLOR)+", "+Integer.toHexString(END_COLOR)+", "+pos+" -> "+Integer.toHexString(color));
ここでは、pos
は単なる0.0から1.0までの倍の値です。
Android開発者プラグインを使用してEclipse内から直接このコードを携帯電話で実行すると、すべて正常に動作します。
しかし:私はAPK、それ確実ねじアップ、与えるのアプリをパッケージ化してインストールする場合、私のような出力:この例では
...
fff9b233, f785a307, 0.877 -> fabcaa1c
fff9b233, f785a307, 0.881 -> fabbaa1b
fff9b233, f785a307, 0.883 -> fabaa91b
fff9b233, f785a307, 0.886 -> fab9a91a
fff9b233, f785a307, 0.89 -> fab8a91a
fff9b233, f785a307, 0.891 -> fa00a91a
fff9b233, f785a307, 0.895 -> fab6a919
fff9b233, f785a307, 0.896 -> fa00a919
fff9b233, f785a307, 0.901 -> fab4a918
fff9b233, f785a307, 0.901 -> fab4a918
fff9b233, f785a307, 0.907 -> fab1a817
fff9b233, f785a307, 0.907 -> fab1a817
fff9b233, f785a307, 0.912 -> f9afa817
fff9b233, f785a307, 0.913 -> f900a817
fff9b233, f785a307, 0.919 -> f9aca816
fff9b233, f785a307, 0.919 -> f9aca816
fff9b233, f785a307, 0.925 -> f9aaa715
fff9b233, f785a307, 0.925 -> f9aaa715
fff9b233, f785a307, 0.93 -> f900a714
fff9b233, f785a307, 0.931 -> f900a714
fff9b233, f785a307, 0.936 -> f900a713
fff9b233, f785a307, 0.937 -> f900a713
fff9b233, f785a307, 0.942 -> f900a612
fff9b233, f785a307, 0.942 -> f900a612
fff9b233, f785a307, 0.947 -> f800a611
fff9b233, f785a307, 0.948 -> f800a611
fff9b233, f785a307, 0.954 -> f800a610
fff9b233, f785a307, 0.954 -> f800a610
fff9b233, f785a307, 0.959 -> f800a50f
...
、位置100は、すべてが正常であるアップまで。それから、Rコンポーネント(0に設定されています; は常にのRコンポーネントが不正になってしまいます)と、最終的にはこの例では0.93から始まって、物事は常にうまくいきます。そして、まったく同じアニメーションをもう一度実行すると、すぐにねじれ始める...
これはどのように地球可能ですか?このProGuardは私のコードを乱していますか?それが可能ならば、確かに見つけ出す方法はありますか?私は本当にここでアイデアを失っています...それがうまくいくかどうかは、どうやって確率論的になりますか?それとも私はここで完全に明白な何かを見逃していますか?
ProGuardの問題である可能性がある場合、どのような最適化がコードのこの部分に影響する可能性がありますか?不安定なものを見つけるために1つずつスイッチを切ることができるスイッチのリストはありますか?
UPDATE:
マイproject.properties
ファイルは(コメント行が削除された)次のようになります。このような
proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
target=android-22
とproguard-project.txt
:
-flattenpackagehierarchy
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
proguard-android.txt
をSDKディレクトリにすべきではまだSDK Tools v24.1.2に同梱されていたようにProGuardを含むパッケージです...;再び)コメントを除く:
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose
-dontoptimize
-dontpreverify
-keepattributes *Annotation*
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
-dontwarn android.support.**
UPDATE 2:
+ Method: a(IID)I
Access flags: 0x9
= public static int a(int,int,double)
Class member attributes (count = 1):
+ Code attribute instructions (code length = 171, locals = 12, stack = 6):
[0] dload_2 v2
[1] dconst_0
[2] dcmpg
[3] ifge +5 (target=8)
[6] dconst_0
[7] dstore_2 v2
[8] dload_2 v2
[9] dconst_1
[10] dcmpl
[11] ifle +5 (target=16)
[14] dconst_1
[15] dstore_2 v2
[16] iload_0 v0
[17] bipush 24
[19] iushr
[20] sipush 255
[23] iand
[24] istore v4
[26] iload_0 v0
[27] bipush 16
[29] iushr
[30] sipush 255
[33] iand
[34] istore v5
[36] iload_0 v0
[37] bipush 8
[39] iushr
[40] sipush 255
[43] iand
[44] istore v6
[46] iload_0 v0
[47] sipush 255
[50] iand
[51] istore v7
[53] iload_1 v1
[54] bipush 24
[56] iushr
[57] sipush 255
[60] iand
[61] iload v4
[63] isub
[64] istore v8
[66] iload_1 v1
[67] bipush 16
[69] iushr
[70] sipush 255
[73] iand
[74] iload v5
[76] isub
[77] istore v9
[79] iload_1 v1
[80] bipush 8
[82] iushr
[83] sipush 255
[86] iand
[87] iload v6
[89] isub
[90] istore v10
[92] iload_1 v1
[93] sipush 255
[96] iand
[97] iload v7
[99] isub
[100] istore v11
[102] iload v4
[104] i2d
[105] iload v8
[107] i2d
[108] dload_2 v2
[109] dmul
[110] dadd
[111] d2i
[112] istore v4
[114] iload v5
[116] i2d
[117] iload v9
[119] i2d
[120] dload_2 v2
[121] dmul
[122] dadd
[123] d2i
[124] istore v5
[126] iload v6
[128] i2d
[129] iload v10
[131] i2d
[132] dload_2 v2
[133] dmul
[134] dadd
[135] d2i
[136] istore v6
[138] iload v7
[140] i2d
[141] iload v11
[143] i2d
[144] dload_2 v2
[145] dmul
[146] dadd
[147] d2i
[148] istore v7
[150] iload v4
[152] bipush 24
[154] ishl
[155] iload v5
[157] bipush 16
[159] ishl
[160] ior
[161] iload v6
[163] bipush 8
[165] ishl
[166] ior
[167] iload v7
[169] ior
[170] ireturn
Code attribute exceptions (count = 0):
Code attribute attributes (attribute count = 2):
+ Line number table attribute (count = 15)
[0] -> line 33
[8] -> line 34
[16] -> line 35
[26] -> line 36
[36] -> line 37
[46] -> line 38
[53] -> line 40
[66] -> line 41
[79] -> line 42
[92] -> line 43
[102] -> line 45
[114] -> line 46
[126] -> line 47
[138] -> line 48
[150] -> line 50
+ Stack map table attribute (count = 2):
- [8] Var: ..., Stack: (empty)
- [16] Var: ..., Stack: (empty)
:
私はProGuardのはdump.txt
ファイルにblend
-methodで何をするかのコンパイル出力を見つけたと思います更新3:
試しましたこの(アイデアは、私は同じすべてのコンポーネントを扱う場合、もはや一つだけを台無しにすることは可能であってはならないということである)にブレンド法を書き換える:
public static int blend(int color1, int color2, double position) {
if (position<0) position=0;
if (position>1) position=1;
int result = 0;
for (int shift = 0; shift<32; shift += 8) {
int component = (color1 >>> shift) & 0xFF;
int change = ((color2 >>> shift) & 0xFF) - component;
component += change * position;
result |= component << shift;
}
return result;
}
驚くことではないが、このコードはちょうど、動作するようになりましたそれはすべきだ!しかし、これはまだ元のコードが失敗し、私のアプリケーションの他のどの場所でも、同様に些細なことが予期しない方法で失敗する可能性があることを理解できなくなってしまいます。
UPDATE 4:
単にこれに行を並べ替えることも、問題が修正されます。
public static int blend(int color1, int color2, double position) {
if (position<0) position=0;
if (position>1) position=1;
int a = (color1 >>> 24) & 0xFF;
int da = ((color2 >>> 24) & 0xFF) - a;
a += da * position;
int r = (color1 >>> 16) & 0xFF;
int dr = ((color2 >>> 16) & 0xFF) - r;
r += dr * position;
int g = (color1 >>> 8) & 0xFF;
int dg = ((color2 >>> 8) & 0xFF) - g;
g += dg * position;
int b = color1 & 0xFF;
int db = (color2 & 0xFF) - b;
b += db * position;
return (a<<24) | (r<<16) | (g<<8) | b;
}
それはいくつかのローカル変数・再利用のものでなければならない理由、私は知りません上記のdump.txtファイルから明らかではありません... Dalvikが行うことですが(署名されたAPKだけに!?!)
なぜあなたのアプリにリンクしてスパムしていますか?このリンクがどのように質問につながっていますか? – Selvin
@セルヴィンあなたが起こっているエラー(成長している星の色)を見たい場合...また、私は通常、人々が私の答えで何をするのか興味深いと思っています...しかし、それがあればそれを削除することができます不適切な... –
最終的にあなたが使用しているデフォルトのproguardファイルについて、proguardファイル情報を提供できますか? – Selvin