继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

无限奔溃问题java.lang.NullPointerException:Attem

慕村9548890
关注TA
已关注
手记 1249
粉丝 227
获赞 989
  • 好多用户反馈说app在华为9.0系统上无法打开APP,于是自己运行没问题,然后从应用市场下载下来安装果然GG

  • 问题排查看到的奔溃日志如下:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.bdqn.kegongchang/xxxx.ui.activity.ActivitySplash}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.FragmentController.attachHost(android.app.Fragment)' on a null object reference
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3300)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3484)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:86)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2123)
        at android.os.Handler.dispatchMessage(Handler.java:109)
        at android.os.Looper.loop(Looper.java:207)
        at android.app.ActivityThread.main

从奔溃日志中可以看到应该是在ActivityThreadperformLaunchActivity方法中调用FragmentController.attachHost方法FragmentController为空造成的空指针,由于是9.0我们查看9.0的源码,首先看看ActivityThreadperformLaunchActivity方法中奔溃位置

 private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {2809        ActivityInfo aInfo = r.activityInfo;2810        if (r.packageInfo == null) {2811            r.packageInfo = getPackageInfo(aInfo.applicationInfo, r.compatInfo,2812                    Context.CONTEXT_INCLUDE_CODE);2813        }28142815        ComponentName component = r.intent.getComponent();2816        if (component == null) {2817            component = r.intent.resolveActivity(2818                mInitialApplication.getPackageManager());2819            r.intent.setComponent(component);2820        }28212822        if (r.activityInfo.targetActivity != null) {2823            component = new ComponentName(r.activityInfo.packageName,2824                    r.activityInfo.targetActivity);2825        }28262827        ContextImpl appContext = createBaseContextForActivity(r);2828        Activity activity = null;2829        try {2830            java.lang.ClassLoader cl = appContext.getClassLoader();2831            activity = mInstrumentation.newActivity(2832                    cl, component.getClassName(), r.intent);2833            StrictMode.incrementExpectedActivityCount(activity.getClass());2834            r.intent.setExtrasClassLoader(cl);2835            r.intent.prepareToEnterProcess();2836            if (r.state != null) {2837                r.state.setClassLoader(cl);2838            }2839        } catch (Exception e) {2840            if (!mInstrumentation.onException(activity, e)) {2841                throw new RuntimeException(2842                    "Unable to instantiate activity " + component2843                    + ": " + e.toString(), e);2844            }2845        }28462847        try {2848            Application app = r.packageInfo.makeApplication(false, mInstrumentation);28492850            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);2851            if (localLOGV) Slog.v(2852                    TAG, r + ": app=" + app2853                    + ", appName=" + app.getPackageName()2854                    + ", pkg=" + r.packageInfo.getPackageName()2855                    + ", comp=" + r.intent.getComponent().toShortString()2856                    + ", dir=" + r.packageInfo.getAppDir());28572858            if (activity != null) {2859                CharSequence title = r.activityInfo.loadLabel(appContext.getPackageManager());2860                Configuration config = new Configuration(mCompatConfiguration);2861                if (r.overrideConfig != null) {2862                    config.updateFrom(r.overrideConfig);2863                }2864                if (DEBUG_CONFIGURATION) Slog.v(TAG, "Launching activity "2865                        + r.activityInfo.name + " with config " + config);2866                Window window = null;2867                if (r.mPendingRemoveWindow != null && r.mPreserveWindow) {2868                    window = r.mPendingRemoveWindow;2869                    r.mPendingRemoveWindow = null;2870                    r.mPendingRemoveWindowManager = null;2871                }2872                appContext.setOuterContext(activity);2873                activity.attach(appContext, this, getInstrumentation(), r.token,2874                        r.ident, app, r.intent, r.activityInfo, title, r.parent,2875                        r.embeddedID, r.lastNonConfigurationInstances, config,2876                        r.referrer, r.voiceInteractor, window, r.configCallback);28772878                if (customIntent != null) {2879                    activity.mIntent = customIntent;2880                }2881                r.lastNonConfigurationInstances = null;2882                checkAndBlockForNetworkAccess();2883                activity.mStartedActivity = false;2884                int theme = r.activityInfo.getThemeResource();2885                if (theme != 0) {2886                    activity.setTheme(theme);2887                }28882889                activity.mCalled = false;2890                if (r.isPersistable()) {2891                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);2892                } else {2893                    mInstrumentation.callActivityOnCreate(activity, r.state);2894                }2895                if (!activity.mCalled) {2896                    throw new SuperNotCalledException(2897                        "Activity " + r.intent.getComponent().toShortString() +2898                        " did not call through to super.onCreate()");2899                }2900                r.activity = activity;2901            }2902            r.setState(ON_CREATE);29032904            mActivities.put(r.token, r);29052906        } catch (SuperNotCalledException e) {2907            throw e;29082909        } catch (Exception e) {2910            if (!mInstrumentation.onException(activity, e)) {2911                throw new RuntimeException(2912                    "Unable to start activity " + component2913                    + ": " + e.toString(), e);2914            }2915        }29162917        return activity;2918    }2919

