(Android) Nadmierna ilość zdarzeń w trakcie uruchamiania aplikacji

(Android) Nadmierna ilość zdarzeń w trakcie uruchamiania aplikacji
Arkady_pl
  • Rejestracja:ponad 15 lat
  • Ostatnio:ponad 8 lat
1

Witajcie.

Tworzę aplikację dla platformy Android przy pomocy środowiska Android Studio 2.1.2.
Ponieważ aplikacja się rozrosła to skutkiem tego jej czas uruchamiania się zwiększył(sporo się dzieje w onCreate).
Z ciekawości oprogramowałem również zdarzenia(dodałem im tylko Log.d) onStart, onRestar, onPostCreate, onResumeonPause i onDestroy.
Przeanalizowałem, które zdarzenia kiedy są wywoływane(w kontekście klawiszy "home", "back" i "task manager").

Skutkiem tego było moje zdziwienie gdy zobaczyłem co się dzieje podczas uruchamiania aplikacji.
Moje pytanie brzmi - dlaczego część zdarzeń wykonuje się dwukrotnie?
Aplikacja ma jedno Active, jedną klasę, nie ma wątków, kreuje tylko sporo klawiszy z obrazkami i kilka większych bitmap.
Nie mam pomysłu dlaczego aplikacja w trakcie uruchamiania "odpala" mi zdarzenia onResume(to jeszcze bym zrozumiał), onPause, oraz całkiem nie mam pomysłu dlaczego uruchamia onDestroy - aby następnie ponownie wykonać onCreate itd.

Poniższe zachowanie jest identyczne na dwóch różnych wersja Android'a i na różnych urządzeniach.

Oto kopia z monitoringu
08-13 16:47:54.223 7247-7247/...................... D/DEBUG2: MainActivity.onCreate
08-13 16:47:54.751 7247-7247/...................... D/DEBUG2: MainActivity.onStart
08-13 16:47:54.751 7247-7247/...................... D/DEBUG2: MainActivity.onPostCreate
08-13 16:47:54.751 7247-7247/...................... D/DEBUG2: MainActivity.onResume
08-13 16:47:54.797 7247-7247/...................... D/DEBUG2: MainActivity.onPause
08-13 16:47:54.797 7247-7247/...................... D/DEBUG2: MainActivity.onDestroy
08-13 16:47:54.811 7247-7247/...................... D/DEBUG2: MainActivity.onCreate
08-13 16:47:54.986 7247-7247/...................... D/DEBUG2: MainActivity.onStart
08-13 16:47:54.986 7247-7247/...................... D/DEBUG2: MainActivity.onPostCreate
08-13 16:47:54.987 7247-7247/...................... D/DEBUG2: MainActivity.onResume

Domyślam się, że jest to jedna z przyczyn długiego uruchamiania bo bez sensu dwa razy kreuje obiekty.
Niemniej oczywiście błędów nie ma. Ale pamięć RAM pożera strasznie.

Arkady_pl
  • Rejestracja:ponad 15 lat
  • Ostatnio:ponad 8 lat
0

Tymczasowo, dodałem zmienną, którą badam na początku onCreate i wracam jeśli trzeba.

Kopiuj
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if (FirstStart) return;
        FirstStart = true;

Jeśli ktoś wie lub podejrzewa co może być przyczyną tego problemu to proszę o informację.

panryz
  • Rejestracja:około 17 lat
  • Ostatnio:4 minuty
0

Nie możemy wróżyć z fusów. Ani nie pokazałeś MainActivity, ani nie pokazałeś Manifestu.

MrHyperion
  • Rejestracja:ponad 9 lat
  • Ostatnio:prawie 4 lata
  • Postów:112
0
Arkady_pl napisał(a):

Tymczasowo, dodałem zmienną, którą badam na początku onCreate i wracam jeśli trzeba.

Kopiuj
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        if (FirstStart) return;
        FirstStart = true;

