11

私は最近、デバイスを頻繁に変更する root ユーザー向けにこのアプリケーションを作成しました。

ここで、アプリケーションのインストール サイズに関する非常に奇妙な動作に気付きました。

ビューが XML ファイルから初期化されている通常のアクティビティを使用した場合、サイズは715 kb.

 @Override
protected void onCreate(Bundle bundle) {
    super.onCreate(bundle);
    setContentView(R.layout.main_layout);
    executeEvents = new ExecuteEvents(this);
    display = (TextView) findViewById(R.id.display);
    powermenu = (Button) findViewById(R.id.powermenu);
    turnoffscreen = (Button) findViewById(R.id.turnscreenoff);
    mapButton = (ImageButton) findViewById(R.id.mapButton);
    SP = getSharedPreferences(PBConstants.Power_Button_SP, MODE_MULTI_PROCESS);
    if(SP.contains(PBConstants.INPUT_DEVICE_TAG))
        display.setText(getResources().getString(R.string.configured));
    mapButton.setOnClickListener(this);
    powermenu.setOnClickListener(this);
    turnoffscreen.setOnClickListener(this);
}

XMLファイルにウィジェットを含むビューを設定して作成されたダイアログに切り替えた後。アプリのサイズは になり200kbました。

@Override
protected void onCreate(Bundle bundle) {
    super.onCreate(bundle);
    //setContentView(R.layout.main_layout);
    LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
    View view = inflater.inflate(R.layout.main_layout, null);
    executeEvents = new ExecuteEvents(this);
    display = (TextView) view.findViewById(R.id.display);
    powermenu = (Button) view.findViewById(R.id.powermenu);
    turnoffscreen = (Button) view.findViewById(R.id.turnscreenoff);
    mapButton = (ImageButton) view.findViewById(R.id.mapButton);
    SP = getSharedPreferences(PBConstants.Power_Button_SP, MODE_MULTI_PROCESS);
    if(SP.contains(PBConstants.INPUT_DEVICE_TAG))
        display.setText(getResources().getString(R.string.configured));
    mapButton.setOnClickListener(this);
    powermenu.setOnClickListener(this);
    turnoffscreen.setOnClickListener(this);

    Dialog dialog = new Dialog(this);
    dialog.setContentView(view);
    dialog.setTitle(getResources().getString(R.string.app_name));
    dialog.show();
}

これ80kbを使用すると、次のようになりました。

@Override
protected void onCreate(Bundle bundle) {
    super.onCreate(bundle);
    dialog = new Dialog(this);
    dialog.setContentView(R.layout.main_layout);
    executeEvents = new ExecuteEvents(this);
    display = (TextView) dialog.findViewById(R.id.display);
    powermenu = (Button) dialog.findViewById(R.id.powermenu);
    turnoffscreen = (Button) dialog.findViewById(R.id.turnscreenoff);
    mapButton = (ImageButton) dialog.findViewById(R.id.mapButton);
    SP = getSharedPreferences(PBConstants.Power_Button_SP, MODE_MULTI_PROCESS);
    if(SP.contains(PBConstants.INPUT_DEVICE_TAG))
        display.setText(getString(R.string.configured));
    mapButton.setOnClickListener(this);
    powermenu.setOnClickListener(this);
    turnoffscreen.setOnClickListener(this);
    dialog.setTitle(getString(R.string.app_name));
    dialog.show();
    dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
        @Override
        public void onDismiss(DialogInterface dialogInterface) {
            dialog.dismiss();
            MainActivity.this.finish();
        }
    });
}

また、最後のスタイルのコード (1 つ) でアニメーションを追加しようとしたときに、アプリケーション サイズの別の奇妙な変化に気付きました80kb。アプリのサイズが大きくなりました1 MB。これは、アニメーションを初期化し、ボタンがクリックされたときに呼び出す方法です:

private static final ScaleAnimation animation = new ScaleAnimation(1, .95f, 1, .95f, Animation.RELATIVE_TO_SELF, (float)0.5, Animation.RELATIVE_TO_SELF, (float)0.5);//declared as global variable

onCreate メソッド内:

animation.setDuration(1000);
animation.setFillAfter(false);

その後、次のように呼び出しましたonClickListener

mapButton.startAnimation(animation);

新しいリソースを追加せず、コードのスタイルを変更しただけなのに、なぜアプリケーションのサイズが大幅に変化するのでしょうか? ダイアログに存在するウィジェットを初期化する方法に大きな違いがあるのはどこですか? 追加した方法でアニメーションを追加すると、大きな違いがあるのはなぜですか?

フォローアップの質問:

 @Override
protected void onCreate(Bundle bundle) {
    super.onCreate(bundle);
    setContentView(R.layout.main_layout);
    executeEvents = new ExecuteEvents(this);
    display = (TextView) this.findViewById(R.id.display);
    powermenu = (Button) this.findViewById(R.id.powermenu);
    turnoffscreen = (Button) this.findViewById(R.id.turnscreenoff);
    mapButton = (ImageButton) this.findViewById(R.id.mapButton);
    SP = getSharedPreferences(PBConstants.Power_Button_SP, MODE_MULTI_PROCESS);
    if(SP.contains(PBConstants.INPUT_DEVICE_TAG))
        display.setText(getResources().getString(R.string.configured));
    mapButton.setOnClickListener(this);
    powermenu.setOnClickListener(this);
    turnoffscreen.setOnClickListener(this);
}

投機

これは、インポートされたパッケージまたはクラスが原因でしょうか? animation少なくとも質問のビットには意味があります。

ビューが初期化されるコンテキストを追加すると、メモリ使用量が削減されますか?

4

1 に答える 1

9

うん、あなたの憶測はほぼ正しいので、すべての Java コードが最初に say によって Java バイトコードにコンパイルされjavac、次にdxそれらを Dalvik バイトコードに変換することを知っているかもしれないので、dalvik バイトコード ファイル (別名dex) は apk 内にパッケージ化されます (btw apk zip 圧縮が役立つため、サイズはそれほど変わりません) 通常、classes.dex後でデバイスに apk をインストールするときに、Android がその特定のデバイス (別名odex) 用に最適化する可能性があります。

したがって、アニメーションを追加するだけで、最終的なキャッシュdexが実際に変更され、このサイズの変更の原因であることを確認するには、apk を解凍するか、デバイス内で見つけることができます。

だからここにあなたのdexアニメーションなし(あなたの80kb)があります:

http://i.imgur.com/2JkpWS3.png

そしてあなたのアプリ情報:

http://i.imgur.com/HseGJih.png

だからここにあなたdexのアニメーションがあります(あなたの1 MB):

http://i.imgur.com/pyrthYd.png

そしてあなたのアプリ情報:

http://i.imgur.com/FSVPWAC.png

よく見ると、dalvik バイトコード定数プールを正しく見るだけで、それらが本当に異なっていることがわかります。

http://i.imgur.com/02mqaif.png

何らかの理由で、それほど大きなサイズの違いはありませんでしたが、目立ちます.gradle + Android Studioを使用してアプリを作成したので、少し助けて最適化できると思います.

最後に、ProGuard を使用することもできますが、ちょっと! 一部のkは最近ではそれほど多くありません。アプリが改善される限り、アプリに「脂肪」を追加しても心配しません。もちろん、常に改善の余地がありますが、java4kなどではないことを忘れないでくださいそのように:)

于 2013-07-18T03:34:23.120 に答える