从最后面的catch可以看到奔溃的位置应该是在2847下面其中某行,这里就不卖关子奔溃的具体位置是在2873行的activity.attach方法中,我们进去看看

  final void attach(Context context, ActivityThread aThread,7045            Instrumentation instr, IBinder token, int ident,7046            Application application, Intent intent, ActivityInfo info,7047            CharSequence title, Activity parent, String id,7048            NonConfigurationInstances lastNonConfigurationInstances,7049            Configuration config, String referrer, IVoiceInteractor voiceInteractor,7050            Window window, ActivityConfigCallback activityConfigCallback) {7051        attachBaseContext(context);70527053        mFragments.attachHost(null /*parent*/);70547055        mWindow = new PhoneWindow(this, window, activityConfigCallback);7056        mWindow.setWindowControllerCallback(this);7057        mWindow.setCallback(this);7058        mWindow.setOnWindowDismissedCallback(this);7059        mWindow.getLayoutInflater().setPrivateFactory(this);7060        if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {7061            mWindow.setSoftInputMode(info.softInputMode);7062        }7063        if (info.uiOptions != 0) {7064            mWindow.setUiOptions(info.uiOptions);7065        }7066        mUiThread = Thread.currentThread();70677068        mMainThread = aThread;7069        mInstrumentation = instr;7070        mToken = token;7071        mIdent = ident;7072        mApplication = application;7073        mIntent = intent;7074        mReferrer = referrer;7075        mComponent = intent.getComponent();7076        mActivityInfo = info;7077        mTitle = title;7078        mParent = parent;7079        mEmbeddedID = id;7080        mLastNonConfigurationInstances = lastNonConfigurationInstances;7081        if (voiceInteractor != null) {7082            if (lastNonConfigurationInstances != null) {7083                mVoiceInteractor = lastNonConfigurationInstances.voiceInteractor;7084            } else {7085                mVoiceInteractor = new VoiceInteractor(voiceInteractor, this, this,7086                        Looper.myLooper());7087            }7088        }70897090        mWindow.setWindowManager(7091                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),7092                mToken, mComponent.flattenToString(),7093                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);7094        if (mParent != null) {7095            mWindow.setContainer(mParent.getWindow());7096        }7097        mWindowManager = mWindow.getWindowManager();7098        mCurrentConfig = config;70997100        mWindow.setColorMode(info.colorMode);71017102        setAutofillCompatibilityEnabled(application.isAutofillCompatibilityEnabled());7103        enableAutofillCompatibilityIfNeeded();7104    }71057106    private void enableAutofillCompatibilityIfNeeded() {7107        if (isAutofillCompatibilityEnabled()) {7108            final AutofillManager afm = getSystemService(AutofillManager.class);7109            if (afm != null) {7110                afm.enableCompatibilityMode();7111            }7112        }7113    }

我们看到在7053行找到了奔溃的位置,那么mFragments他是什么,他在什么时候初始化的

832    final FragmentController mFragments = FragmentController.createController(new HostCallbacks());

activity的832行看到他是个成员变量activity创建的时候一起创建了,按道理说这里应该不可能为空啊,到这里没有其他思路了,我们还有一个APP没问题,想到能不能看看有啥区别,最终发现是集成的FragmentActivity而我们奔溃的是APP是继承与actiivity这个项目比较老,有没有可能是这问题,于是看看FragmentActivity

   protected void onCreate(@Nullable Bundle savedInstanceState) {323        mFragments.attachHost(null /*parent*/);324325        super.onCreate(savedInstanceState);326327        NonConfigurationInstances nc =328                (NonConfigurationInstances) getLastNonConfigurationInstance();329        if (nc != null) {330            mViewModelStore = nc.viewModelStore;331        }332        if (savedInstanceState != null) {333            Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);334            mFragments.restoreAllState(p, nc != null ? nc.fragments : null);335336            // Check if there are any pending onActivityResult calls to descendent Fragments.337            if (savedInstanceState.containsKey(NEXT_CANDIDATE_REQUEST_INDEX_TAG)) {338                mNextCandidateRequestIndex =339                        savedInstanceState.getInt(NEXT_CANDIDATE_REQUEST_INDEX_TAG);340                int[] requestCodes = savedInstanceState.getIntArray(ALLOCATED_REQUEST_INDICIES_TAG);341                String[] fragmentWhos = savedInstanceState.getStringArray(REQUEST_FRAGMENT_WHO_TAG);342                if (requestCodes == null || fragmentWhos == null ||343                            requestCodes.length != fragmentWhos.length) {344                    Log.w(TAG, "Invalid requestCode mapping in savedInstanceState.");345                } else {346                    mPendingFragmentActivityResults = new SparseArrayCompat<>(requestCodes.length);347                    for (int i = 0; i < requestCodes.length; i++) {348                        mPendingFragmentActivityResults.put(requestCodes[i], fragmentWhos[i]);349                    }350                }351            }352        }353354        if (mPendingFragmentActivityResults == null) {355            mPendingFragmentActivityResults = new SparseArrayCompat<>();356            mNextCandidateRequestIndex = 0;357        }358359        mFragments.dispatchCreate();360    }

FragmentActivity我们发现他调用mFragments.attachHost(null /*parent*/);是在onCreate中,而activity是在attch中,他初始化FragmentController也是在创建的时候初始化的,看到这里应该没啥区别了,就是初始化时机不一样,到此问题原因分析完了,但是具体怎么导致的确实没找到,我们换成FragmentActivity成功解决,这里目前只能说是华为room存在一定适配问题。



作者:Lazy1
链接:https://www.jianshu.com/p/da79c8f1a6d5


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP