Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does application install size vary on phone?

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?

like image 843
Karthik Balakrishnan Avatar asked Jul 12 '13 14:07

Karthik Balakrishnan


People also ask

Why does app size increase after installing Android?

Since apps are compressed when they're downloaded, it can make install sizes larger than download sizes. When an app has a larger install size, more space is required on a user's device to complete the installation. After the app is opened, its size on the disk varies depending on the app usage.

How many GB does an app take up?

Typically, individual apps can use between 40MB – 1GB of phone storage.

Do apps get bigger with every update?

No, update doesn't always have to guarantee an increase in size of an app. Generally, app developers add new libraries and codes in updates which tends to increase the size of the app. But if developer decides to remove certain codes and libraries, it surely will decrease the size of the app.


1 Answers

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):

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

And your app info:

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

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

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

And your app info:

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

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

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

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 :)

like image 189
eveliotc Avatar answered Nov 15 '22 20:11

eveliotc