zoukankan      html  css  js  c++  java
  • Android 多进程引发的一次crash

    问题现象:

      应用内操作后出现空指针异常

    问题日志:

     1  FATAL EXCEPTION: main
     2 04-19 10:46:15.507 E/AndroidRuntime(23919): Process: com.test.test:remote, PID: 23919
     3 04-19 10:46:15.507 E/AndroidRuntime(23919): java.lang.RuntimeException: Error receiving broadcast Intent { act=android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT cat=[android.bluetooth.headset.intent.category.companyid.85] flg=0x10 (has extras) } in com.xupin.poclibrary.tool.bluetooth.BluetoothManager$2@256db6d
     4 04-19 10:46:15.507 E/AndroidRuntime(23919):     at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0$LoadedApk$ReceiverDispatcher$Args(LoadedApk.java:1712)
     5 04-19 10:46:15.507 E/AndroidRuntime(23919):     at android.app.-$$Lambda$LoadedApk$ReceiverDispatcher$Args$_BumDX2UKsnxLVrE6UJsJZkotuA.run(Unknown Source:2)
     6 04-19 10:46:15.507 E/AndroidRuntime(23919):     at android.os.Handler.handleCallback(Handler.java:883)
     7 04-19 10:46:15.507 E/AndroidRuntime(23919):     at android.os.Handler.dispatchMessage(Handler.java:100)
     8 04-19 10:46:15.507 E/AndroidRuntime(23919):     at android.os.Looper.loop(Looper.java:238)
     9 04-19 10:46:15.507 E/AndroidRuntime(23919):     at android.app.ActivityThread.main(ActivityThread.java:7823)
    10 04-19 10:46:15.507 E/AndroidRuntime(23919):     at java.lang.reflect.Method.invoke(Native Method)
    11 04-19 10:46:15.507 E/AndroidRuntime(23919):     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:512)
    12 04-19 10:46:15.507 E/AndroidRuntime(23919):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1017)
    13 04-19 10:46:15.507 E/AndroidRuntime(23919): Caused by: java.lang.NullPointerException: Attempt to read from field 'com.test.test.tool.entity.SessionEntity com.test.test.services.TestServices.callingSession' on a null object reference
    14 04-19 10:46:15.507 E/AndroidRuntime(23919):     at com.test.test.tool.bluetooth.BluetoothManager.handlePttBtnDown(BluetoothManager.java:469)
    15 04-19 10:46:15.507 E/AndroidRuntime(23919):     at com.test.test.tool.bluetooth.BluetoothManager.access$300(BluetoothManager.java:42)
    16 04-19 10:46:15.507 E/AndroidRuntime(23919):     at com.test.test.tool.bluetooth.BluetoothManager$2.onReceive(BluetoothManager.java:521)
    17 04-19 10:46:15.507 E/AndroidRuntime(23919):     at android.app.LoadedApk$ReceiverDispatcher$Args.lambda$getRunnable$0$LoadedApk$ReceiverDispatcher$Args(LoadedApk.java:1677)

    定位分析:

      crash 发生在remote进程(百度地图服务进程),而且分析,应用正常启动后 TestServices 该单例不可能为空,且通过日志发现动态注册的监听器会触发两次。

    解决:

      添加主进程判断:

      Copyed from Android Jetpack 中WorkManager库中的GreedyScheduler.java 

    public class ProcessUtil {
        private static final String TAG = "ProcessUtil";
    
        public static boolean isMainProcess(Context context) {
            String packageName = context.getPackageName();
            String processName = getProcessName(context);
            Log.d(TAG, "package name:" + packageName + " process name:" + processName);
            return TextUtils.equals(context.getPackageName(), getProcessName(context));
        }
    
        @Nullable
        public static String getProcessName(Context context) {
            if (SDK_INT >= 28) {
                return Application.getProcessName();
            }
    
            // Try using ActivityThread to determine the current process name.
            try {
                Class<?> activityThread = Class.forName(
                        "android.app.ActivityThread",
                        false,
                        MyApplication.class.getClassLoader());
                final Object packageName;
                if (SDK_INT >= 18) {
                    Method currentProcessName = activityThread.getDeclaredMethod("currentProcessName");
                    currentProcessName.setAccessible(true);
                    packageName = currentProcessName.invoke(null);
                } else {
                    Method getActivityThread = activityThread.getDeclaredMethod(
                            "currentActivityThread");
                    getActivityThread.setAccessible(true);
                    Method getProcessName = activityThread.getDeclaredMethod("getProcessName");
                    getProcessName.setAccessible(true);
                    packageName = getProcessName.invoke(getActivityThread.invoke(null));
                }
                if (packageName instanceof String) {
                    return (String) packageName;
                }
            } catch (Throwable exception) {
                Log.d("TAG", "Unable to check ActivityThread for processName", exception);
            }
    
            // Fallback to the most expensive way
            int pid = android.os.Process.myPid();
            ActivityManager am =
                    (ActivityManager) context.getSystemService(ACTIVITY_SERVICE);
    
            if (am != null) {
                List<ActivityManager.RunningAppProcessInfo> processes = am.getRunningAppProcesses();
                if (processes != null && !processes.isEmpty()) {
                    for (ActivityManager.RunningAppProcessInfo process : processes) {
                        if (process.pid == pid) {
                            return process.processName;
                        }
                    }
                }
            }
    
            return null;
        }
    }

    参考文档

      https://yuanfentiank789.github.io/2017/10/26/Android%E5%BA%94%E7%94%A8%E5%86%85%E5%A4%9A%E8%BF%9B%E7%A8%8B%E5%88%86%E6%9E%90%E5%92%8C%E7%A0%94%E7%A9%B6/

      https://stackoverflow.com/questions/6954027/detecting-if-youre-in-the-main-process-or-the-remote-service-process-in-applica/36256085

  • 相关阅读:
    springmvc下的web.xml的配置
    Java利用Xstream注解生成和解析xml
    第十二章 多态性与抽象类
    第十一章 继承与派生 学习笔记
    车辆选择(继承)
    5-3 两点间距离计算
    5-2 时间模拟
    5-5 多边形周长计算(继承)
    4-5 求自定类型元素的最大值 (10分)
    4-4 求自定类型元素的平均 (10分)
  • 原文地址:https://www.cnblogs.com/kelisi-king/p/14677939.html
Copyright © 2011-2022 走看看