9

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.

sabo
  • 911
  • 13
  • 37
  • Could you try creating apk file without proguard if you do? – kimkevin Oct 17 '17 at 02:10
  • 1
    @KimKevin Does that just involve removing the entry for it in the buildTypes in the app gradle? If so, I removed it and uploaded a beta version of my app and still got the same error on launch. – sabo Oct 17 '17 at 02:49
  • yes it is. minifyEnabled sets as false. or because ClassNotFoundException occurred ... did you register NotificationListenerService to AndroidManifest.xml? – kimkevin Oct 17 '17 at 02:53
  • 1
    @KimKevin I removed the proguard and set minifyEnabled to false. Yes I put the NotificationListenerService in the manifest as a service. – sabo Oct 17 '17 at 03:05
  • It's my mistake. NotificationListener should be set in AndroidManifest.xml. pretty sure you did... – kimkevin Oct 17 '17 at 03:08
  • please add NotificationListener and AndroidManifest codes. – kimkevin Oct 17 '17 at 03:09
  • 1
    @KimKevin Please see my edit. I'm curious after looking through the documentation some more if the intent-filter on the service in the manifest could be an issue. – sabo Oct 17 '17 at 03:23
  • Thank you for sharing and editing. I think you need to check NotificationListener.class file in build folder (maybe path is build/intermediates/classes/your_package/NotificationListener). please rebuild before looking for it. – kimkevin Oct 17 '17 at 03:41
  • @KimKevin I found it where you said. – sabo Oct 17 '17 at 03:48

3 Answers3

2

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
kimkevin
  • 2,202
  • 1
  • 26
  • 48
  • I went ahead and removed the startService() call since it bindService() should handle it. It still crashes though. I want to see if the error changed but I don't get any crashes for the beta for some reason. – sabo Oct 17 '17 at 19:29
  • Yeah I still get the same error when I remove the startService(). – sabo Oct 18 '17 at 02:53
  • I don't have experience dealing with the proguard files so I went ahead and added that to both my proguard-android.txt-2.3.3 file and to my aapt_rules.txt file. It still crashes though. – sabo Oct 18 '17 at 14:51
  • Any other ideas on this? Was that proguard-android.txt-2.3.3 file the right file to put those changes you mentioned? – sabo Oct 20 '17 at 13:34
0

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.

Vikrant Shah
  • 547
  • 1
  • 4
  • 18
  • Can I just remove proguard if having it causes an issue? – sabo Nov 06 '17 at 03:07
  • Every things has there own pros and cons, Proguard has also.it'll provide you good security and many other features too. So, my opinion is to add this files to proguard-rules.pro file instead of totally removing it. – Vikrant Shah Nov 06 '17 at 05:31
0

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 (i.e. the handleMessage branch which delegates this handleReceiver call).

Piotr Wilkin
  • 3,446
  • 10
  • 18