Как размер установки приложения зависит от телефона?

Недавно я сделал это application для пользователей 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();
        }
    });
}

Я также заметил еще одно странное изменение размера приложения, когда я попытался добавить анимацию с последним стилем кода (80kb one). Размер приложения стал тяжелым 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 по крайней мере.

Добавил бы контекст, в который инициализируются представления, уменьшает использование памяти?

Ответ 1

Yup, ваши предположения близки к правильным, так как вы можете знать, что весь ваш Java-код сначала скомпилирован в байт-код Java, скажем javac, затем dx преобразует их в байт-код Dalvik, ваш байт-код dalvik (aka 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 или на например:)