仅在生产版本中的应用程序加载上的RuntimeException

时间:2017-10-16 21:32:04

标签: java android android-service android-service-binding

我正在创建一个我正在创建的应用程序的问题。基本上,当你第一次尝试打开它时,应用程序会崩溃,之后它就会好起来。令人困惑的部分是它只在您从Google Play下载应用时才会发生。如果我直接从Android Studio在手机上加载应用程序,我不会收到任何错误。

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)

在研究了这个问题后,我发现有人说要清除设备的缓存。这解决了这个问题......但是这只是擦除了应用程序,从那时起就可以正常工作。初始安装仍然崩溃。这发生在多个设备上,但我无法在调试时重现它。我唯一想到的是,在调用setContentView()之后,我在onCreate()中有了这段代码。

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

NotificationListener.class扩展了NotificationListenerService。除了首次发布之外,一切都很有效。

更新

以下是我在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>

以下是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;
        }
    }
}

以下是Binder的ServiceConnection:

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

我知道这必须是服务绑定的问题,因为如果我删除所有绑定代码并启动服务,一切都按预期运行。只有当我添加绑定代码时才会出现此错误。

3 个答案:

答案 0 :(得分:2)

您似乎不需要再次启动和绑定服务。请在删除以下代码后创建签名apk文件。

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

[编辑]

我认为它是程序混淆,所以请将以下代码添加到您的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

答案 1 :(得分:0)

通常这个问题是因为proguard而发生的,如果你将proguard添加到你的项目中它会停止这样的一些功能。

只需尝试通过添加

proguard-rules.pro 文件中添加服务模块
  

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

     

例如:&gt; -keep class com.demo.service。** {*; }

这将在proguard中添加所有服务权限。

答案 2 :(得分:0)

这里的let myArr = [ {name: "john", age:23}, {name: "john", age:43}, {name: "jim", age:101}, {name: "bob", age:67}, ]; let list = _.filter(myArr, item => item.name === "john");有一条空信息。查看ClassNotFoundException源代码,如果找不到它,它会抛出一个带有指定类名称的dalvik.system.BaseDexClassLoader,因此,您在某处传递一个空类名(即在消息中)由ClassNotFoundException处理。如果你能提供完整的堆栈跟踪(即委托此ActivityThread::handleReceiver调用的handleMessage分支),将会有很大帮助。