Jeśli ktoś wie lub podejrzewa co może być przyczyną tego problemu to proszę o informację.

Ifologia nie jest żadnym rozwiązaniem. Tak jak Panryz, wrzuć niezbędne informacje.

Arkady_pl
  • Rejestracja:ponad 15 lat
  • Ostatnio:ponad 8 lat
0

onCreate ma ponad 200 linii kodu i chyba nie ma co analizować - nadawanie wartości zmiennych, tworzenie obiektów, itd.
A manifest poniżej.

Kopiuj
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="eu.etmx.artpainterpro">

    <uses-feature
        android:name="android.hardware.camera"
        android:required="true" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:largeHeap="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".splash"
            android:theme="@style/AppTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".MainActivity">
        </activity>
    </application>

</manifest>

Splash'a dodałem teraz i nie wpłynął on na podwójne uruchamianie.
Wtedy manifest wyglądał tak:

Kopiuj
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="eu.etmx.artpainterpro">

    <uses-feature
        android:name="android.hardware.camera"
        android:required="true" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:largeHeap="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:theme="@style/AppTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

W logach też jest zero wiadomości.
Tak jakby apka startowała, a następnie zamykała się i startowała ponownie.

W kodzie dodałem static int sysCount =0;
i powiększam ją o 1 na początku wywołania onCreate.
I wartość zmiennej się zwiększa.
Ewidentnie apka nie zamyka się całkowicie tylko "COŚ" wywołuje mi metody dwukrotnie.

(?)Moje pytanie to nie prośba o analizę kodu ale raczej prośba o jakieś sugestie, co może potencjalnie generować takie efekty.
Pomijam źle napisany kod, który sam generuje takie efekty.
Może to jakaś konfiguracja urządzenia albo kompilatora, a może to środowisko Andtroid Studio "tak ma".

Pozdrawiam.

MrHyperion
@Arkady_pl jeśli metoda ma więcej niż 20 linii to należy ją zrefaktorować ;).
Arkady_pl
@MrHyperion na czym polega refaktorowanie? Tego terminu nie znam z praktyki - poza refaktorowaniem zasobów czyli wywalaniem niepotrzebnych rzeczy.
panryz
200 linijek onCreate :D gratuluję.
MrHyperion
@Arkady_pl refaktorowanie, czyli porządkowanie kodu. Jeśli metoda ma więcej niż 20 linijek albo robi różne rzeczy, należy ją porozbijać na mniejsze metody które wykonują jedną czynność. Teoretycznie takie działanie usprawnia czytanie kodu oraz ułatwia pisanie testów.
Arkady_pl
@MrHyperion - ok, rozumiem, da się to zrobić w tej sytuacji, co jednak nie zmieni czasu realizacji.
Arkady_pl
  • Rejestracja:ponad 15 lat
  • Ostatnio:ponad 8 lat
0

Obecnie sytuacja się "skomplikowała".
Ten sam soft na Tablecie z Android 4.1 wywołuje jednokrotnie metody, natomiast z Android 5.1 wywołuje dwukrotnie.

DC
Welcome to Android Fragmentation :D
panryz
Będziem dalej wróżyć z fusów. Odpal jeszcze na kilkunastu urządzeniach to wyjdą inne klocki.
Arkady_pl
  • Rejestracja:ponad 15 lat
  • Ostatnio:ponad 8 lat
0

Zatem uprościłem wszystko aby tylko apka się uruchomiła(oczywiście wiele nie działa ale interfejs startuje bez błędu).
Manifest już podałem wcześniej.
Obecnie onCreate wygląda tak:

Kopiuj
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        Log.d("DEB2", "onCreate("+(sysCount++)+")");
    }

natomiast obsługa wywołań została okrojona i wygląda tak:
(FirstStart jest ustawione na true;)

