Android开发之Activity 生命周期函数执行过程详解
白羽 2018-06-05 来源 :网络 阅读 1016 评论 0

摘要:Activity 生命周期函数执行过程详解,平时开发中接触到Android的启动以及各种生命周期函数,但是其背后的执行过程是怎么样的呢?本文从源码的角度来分析activity的启动以及它的生命周期函数。希望本文对大家学Android有所帮助


Activity 生命周期函数执行过程详解,平时开发中接触到Android的启动以及各种生命周期函数,但是其背后的执行过程是怎么样的呢?本文从源码的角度来分析activity的启动以及它的生命周期函数。
 

关键的类

 

在分析源码之前,先了解下几个关键的类的作用:

ActivityManagerService:activity的启动以及生命周期都统一由ActivityManagerService管理,而ActivityManagerService处于SystemServer进程中,应用程序进程通过Binder机制与SystemServer进程进行通信。

ActivityManagerProxy:是ActivityManagerService在客户端的代理,客户端通过ActivityManageProxy间接调用ActivityManagerService。

ActivityThread:应用程序的主线程ActivityThread,也是应用程序的入口;消息循环机制的创建、初始化信息等都在ActivityThread中完成。

ApplicationThread:用来实现ActivityManagerService与ActivityThread之间的交互。在ActivityManagerService需要管理相关Application中的Activity的生命周期时,通过ApplicationThread的代理对象与ActivityThread通讯。

ApplicationThreadProxy:是ApplicationThread在服务器端的代理,负责和客户端的ApplicationThread通讯。AMS就是通过该代理与ActivityThread进行通信的。

Instrumentation:每一个应用程序只有一个Instrumentation对象,每个Activity内都有一个对该对象的引用。Instrumentation可以理解为应用进程的管家,ActivityThread要创建或暂停某个Activity时,都需要通过Instrumentation来进行具体的操作。
 

Activity的启动流程

 

分析Activity的启动流程,那就从startActivity()分析吧
   
@Override
public void startActivity(Intent intent, @Nullable Bundle options) {
    if (options != null) {
        startActivityForResult(intent, -1, options);
    } else {
        // Note we want to go through this call for compatibility with
        // applications that may have overridden the method.
        startActivityForResult(intent, -1);
    }
}
   
调用startActivity()直接调用startActivityForResult()
   
public void startActivityForResult(Intent intent, int requestCode, @Nullable Bundle options) {
       if (mParent == null) {
           Instrumentation.ActivityResult ar =
               mInstrumentation.execStartActivity(
                   this, mMainThread.getApplicationThread(), mToken, this,
                   intent, requestCode, options);
           if (ar != null) {
               mMainThread.sendActivityResult(
                   mToken, mEmbeddedID, requestCode, ar.getResultCode(),
                   ar.getResultData());
           }
           if (requestCode >= 0) {
 
               mStartedActivity = true;
           }
 
           final View decor = mWindow != null ? mWindow.peekDecorView() : null;
           if (decor != null) {
               decor.cancelPendingInputEvents();
           }
       } else {
           if (options != null) {
               mParent.startActivityFromChild(this, intent, requestCode, options);
           } else {
 
               mParent.startActivityFromChild(this, intent, requestCode);
           }
       }
       if (options != null && !isTopOfTask()) {
           mActivityTransitionState.startExitOutTransition(this, options);
       }
   }
   
当mParent == null时,调用了Instrumentation的execStartActivity()方法,不为空时调用startActivityFromChild(),先来看看startActivityFromChild()
   
public void startActivityFromChild(@NonNull Activity child, Intent intent,
        int requestCode, @Nullable Bundle options) {
    Instrumentation.ActivityResult ar =
        mInstrumentation.execStartActivity(
            this, mMainThread.getApplicationThread(), mToken, child,
            intent, requestCode, options);
    if (ar != null) {
        mMainThread.sendActivityResult(
            mToken, child.mEmbeddedID, requestCode,
            ar.getResultCode(), ar.getResultData());
    }
}
   
还是调用了Instrumentation的execStartActivity()方法,因为mInstrumentation对象在一个应用中只会存在一个实例,因此mParent是不是null都会执行Instrumentation的execStartActivity()方法
   
