07-15 15:48:44.699 3430 3430 D AndroidRuntime: Shutting down VM
07-15 15:48:44.702 3430 3430 E AndroidRuntime: FATAL EXCEPTION: main
07-15 15:48:44.702 3430 3430 E AndroidRuntime: Process: com.sohu.sohuvideo, PID: 3430
07-15 15:48:44.702 3430 3430 E AndroidRuntime: java.lang.RuntimeException: Unable to resume activity {com.sohu.sohuvideo/com.sohu.sohuvideo.ui.BuyVipActivity}: java.lang.NullPointerException: uriString
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3992)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4024)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at android.app.servertransaction.ResumeActivityItem.execute(ResumeActivityItem.java:51)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at android.app.servertransaction.TransactionExecutor.executeLifecycleState(TransactionExecutor.java:145)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:70)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1926)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:106)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at android.os.Looper.loop(Looper.java:214)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6990)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: Caused by: java.lang.NullPointerException: uriString
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at android.net.Uri$StringUri.<init>(Uri.java:490)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at android.net.Uri$StringUri.<init>(Uri.java:480)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at android.net.Uri.parse(Uri.java:452)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at com.sohu.sohuvideo.paysdk.ui.dialog.ActivityCommodityPayResultDialogFragment.onCreateView(ActivityCommodityPayResultDialogFragment.java:159)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2698)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:320)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1187)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1356)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at androidx.fragment.app.FragmentManager.moveFragmentToExpectedState(FragmentManager.java:1434)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at androidx.fragment.app.FragmentManager.moveToState(FragmentManager.java:1497)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at androidx.fragment.app.BackStackRecord.executeOps(BackStackRecord.java:447)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at androidx.fragment.app.FragmentManager.executeOps(FragmentManager.java:2169)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:1992)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:1947)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:1849)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at androidx.fragment.app.FragmentController.execPendingActions(FragmentController.java:447)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at androidx.fragment.app.FragmentActivity.onResume(FragmentActivity.java:458)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at com.sohu.sohuvideo.ui.BaseActivity.onResume(BaseActivity.java:285)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at com.sohu.sohuvideo.ui.BuyVipActivity.onResume(BuyVipActivity.java:316)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1412)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at android.app.Activity.performResume(Activity.java:7611)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3984)
07-15 15:48:44.702 3430 3430 E AndroidRuntime: ... 11 more
只是单纯解决这个异常很简单。不过,这边文章想说的是,我们可以从堆栈信息中了解一些知识。
从B Activity返回到A activity是先执行A的onActivityResult然后是onResume方法,在onActivityResult中把Fragment添加到A activity中的。
那为啥Fragment的onCreateView的执行过程是从Activity的onResume方法开始的呢?
这个就要从我们使用的Fragment commit方式说起了,我们采用的是commitAllowingStateLoss,commitAllowingStateLoss和commit方式都不是及时的,是主线程异步的,主线程异步指的是不在当前消息的执行体内,而是在Looper的下一个消息执行体内,而且会把之前所有提交还没执行的commit都执行。这个可以从源码中知道
* Schedules the execution when one hasn't been scheduled already. This should happen
* the first time {@link #enqueueAction(OpGenerator, boolean)} is called or when
* a postponed transaction has been started with
* {@link Fragment#startPostponedEnterTransition()}
@SuppressWarnings("WeakerAccess")
void scheduleCommit() {
synchronized (mPendingActions) {
boolean postponeReady =
mPostponedTransactions != null && !mPostponedTransactions.isEmpty();
boolean pendingReady = mPendingActions.size() == 1;
if (postponeReady || pendingReady) {
mHost.getHandler().removeCallbacks(mExecCommit);
mHost.getHandler().post(mExecCommit);
updateOnBackPressedCallbackEnabled();
private Runnable mExecCommit = new Runnable() {
@Override
public void run() {
execPendingActions(true);
* Only call from main thread!
boolean execPendingActions(boolean allowStateLoss) {
ensureExecReady(allowStateLoss);
boolean didSomething = false;
while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
mExecutingActions = true;
try {
removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
} finally {
cleanupExec();
didSomething = true;
updateOnBackPressedCallbackEnabled();
doPendingDeferredStart();
mFragmentStore.burpActive();
return didSomething;
如果按照真是按照上面讲的逻辑执行的话,执行逻辑应该是Handler的callback方法,mHost.getHandler()是new出来的一个Handler,不是ActivityThread$H这个handler,大家想想,平时new一个handler执行一个runnable是一个怎么样的调用堆栈。
可是,实际情况走的却是onResume,这个就需要看看onResume源码了
* Dispatch onResume() to fragments. Note that for better inter-operation
* with older versions of the platform, at the point of this call the
* fragments attached to the activity are <em>not</em> resumed.
@Override
protected void onResume() {
super.onResume();
mResumed = true;
mFragments.noteStateNotSaved();
mFragments.execPendingActions();
看到没,也调用了execPendingActions方法。同时也说明了一个问题,onActivityResult和onResume是在一个消息的执行体内,因为如果不在,就很难保证是先执行onResume还是先执行mExecCommit。而且我们也知道commit是主线程异步,也不只是绝对的。
把commitAllowingStateLoss换成commitNowAllowingStateLoss,让Fragment立即执行