Kopiuj
    @Override
    public void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        Log.d("DEB2", "onPostCreate");
        if (FirstStart) return;
    }


    @Override
    public void onPostResume() {
        super.onPostResume();
        Log.d("DEB2", "onPostResume");
        if (FirstStart) return;
   }

pozostałe zdarzenia wyglądają analogicznie.
Zatem z fusów nic nie zostało bo apka jest "pusta".

A mimo to, nadal mam takie wpisy jak poniżej(zwracam uwagę na () za onCreate:

Kopiuj
08-16 20:14:25.131 15448-15448/eu.etmx.artpainterpro D/DEB2: onCreate(0)
08-16 20:14:25.146 15448-15448/eu.etmx.artpainterpro D/DEB2: onStart
08-16 20:14:25.146 15448-15448/eu.etmx.artpainterpro D/DEB2: onPostCreate
08-16 20:14:25.146 15448-15448/eu.etmx.artpainterpro D/DEB2: onPostResume
08-16 20:14:25.243 15448-15448/eu.etmx.artpainterpro D/DEB2: onPause
08-16 20:14:25.245 15448-15448/eu.etmx.artpainterpro D/DEB2: onStop
08-16 20:14:25.245 15448-15448/eu.etmx.artpainterpro D/DEB2: onDestroy
08-16 20:14:25.333 15448-15448/eu.etmx.artpainterpro D/DEB2: onCreate(1)
08-16 20:14:25.335 15448-15448/eu.etmx.artpainterpro D/DEB2: onStart
08-16 20:14:25.335 15448-15448/eu.etmx.artpainterpro D/DEB2: onPostCreate
08-16 20:14:25.335 15448-15448/eu.etmx.artpainterpro D/DEB2: onPostResume

Zatem, co dalej?

Zobacz pozostałe 3 komentarze
panryz
Nie o to mi chodziło. Po prostu nie chciałeś pokazać nam onCreate(), a tutaj taki byk
Arkady_pl
bo wiedziałem, że kreowanie obiektów i nadawanie wartości na to nie wpływa. Okazało się, że wpływ ma coś naturalnego. Teraz rozumiem dlaczego wywołuje te metody - chodzi o to aby interfejs mógł zareagować na zmianę orientacji.
panryz
No ok, ale pokazałeś nam to bardzo późno. Generalnie wymuszenie orientacji w onCreate jest bardzo nienaturalne.
Arkady_pl
@panryz - nie denerwuj się, programuję już od lat w różnych językach więc się spodziewam różnych przyczyn. Androidem i java zajmuję się od tygodnia i pewne różnice muszę szybko wyłapać. Wielkie dzięki!
panryz
Wcale się nie denerwuję:) Informację o tym, że takich rzeczy nie robi się w onCreate odbierz jako dobrą praktykę :)
GThoro
  • Rejestracja:prawie 11 lat
  • Ostatnio:ponad 6 lat
  • Postów:98
1

Zmiana orientacji activity resetuje je.

Arkady_pl
  • Rejestracja:ponad 15 lat
  • Ostatnio:ponad 8 lat
0
GThoro napisał(a):

Zmiana orientacji activity resetuje je.

Potwierdzam. Pomogło.

Kopiuj
08-16 20:29:57.636 18390-18390/eu.etmx.artpainterpro D/DEB2: onCreate(0)
08-16 20:29:57.637 18390-18390/eu.etmx.artpainterpro D/DEB2: onStart
08-16 20:29:57.637 18390-18390/eu.etmx.artpainterpro D/DEB2: onPostCreate
08-16 20:29:57.638 18390-18390/eu.etmx.artpainterpro D/DEB2: onPostResume

Pozostaje pytanie jak mogę wymusić orientację nie w onCreate.
Manifest?

GThoro
Tak, w manifeście możesz ustawić orientację dla activity -> android:screenOrientation="landscape"
Arkady_pl
  • Rejestracja:ponad 15 lat
  • Ostatnio:ponad 8 lat
0

Serdeczne podziękowania za pomoc!

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.