How does application install size vary on phone?

android, animation, dialog, size, view

Solution

Yup, your speculations are close to be right, so as you may know all your Java code first is compiled to Java bytecode by say `javac`, then `dx` converts them to Dalvik bytecode, your dalvik bytecode file (a.k.a. `dex`) is packaged inside your apk (btw apk size doesn't vary much as zip compression helps) usually as `classes.dex` which later on when you install the apk in you device, Android might optimize it for that particular device (a.k.a. `odex`).

So to verify that your final cached `dex` actually changes and is the responsible for this size change, by say just adding animations, you can find it either by unzipping your apk or inside your device, I always find the second option more exciting:

So here is your `dex` without animation (your `80kb`):

And your app info:

So here is your `dex` with animation (your `1 MB`):

And your app info:

A closer look you can find they are truly different by just looking right in your dalvik bytecode constants pool:

For some reason I didn't get such radical size difference yet it is noticiable, I built your app using gradle + Android Studio so I think they help and optimize things a bit.

Finally, you could use ProGuard but hey! some k aren't that much this days, I wouldn't worry for adding some "fat" to your app as long it makes it better, of course there is always room for improvement yet remember that you are not in a java4k or stuff like that :)

Problem

I recently made this application for root users who mod their device frequently. Now I noticed quite strange behaviour with the application's install size. When I used a regular activity with views being initialized from the XML file, the size was `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); } ``` After I switched to a dialog which was created setting a view which contained the widgets in the XML file. The app size was now `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(); } ``` It reduced to `80kb` when I used this: ``` @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(); } }); } ``` I also noticed another strange change in application size when I tried to add an animation with the last style of code(the `80kb` one). The app size became a hefty `1 MB`. This is how I initialized the animation and tried calling it when the button was clicked : ``` 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 ``` Inside the onCreate method: ``` animation.setDuration(1000); animation.setFillAfter(false); ``` After which I called it in the `onClickListener`: ``` mapButton.startAnimation(animation); ``` Why is there such a drastic change in application size when I haven't added any new resources but only changed the style of code? Where is there such a HUGE difference in the way I initialize widgets present in dialogs? Why is there a HUGE difference when I add an animation the way I've added it? Follow up question: ``` @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); } ``` SPECULATION Could this be due to the packages or classes which are imported? It makes sense for the `animation` bit of the question at least. Would adding the context to which the views are initialized reduce memory usage?

Original source