简体   繁体   中英

RuntimeException on app load only in production release

I am having an issue with an app I am creating. Basically the app will crash the first time you try to open it and then it will be alright after that. The confusing part is it only happens when you download the app from Google Play. If I load the app on my phone straight from Android Studio I don't get any errors.

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)

After researching this issue I have found people say to clear the cache of the device. This fixed the issue...but that just wipes the app and it works fine from then on. The initial install still crashes. This has happened on multiple devices yet I cannot reproduce it while debugging. My only thought is that I have this code in the onCreate() right after I call setContentView().

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

NotificationListener.class extends NotificationListenerService. Everything works great except for the initial launch.

UPDATE

Here is how I set the service in the 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>

Here is a simplified version of my 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;
        }
    }
}

Here is the ServiceConnection for the Binder:

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

I know this has to be an issue with the binding of the service because if I remove all of the binding code and just start the service, everything runs as it should. It is only when I add the binding code that I get this error.

It seems that you don't need to start and bind service again. please creating signing apk file after deleting below codes.

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

[EDIT]

I think it's proguard obfuscation, so please add the following codes to your proguard file.

# 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

Generally this problem happen because of proguard, If you add proguard into your project it'll stop some of functionality like this.

Just try to add your service module in proguard-rules.pro file by adding

-keep class {package-name}.{service-module-name}.** { *; }

For Example : > -keep class com.demo.service.** { *; }

this will add all services permission in proguard.

The ClassNotFoundException here has an empty message. Looking at the dalvik.system.BaseDexClassLoader source code, it throws a ClassNotFoundException with the name of the indicated class if it can't find it, therefore, you are passing an empty class name somewhere (namely, in the message that is handled by ActivityThread::handleReceiver . It would greatly help if you could provide the full stack trace (ie the handleMessage branch which delegates this handleReceiver call).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM