2023年6月27日发(作者:)
android启动流程分析,Android绘制流程窗⼝启动流程分析(上)源码分析篇 - Android绘制流程(⼀)窗⼝启动流程分析Activity、View、Window之间的关系可以⽤以下的简要UML关系图表⽰,在这⾥贴出来,⽐较能够帮组后⾯流程分析部分的阅读。⼀、Activity的启动流程在startActivity()后,经过⼀些逻辑流程会通知到ActivityManagerService(后⾯以AMS简称),AMS接收到启动acitivty的请求后,会通过跨进程通信调⽤LauncherActivity()⽅法,我们从这⾥开始分析,⾸先来看handleLauncherActivity()⽅法。`private void handleLaunchActivity(ActivityClientRecord r, Intent customIntent, String reason) {...// Initialize before creating the lize();Activitya = performLaunchActivity(r, customIntent);if (a != null) { dConfig = new Configuration(mConfiguration); reportSizeConfigurations(r); Bundle oldState = ;//该⽅法会调⽤到Activity的onResume()⽅法 handleResumeActivity(, false, ard, !hed && !NotResumed, ocessedSeq, reason);...}...}`这⾥重点关注三个⽅法(加粗的地⽅),⾸先来看lize(),WindowManagerGlobal是单例模式的,⼀个进程内只有⼀个,这⾥调⽤该类的初始化⽅法,后续我们再对该类的作⽤和相关⽅法进⾏分析;第三个是在创建好Activity后调⽤Acitivty的onResume()⽅法。这⾥我们来看需关注的第⼆个⽅法performLaunchActivity(),代码如下。private ActivityperformLaunchActivity(ActivityClientRecord r, Intent customIntent) { ...//通过反射⽅式创建Activity Activityactivity =null;try{ oader cl = ssLoader(); activity =ivity( cl, ssName(), );
entExpectedActivityCount(ss()); rasClassLoader(cl);
eToEnterProcess();if( !=null) { ssLoader(cl); } }catch(Exception e){if(!ption(activity, e)) {thrownewRuntimeException("Unable to instantiate activity "+ component
+": "+ ng(), e); } }try{ ...if(activity !=null) { Context appContext =createBaseContextForActivity(r, activity); CharSequence title =bel(kageManager()); Configuration config=newConfiguration(mCompatConfiguration);if(deConfig !=null) { From(deConfig);
}if(DEBUG_CONFIGURATION) Slog.v(TAG,"Launching activity "+ +" with config "+ config);
Windowwindow=null;if(ngRemoveWindow !=null&& rveWindow) {window= ngRemoveWindow;
ngRemoveWindow =null; ngRemoveWindowManager =null; }
(appContext,this, getInstrumentation(), , , app, , tyInfo, title, ,
edID, nConfigurationInstances, config, er, nteractor,window); ...//调⽤acitivity的onCreate()⽅法if(istable()) { tivityOnCreate(activity, , tentState); }else{
tivityOnCreate(activity, ); } ... }returnactivity; }这个⽅法主要是读取Acitivity这⾥利⽤反射创建出ActivityClientRecord所要求的Activity对象,然后调⽤了()⽅法。注意attach()传⼊的参数有很多,在performLacunchActivity()⽅法流程中,调⽤attach()⽅前,我们省略掉的步骤基本都在为这些参数做准备,attach()⽅法的作⽤其实就是将这些参数配置到新创建的Activity对象中;⽽在attach之后则会回调到acitivity的onCreate()⽅法。我们进⼊类详细来看下attach⽅法。此外,在attach之前会初始化⼀个Window对象,是⼀个抽象类,代表了⼀个矩形不可见的容器,主要负责加载显⽰界⾯,每个Activity都会对应了⼀个Window对象。如果ngRevomeWindow变量中已经保存了⼀个Window对象,则会在后⾯的attach⽅法中被使⽤,具体使⽤的场景会在后⾯中介绍。`final void attach(Context context, ActivityThread aThread,Instrumentation instr, IBinder token, int ident,Application application, Intent intent, ActivityInfo info,CharSequence title, Activity parent, String id,NonConfigurationInstances lastNonConfigurationInstances,Configuration config, String referrer, IVoiceInteractor voiceInteractor,Window window) {attachBaseContext(context);Host(null/*parent*/); mWindow=newPhoneWindow(this,window);//(1)dowControllerCallback(this); lback(this);
indowDismissedCallback(this);
outInflater().setPrivateFactory(this);if(putMode !=_INPUT_STATE_UNSPECIFIED) {
tInputMode(putMode); }if(ons !=0) { ptions(ons); } ...//初始化Acitity相关属性dowManager(
(WindowManager)temService(_SERVICE), mToken, nToString(),
( & _HARDWARE_ACCELERATED) !=0);//(2)if(mParent !=null) {
tainer(dow()); } mWindowManager = dowManager();
mCurrentConfig = config;}`重点关注初始化window对象的操作,⾸先创建了PhoneWindow对象为activity的mWindow变量,在创建时传⼊了上⼀个activity对应的window对象,之后⼜将这个acitivity设置为window对象的回调。Activity中很多操作view相关的⽅法,例如setContentView()、findViewById()、getLayoutInflater()等,实际上都是直接调⽤到PhoneWindow⾥⾯的相关⽅法。创建完acitivty对应的PhoneWindow之后便会调⽤setWindowManager()⽅法。⾸先来看PhonewWindow构造⽅法。publicPhoneWindow(Context context, WindowpreservedWindow){this(context);// Only main activity windows use decor context, all the other windows depend onwhatever// context that was given to corContext =true;if(preservedWindow !=null) {//快速重启activity机制mDecor = (DecorView) orView(); mElevation = vation();
mLoadElevation =false; mForceDecorInstall =true;// If we're preserving window, carry over the app token from thepreserved// window, as we'll be skipping the addView in handleResumeActivity(), and// the token will not be updated as fora new ributes().token = ributes().token; }// Even though the device doesn'tsupport picture-in-picture mode,// an user can force using it through developer nforceResizable =(tentResolver(), DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES,0) !=0;
mSupportsPictureInPicture = forceResizable || kageManager().hasSystemFeature(
E_PICTURE_IN_PICTURE); }点击下⽅链接免费获取Android进阶资料:
发布者:admin,转转请注明出处:http://www.yc00.com/xiaochengxu/1687842101a49997.html
评论列表(0条)