2017-10-16 36 views
7

Mam problem z tworzoną przeze mnie aplikacją. Zasadniczo aplikacja ulegnie awarii po pierwszym uruchomieniu, a potem wszystko będzie w porządku. Ta myląca część ma miejsce tylko wtedy, gdy pobierzesz aplikację z Google Play. Jeśli załaduję aplikację na mój telefon prosto z Android Studio, nie otrzymam żadnych błędów.RuntimeException na ładowanie aplikacji tylko w wersji produkcyjnej

java.lang.RuntimeException: 
    at android.app.ActivityThread.handleReceiver (ActivityThread.java:3290) 
    at android.app.ActivityThread.-wrap20 (ActivityThread.java) 
    at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1715) 
    at android.os.Handler.dispatchMessage (Handler.java:102) 
    at android.os.Looper.loop (Looper.java:154) 
    at android.app.ActivityThread.main (ActivityThread.java:6682) 
    at java.lang.reflect.Method.invoke (Native Method) 
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1520) 
    at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1410) 
Caused by: java.lang.ClassNotFoundException: 
    at dalvik.system.BaseDexClassLoader.findClass (BaseDexClassLoader.java:56) 
    at java.lang.ClassLoader.loadClass (ClassLoader.java:380) 
    at java.lang.ClassLoader.loadClass (ClassLoader.java:312) 
    at android.app.ActivityThread.handleReceiver (ActivityThread.java:3285) 

Po zbadaniu tego problemu stwierdziłem, że ludzie mówią, aby wyczyścić pamięć podręczną urządzenia. To rozwiązało problem ... ale to tylko wyczyści aplikację i od tej chwili działa poprawnie. Pierwsza instalacja nadal się zawiesza. Stało się to na wielu urządzeniach, ale nie mogę go odtworzyć podczas debugowania. Moją jedyną myślą jest, że mam ten kod w onCreate() zaraz po wywołaniu setContentView().

Intent intent = new Intent(this, NotificationListener.class); 
startService(intent); 
bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); 

NotificationListener.class rozszerza NotificationListenerService. Wszystko działa świetnie, z wyjątkiem pierwszego uruchomienia.

UPDATE

Oto jak ustawić obsługę w AndroidManifest:

<service android:name=".NotificationListener" 
    android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"> 
    <intent-filter> 
     <action android:name="android.service.notification.NotificationListenerService" /> 
    </intent-filter> 
</service> 

Tutaj jest uproszczoną wersją mojego NotificationListenerService:

public class NotificationListener extends NotificationListenerService 
{ 
    private IBinder mBinder = new LocalBinder(); 

    @Override 
    public void onNotificationPosted(StatusBarNotification sbn) 
    { 
     super.onNotificationPosted(sbn); 

     // custom code 
    } 

    @Override 
    public void onNotificationRemoved(StatusBarNotification sbn) 
    { 
     super.onNotificationRemoved(sbn); 
    } 

    @Override 
    public IBinder onBind(Intent intent) 
    { 
     if (SERVICE_INTERFACE.equals(intent.getAction())) 
      return super.onBind(intent); 
     else return mBinder; 
    } 

    public class LocalBinder extends Binder 
    { 
     public NotificationListener getService() 
     { 
      return NotificationListener.this; 
     } 
    } 
} 

Oto ServiceConnection dla Spoiwo:

private ServiceConnection serviceConnection = new ServiceConnection() 
{ 
    @Override 
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) 
    { 
     NotificationListener.LocalBinder localBinder = (NotificationListener.LocalBinder) iBinder; 
     notificationListener = localBinder.getService(); 
     bound = true; 

     // code to call custom function in NotificationListener class 
    } 

    @Override 
    public void onServiceDisconnected(ComponentName componentName) 
    { 
     notificationListener = null; 
     bound = false; 
    } 
}; 

Wiem, że to musi być problem z powiązaniem usługi, ponieważ jeśli usuwam cały kod wiążący i po prostu uruchamiam usługę, wszystko działa tak, jak powinno. Dopiero po dodaniu kodu wiążącego otrzymuję ten błąd.

+0

Czy możesz spróbować utworzyć plik APK bez progu, jeśli to zrobisz? – kimkevin

+1

@KimKevin Czy to wymaga usunięcia wpisu w Jeśli tak, to usunąłem go i przesłałem wersję beta mojej aplikacji i nadal mam ten sam błąd przy uruchomieniu – saboehnke

+0

tak to jest. minifyEnabled ustawia jako false lub ponieważ wystąpił ClassNotFoundException ... czy zarejestrujesz się NotificationListenerService to AndroidMani fest.xml? – kimkevin

Odpowiedz

1

Wygląda na to, że nie trzeba ponownie uruchamiać i wiązać usługi. proszę utworzyć podpisujący plik APK po skasowaniu poniższych kodów.

Intent intent = new Intent(this, NotificationListener.class); 
startService(intent); 

[EDIT]

myślę, że to PROGUARD zaciemniania, więc proszę dodać następujące kody do pliku PROGUARD.

# Base Android exclusions, required for proper function of various components 
-keep public class * extends android.app.Activity 
-keep public class * extends android.app.Application 
-keep public class * extends android.app.Service 
-keep public class * extends android.content.BroadcastReceiver 
-keep public class * extends android.content.ContentProvider 
-keep public class * extends android.preference.Preference 
-keep public class * extends android.support.v4.app.Fragment 
-keep public class * extends android.app.Fragment 
+0

Poszedłem dalej i usunąłem wywołanie startService(), ponieważ bindService() powinien go obsłużyć. Nadal jednak ulega awarii. Chcę sprawdzić, czy błąd się nie zmienił, ale z jakiegoś powodu nie dostaję żadnych awarii dla wersji beta. – saboehnke

+0

Tak, nadal mam ten sam błąd, gdy usuwam startService(). – saboehnke

+0

Nie mam doświadczenia w pracy z plikami proguard, więc dodałem je zarówno do mojego pliku proguard-android.txt-2.3.3, jak i do pliku aapt_rules.txt. Nadal jednak ulega awarii. – saboehnke

0

Generalnie ten problem występuje z powodu progu, jeśli dodasz proguard do projektu, zatrzyma on niektóre funkcje takie jak ta.

Wystarczy spróbować, aby dodać modułu serwisowego w proguard-rules.pro pliku dodając

-Trzymaj klasa {nazwa-pakietu} {service-module-name} ** {*..; }

Na przykład:> -keep class com.demo.service. ** {*; }

spowoduje to dodanie wszystkich uprawnień do usług w programie.

+0

Czy mogę po prostu usunąć program proguard, jeśli powoduje on problem? – saboehnke

+0

Każda rzecz ma swoje plusy i minusy, Proguard również. Zapewni ci dobre bezpieczeństwo i wiele innych funkcji. Tak więc, moim zdaniem jest dodanie tych plików do pliku proguard-rules.pro zamiast całkowitego usunięcia go. –

0

Tutaj znajduje się pusta wiadomość ClassNotFoundException.Patrząc na kod źródłowy dalvik.system.BaseDexClassLoader, generuje on ClassNotFoundException z nazwą wskazanej klasy, jeśli nie może jej znaleźć, dlatego gdzieś podajesz pustą nazwę klasy (czyli w komunikacie obsługiwanym przez ActivityThread::handleReceiver. bardzo pomocne, jeśli mógłbyś podać pełny ślad stosu (tj. gałąź handleMessage, która deleguje to wywołanie)