public ActivityResult execStartActivity(
          Context who, IBinder contextThread, IBinder token, Activity target,
          Intent intent, int requestCode, Bundle options) {
      IApplicationThread whoThread = (IApplicationThread) contextThread;
      if (mActivityMonitors != null) {
          synchronized (mSync) {
              final int N = mActivityMonitors.size();
              for (int i=0; i<n; activitymonitor="" am="mActivityMonitors.get(i);" final="" if="" requestcode="" return="">= 0 ? am.getResult() : null;
                      }
                      break;
                  }
              }
          }
      }
      try {
          intent.migrateExtraStreamToClipData();
          intent.prepareToLeaveProcess();
          int result = ActivityManagerNative.getDefault()
              .startActivity(whoThread, who.getBasePackageName(), intent,
                      intent.resolveTypeIfNeeded(who.getContentResolver()),
                      token, target != null ? target.mEmbeddedID : null,
                      requestCode, 0, null, options);
          checkStartActivityResult(result, intent);
      } catch (RemoteException e) {
      }
      return null;
  }</n;>
   
通过Instrumentation的execStartActivity()方法,会调用ActivityManagerNative.getDefault().startActivity(),而ActivityManagerNative通过Binder机制实现的,因此会通过ActivityManagerProxy调用ActivityManagerService来启动activity。
让我们总结一下activity的启动过程:Activity → Instrumentation → ActivityManagerProxy → ActivityManagerService。 
Activity的生命周期函数执行过程
 
上面分析了Activity的启动过程,当启动初始化activity之后,各个生命周期函数是怎么从ActivityManagerService到activity的呢?
以onResume()为例,首先来看ApplicationThreadProxy,位于SystemServer进程中
public final void scheduleResumeActivity(IBinder token, int procState, boolean isForward,
        Bundle resumeArgs)
        throws RemoteException {
    Parcel data = Parcel.obtain();
    data.writeInterfaceToken(IApplicationThread.descriptor);
    data.writeStrongBinder(token);
    data.writeInt(procState);
    data.writeInt(isForward ? 1 : 0);
    data.writeBundle(resumeArgs);
    mRemote.transact(SCHEDULE_RESUME_ACTIVITY_TRANSACTION, data, null,
            IBinder.FLAG_ONEWAY);
    data.recycle();
}
   
通过Binder机制,调用应用程序进程中的ApplicationThread对应的scheduleResumeActivity()函数
   
public final void scheduleResumeActivity(IBinder token, int processState,
             boolean isForward, Bundle resumeArgs) {
         updateProcessState(processState, false);
         sendMessage(H.RESUME_ACTIVITY, token, isForward ? 1 : 0);
}
   
而ApplicationThread通过sendMessage发送消息给H处理,其中H是ActivityThread的一个私有内部类,在main()函数中进行了初始化。
   
case RESUME_ACTIVITY:
     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
     handleResumeActivity((IBinder) msg.obj, true, msg.arg1 != 0, true);
     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
     break;
   
在H的handleMessage()函数中调用handleResumeActivity()函数
   
final void handleResumeActivity(IBinder token,
          boolean clearHide, boolean isForward, boolean reallyResume) {
 
 
      // TODO Push resumeArgs into the activity for consideration
      ActivityClientRecord r = performResumeActivity(token, clearHide);
 
      if (r != null) {
          final Activity a = r.activity;
 
 
          final int forwardBit = isForward ?
                  WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION : 0;
 
          boolean willBeVisible = !a.mStartedActivity;
          if (!willBeVisible) {
              try {
                  willBeVisible = ActivityManagerNative.getDefault().willActivityBeVisible(
                          a.getActivityToken());
              } catch (RemoteException e) {
              }
          }
          if (r.window == null && !a.mFinished && willBeVisible) {
              r.window = r.activity.getWindow();
              View decor = r.window.getDecorView();
              decor.setVisibility(View.INVISIBLE);
              ViewManager wm = a.getWindowManager();
              WindowManager.LayoutParams l = r.window.getAttributes();
              a.mDecor = decor;
              l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
              l.softInputMode |= forwardBit;
              if (a.mVisibleFromClient) {
                  a.mWindowAdded = true;
                  wm.addView(decor, l);
              }
 
 
          } else if (!willBeVisible) {
              if (localLOGV) Slog.v(
                  TAG, "Launch " + r + " mStartedActivity set");
              r.hideForNow = true;
          }
 
          // Get rid of anything left hanging around.
          cleanUpPendingRemoveWindows(r);
 
          // The window is now visible if it has been added, we are not
          // simply finishing, and we are not starting another activity.
          if (!r.activity.mFinished && willBeVisible
                  && r.activity.mDecor != null && !r.hideForNow) {
              if (r.newConfig != null) {
                  if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity "
                          + r.activityInfo.name + " with newConfig " + r.newConfig);
                  performConfigurationChanged(r.activity, r.newConfig);
                  freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.newConfig));
                  r.newConfig = null;
              }
              if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward="
                      + isForward);
              WindowManager.LayoutParams l = r.window.getAttributes();
              if ((l.softInputMode
                      & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION)
                      != forwardBit) {
                  l.softInputMode = (l.softInputMode
                          & (~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION))
                          | forwardBit;
                  if (r.activity.mVisibleFromClient) {
                      ViewManager wm = a.getWindowManager();
                      View decor = r.window.getDecorView();
                      wm.updateViewLayout(decor, l);
                  }
              }
              r.activity.mVisibleFromServer = true;
              mNumVisibleActivities++;
              if (r.activity.mVisibleFromClient) {
                  r.activity.makeVisible();
              }
          }
 
          if (!r.onlyLocalRequest) {
              r.nextIdle = mNewActivities;
              mNewActivities = r;
              if (localLOGV) Slog.v(
                  TAG, "Scheduling idle handler for " + r);
              Looper.myQueue().addIdleHandler(new Idler());
          }
          r.onlyLocalRequest = false;
 
          // Tell the activity manager we have resumed.
          if (reallyResume) {
              try {
                  ActivityManagerNative.getDefault().activityResumed(token);
              } catch (RemoteException ex) {
              }
          }
 
      } else {
          // If an exception was thrown when trying to resume, then
          // just end this activity.
          try {
              ActivityManagerNative.getDefault()
                  .finishActivity(token, Activity.RESULT_CANCELED, null, false);
          } catch (RemoteException ex) {
          }
      }
  }
   
