2013-07-12 13 views
11

Niedawno zrobiłem to application dla użytkowników root, którzy często modyfikują swoje urządzenie.Jak rozmiar instalacji aplikacji zależy od telefonu?

Teraz zauważyłem dość dziwne zachowanie z rozmiarem instalacji aplikacji.

Kiedy użyłem zwykłej aktywności z widokami inicjowanymi z pliku XML, rozmiar był 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); 
} 

Po tym, jak przełączyłem się do okna dialogowego, które zostało utworzone, ustawiając widok, który zawierał widżety w pliku XML. Rozmiar aplikacji był teraz: 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(); 
} 

ona zredukowana do 80kb gdy użyłem tego:

@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(); 
     } 
    }); 
} 

Zauważyłem również inną dziwną zmianę w wielkości aplikacji, gdy próbowałem dodać animację z ostatniego stylu Kodeksu (80kb jeden) . Rozmiar aplikacji stał się spory. To jak ja zainicjowany animację i próbował nazywając ją, gdy przycisk został kliknięty:

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 

Wewnątrz onCreate metody:

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

Po czym zadzwoniłem go w onClickListener:

mapButton.startAnimation(animation); 

Dlaczego istnieje tak drastyczna zmiana w rozmiarze aplikacji, gdy nie dodałem żadnych nowych zasobów, ale zmieniłem tylko styl kodu? Gdzie jest taka OGROMNA różnica w sposobie inicjalizacji widżetów obecnych w oknach dialogowych? Dlaczego istnieje ogromna różnica po dodaniu animacji w taki sposób, w jaki ją dodałem?

Kontynuacja pytanie:

@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); 
} 

spekulacji

Może to być spowodowane pakietów lub klas, które są importowane? Ma to sens przynajmniej dla pewnej części pytania.

Dodanie kontekstu, w którym inicjalizowane są widoki, zmniejsza zużycie pamięci?

+0

Możesz rozpakować plik APK i przeanalizować jego składniki. Możesz także przeanalizować plik dex (http://code.google.com/p/smali), aby zobaczyć jego strukturę. –

+0

Rozmiar pliku APK jest taki sam. Rozmiar instalacji jest inny. –

+0

Wow, to interesujące. Na urządzeniu zrootowanym można analizować poszczególne pliki związane z zainstalowaną aplikacją. Na przykład 'ls -l/data/app/{pakiet}', 'ls -l/data/data/{pakiet}'. –

Odpowiedz

9

Tak, twoje spekulacje są blisko, aby być w porządku, tak jak można wiedzieć wszystko kodu Java pierwszy jest kompilowany do kodu bajtowego Javy przez powiedzmy javac, następnie dx konwertuje je do Dalvik kodu bajtowego, plik kodu bajtowego Dalvik (aka dex) jest w pakiecie apk (rozmiar btw apk nie różni się zbytnio od kompresji zip) zwykle jako classes.dex, który później po zainstalowaniu apk w twoim urządzeniu, Android może zoptymalizować go dla tego konkretnego urządzenia (aka odex).

Aby zweryfikować, że ostateczny buforowany plik dex rzeczywiście się zmienia i jest odpowiedzialny za tę zmianę wielkości, powiedzmy po prostu dodając animacje, możesz go znaleźć, rozpakowując plik APK lub w urządzeniu, zawsze znajduję drugą opcję. ekscytujące:

Więc tutaj jest dex bez animacji (Twój 80kb):

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

A twój informacji app:

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

Więc tutaj jest dex z animacją (Twój 1 MB):

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

A twój informacji app:

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

Bliższe spojrzenie można znaleźć są naprawdę inaczej po prostu patrząc w swoje stałe stałe bajtowe dalvik:

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

Z jakiegoś powodu nie miałem takiej różnicy radykalne rozmiar to jeszcze noticiable, zbudowałem swoją aplikację za pomocą Gradle + Android Studio, więc myślę, że pomoc i zoptymalizować rzeczy trochę.

Wreszcie możesz użyć ProGuarda, ale hej! niektóre k nie są tak wiele w dzisiejszych czasach, nie martwiłbym się o dodanie "grubej" do twojej aplikacji, o ile poprawi się to, oczywiście, zawsze jest miejsce na ulepszenie, ale pamiętaj, że nie jesteś w java4k lub w ten sposób :)

+0

Kiedy dokonałeś tych zmian, czy działanie aplikacji różni się w zależności od różnych stylów implementacji? –

+0

@Torcellite to kolejne pytanie, powiedziałbym, że powinieneś najpierw martwić się o wyciek 'MainActivity's z tymi wszystkimi' statycznymi' członkami zanim jeszcze martwisz się o wydajność – eveliotc

+0

Miałem wrażenie, że statyczni członkowie mają tylko jedną instancję, a więc nie powodują znaczny wyciek. Proszę, wybacz mi moją niewiedzę w tej sprawie. Próbuję się uczyć. –