华为9.0无限奔溃问题java.lang.NullPointerException:Attempt to invoke virtual method 'void android.app.Frag...

  • 好多用户反馈说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        }
2814
2815        ComponentName component = r.intent.getComponent();
2816        if (component == null) {
2817            component = r.intent.resolveActivity(
2818                mInitialApplication.getPackageManager());
2819            r.intent.setComponent(component);
2820        }
2821
2822        if (r.activityInfo.targetActivity != null) {
2823            component = new ComponentName(r.activityInfo.packageName,
2824                    r.activityInfo.targetActivity);
2825        }
2826
2827        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 " + component
2843                    + ": " + e.toString(), e);
2844            }
2845        }
2846
2847        try {
2848            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
2849
2850            if (localLOGV) Slog.v(TAG, "Performing launch of " + r);
2851            if (localLOGV) Slog.v(
2852                    TAG, r + ": app=" + app
2853                    + ", appName=" + app.getPackageName()
2854                    + ", pkg=" + r.packageInfo.getPackageName()
2855                    + ", comp=" + r.intent.getComponent().toShortString()
2856                    + ", dir=" + r.packageInfo.getAppDir());
2857
2858            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);
2877
2878                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                }
2888
2889                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);
2903
2904            mActivities.put(r.token, r);
2905
2906        } catch (SuperNotCalledException e) {
2907            throw e;
2908
2909        } catch (Exception e) {
2910            if (!mInstrumentation.onException(activity, e)) {
2911                throw new RuntimeException(
2912                    "Unable to start activity " + component
2913                    + ": " + e.toString(), e);
2914            }
2915        }
2916
2917        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);
7052
7053        mFragments.attachHost(null /*parent*/);
7054
7055        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();
7067
7068        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        }
7089
7090        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;
7099
7100        mWindow.setColorMode(info.colorMode);
7101
7102        setAutofillCompatibilityEnabled(application.isAutofillCompatibilityEnabled());
7103        enableAutofillCompatibilityIfNeeded();
7104    }
7105
7106    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*/);
324
325        super.onCreate(savedInstanceState);
326
327        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);
335
336            // 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        }
353
354        if (mPendingFragmentActivityResults == null) {
355            mPendingFragmentActivityResults = new SparseArrayCompat<>();
356            mNextCandidateRequestIndex = 0;
357        }
358
359        mFragments.dispatchCreate();
360    }

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容