在handleResumeActivity()调用了performResumeActivity()函数,并对view进行显示,同时通知ActivityManagerService已经完成resume.看看performResumeActivity()函数的实现
   
public final ActivityClientRecord performResumeActivity(IBinder token,
           boolean clearHide) {
       ActivityClientRecord r = mActivities.get(token);
       if (localLOGV) Slog.v(TAG, "Performing resume of " + r
               + " finished=" + r.activity.mFinished);
       if (r != null && !r.activity.mFinished) {
           if (clearHide) {
               r.hideForNow = false;
               r.activity.mStartedActivity = false;
           }
           try {
               r.activity.mFragments.noteStateNotSaved();
               if (r.pendingIntents != null) {
                   deliverNewIntents(r, r.pendingIntents);
                   r.pendingIntents = null;
               }
               if (r.pendingResults != null) {
                   deliverResults(r, r.pendingResults);
                   r.pendingResults = null;
               }
               r.activity.performResume();
 
               EventLog.writeEvent(LOG_ON_RESUME_CALLED,
                       UserHandle.myUserId(), r.activity.getComponentName().getClassName());
 
               r.paused = false;
               r.stopped = false;
               r.state = null;
               r.persistentState = null;
           } catch (Exception e) {
               if (!mInstrumentation.onException(r.activity, e)) {
                   throw new RuntimeException(
                       "Unable to resume activity "
                       + r.intent.getComponent().toShortString()
                       + ": " + e.toString(), e);
               }
           }
       }
       return r;
   }
   
其中 r.activity.performResume();执行resume,调用activity的performResume()函数。
   
final void performResume() {
    performRestart();
 
    mFragments.execPendingActions();
 
    mLastNonConfigurationInstances = null;
 
    mCalled = false;
    // mResumed is set by the instrumentation
    mInstrumentation.callActivityOnResume(this);
    if (!mCalled) {
        throw new SuperNotCalledException(
            "Activity " + mComponent.toShortString() +
            " did not call through to super.onResume()");
    }
 
    // Now really resume, and install the current status bar and menu.
    mCalled = false;
 
    mFragments.dispatchResume();
    mFragments.execPendingActions();
 
    onPostResume();
    if (!mCalled) {
        throw new SuperNotCalledException(
            "Activity " + mComponent.toShortString() +
            " did not call through to super.onPostResume()");
    }
}
   
而在activity的performResume()函数中调用了mInstrumentation.callActivityOnResume(this),
   
public void callActivityOnResume(Activity activity) {
    activity.mResumed = true;
    activity.onResume();
 
    if (mActivityMonitors != null) {
        synchronized (mSync) {
            final int N = mActivityMonitors.size();
            for (int i=0; i<n; activitymonitor="" am="mActivityMonitors.get(i);" final="" pre=""><p>Instrumentation的函数callActivityOnResume()执行了 activity.onResume()方法,至此,resume整个流程完成。</p><p>Resume执行过程:ApplicationThreadProxy → ApplicationThread → H → Activity → Instrumentation → Activity</p><h3 id="总结">总结</h3><hr><p>activity的启动过程:Activity → Instrumentation → ActivityManagerProxy → ActivityManagerService(SystemServer进程)。</p><p>生命周期函数执行过程:ApplicationThreadProxy(SystemServer进程) → ApplicationThread → H → Activity → Instrumentation → Activity</p>
    </n;>

   

 


本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之Android频道!


本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程