AMS和WMS部分知识点

1. 在WindowMangerImpl中调用addView方法是,需要获取Display对象,那么Display是从哪里来的?

WindowMangerImpl的addView方法

@Override
public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {
    applyDefaultToken(params);
    mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);
}

在ContextImpl的getDisplay()方法中获得

//ContextImpl.java
Display getDisplay() {
        if (mDisplay != null) {
            return mDisplay;
        }
        return ResourcesManager.getInstance().getAdjustedDisplay(
                Display.DEFAULT_DISPLAY, mDisplayAdjustments);
    }
  1. SystemServiceRegistry类是一个为Context提供获取各种系统服务在App中的包装类,例如WMS在App中的包装类是WindowManger
//服务注册,在静态代码块中完成
registerService(Context.WINDOW_SERVICE, WindowManager.class,
                new CachedServiceFetcher<WindowManager>() {
            @Override
            public WindowManager createService(ContextImpl ctx) {
            //创建WindowManagerImpl,和Display
                return new WindowManagerImpl(ctx.getDisplay());
            }});
            
//ContextImpl中获取系统服务的方法
@Override
public Object getSystemService(String name) {
    return SystemServiceRegistry.getSystemService(this, name);
}
  1. ActivitManagerNative对应AIDL中Stub类
  2. 所有的系统服务都是在SystemServer类中创建的
 // Create the system service manager.
 //所有服务的管理类
mSystemServiceManager = new SystemServiceManager(mSystemContext);
LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);

// Start services.
try {
    //创建AMS,PMS等服务
    startBootstrapServices();
    //创建BatteryService,WebViewUpdateService等
    startCoreServices();
    //创建IMS,WMS等服务
    startOtherServices();
} catch (Throwable ex) {
    
    throw ex;
}
  1. 在Handler中有个隐藏的runWithScissors(Runnabler, int timeout)方法,这是一个同步的方法,等待r执行完后再返还,在WMS创建过程中执行main()方法时有使用,目的是在未完成WMS创建之前阻塞SystemServer线程
public static WindowManagerService main(final Context context,
        final InputManagerService im,
        final boolean haveInputMethods, final boolean showBootMsgs,
        final boolean onlyCore) {
    final WindowManagerService[] holder = new WindowManagerService[1];
    DisplayThread.getHandler().runWithScissors(new Runnable() {
        @Override
        public void run() {
            holder[0] = new WindowManagerService(context, im,
                    haveInputMethods, showBootMsgs, onlyCore);
        }
    }, 0);
    return holder[0];
}

其中DisplayThread 继承自 ServiceThread,实际上是一个HandlerTread,目的是系统服务可以在自己的Looper中执行;
6. View的invalidate()方法执行过程:
invalidate()会调用到invalidateInternal方法;
其实postInvlidate()方法最后调用的也是invalidate()方法,只不过是通过ViewRootImpl内的handler做了延迟处理

void invalidateInternal(int l, int t, int r, int b, boolean invalidateCache,
        boolean fullInvalidate) {
    
    //省略代码
        // Propagate the damage rectangle to the parent view.
        final AttachInfo ai = mAttachInfo;
        //mParent的值是在哪里来的???
        final ViewParent p = mParent;
        if (p != null && ai != null && l < r && t < b) {
            final Rect damage = ai.mTmpInvalRect;
            damage.set(l, t, r, b);
            //执行视图的重绘
            p.invalidateChild(this, damage);
        }

    //省略代码   
    }
}

View的重绘是在ViewRootImpl的scheduleTraversals()方法中开始的,因此这个mParent一定是一个ViewRootImpl(实现了ViewParent接口)对象,但是它是在哪里被赋值的呢?在View类中有一个assignParent(ViewParent parent)方法,查询这个方法被调用的地方是在ViewRootImple中的setView(View view, WindowManager.LayoutParams attrs, View panelParentView)方法内执行的

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
        synchronized (this) {
            if (mView == null) {
                mView = view;

                //省略代码
                mAdded = true;
                int res; /* = WindowManagerImpl.ADD_OKAY; */

                // Schedule the first layout -before- adding to the window
                // manager, to make sure we do the relayout before receiving
                // any other events from the system.
                requestLayout();
               
                try {
                    mOrigWindowType = mWindowAttributes.type;
                    mAttachInfo.mRecomputeGlobalAttributes = true;
                    collectViewAttributes();
                    //向WMS发起添加窗口的请求
                    res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
                            getHostVisibility(), mDisplay.getDisplayId(),
                            mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
                            mAttachInfo.mOutsets, mInputChannel);
                } catch (RemoteException e) {
                    //省略代码
                } finally {
                    if (restore) {
                        attrs.restore();
                    }
                }

                //省略代码

                if (view instanceof RootViewSurfaceTaker) {
                    mInputQueueCallback =
                        ((RootViewSurfaceTaker)view).willYouTakeTheInputQueue();
                }
                if (mInputChannel != null) {
                    if (mInputQueueCallback != null) {
                        mInputQueue = new InputQueue();
                        mInputQueueCallback.onInputQueueCreated(mInputQueue);
                    }
                    //接收输入事件,触摸等
                    mInputEventReceiver = new WindowInputEventReceiver(mInputChannel,
                            Looper.myLooper());
                }
                //省略代码
                
                //将ViewRootImpl回传给view
                view.assignParent(this);
                //省略代码
            }
        }
    }

View重绘的时机包括,invalidate(),requestLayout(),requsetFoust()

ViewRootImpl的setView方法是在WindowMangerGlobal的addView方法内执行的,WindowMangerGlobal是一个单例,每一个App只包含一个;
而WindowMangerGlobal的addView()方法是被WindowMangerImpl的addView方法内调用的;

  1. WindowManger的创建时在Activity的attach(…)方法内,创建了Window对象,并调用window的setWindowManger()方法创建了一个WindowMangerImpl的对象
    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);

        mFragments.attachHost(null /*parent*/);
        //创建Window
        mWindow = new PhoneWindow(this, window);
        mWindow.setWindowControllerCallback(this);
        //MotionEvent事件能回调到Activity的关键
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
    //省略代码

        //创建WindowManger,实际是一个WindowMangerImple对象
        mWindow.setWindowManager(
                (WindowManager)context.getSystemService(Context.WINDOW_SERVICE),
                mToken, mComponent.flattenToString(),
                (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0);
        if (mParent != null) {
            mWindow.setContainer(mParent.getWindow());
        }
        mWindowManager = mWindow.getWindowManager();
        mCurrentConfig = config;
    }
  1. 简明介绍一个App的启动过程

    1. 从Launcher中点击App图标时,会向AMS发送一个启动Activity C的请求,AMS通过Intent查询该Activity是否存在,如果存在就创建一个ActivityRecord对象,并通知Launcher可以暂停了;
    2. Launcher调用pause方法,并通知AMS自己暂停了;
    3. AMS就检查Activity C所在的App是否已经启动,如果没有启动就创建一个新的进程,并调用ActivityThread的main()方法,在main()方法内会创建ActivityThread对象并调用attach方法,里面会将当前ActivityThread内的ApplicationThread对象作为IBinder传递给AMS;
    4. AMS会创建一个ProcessRecord对象保存App的进程信息;然后调用ApplicationThread的bindApplication,并取出之前保存的ActivityRecord对象,调用ApplicationThread的scheduleLaunchActivity()方法启动Activity
    5. 在handleBindApplicaton方法内会完成App环境的初始化,创建Application对象和Instrumentation对象
    6. scheduleLaunchActivity()会创建Activity对象,并调用onCreate()方法
  2. Activity的handleBindApplicaton在执行完成后为什么没有通知AMS自己已经创建完成了??
    因为在handleBindApplicaton,performLaunchActivity,handleCreateService,handleReciver方法内部都会通过LoadApk内的makeApplication方法检测Application对象是否已经创建

private void handleCreateService(CreateServiceData data) {
       //省略
        try {
            if (localLOGV) Slog.v(TAG, "Creating service " + data.info.name);

            ContextImpl context = ContextImpl.createAppContext(this, packageInfo);
            context.setOuterContext(service);

            //获取Application对象
            Application app = packageInfo.makeApplication(false, mInstrumentation);
            service.attach(context, this, data.info.name, data.token, app,
                    ActivityManagerNative.getDefault());
            service.onCreate();
            mServices.put(data.token, service);
            try {
                ActivityManagerNative.getDefault().serviceDoneExecuting(
                        data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
            } catch (RemoteException e) {
                // nothing to do.
            }
        }
        」

LoadApk内的makeApplication方法

    public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
            //检查Application是否已经创建
        if (mApplication != null) {
            return mApplication;
        }
        //否则执行创建Application
        Application app = null;

        //省略代码
        try {
            java.lang.ClassLoader cl = getClassLoader();
            if (!mPackageName.equals("android")) {
                initializeJavaContextClassLoader();
            }
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
        
        }
    

       //省略代码
        return app;
    }

LoadApk作为存储加载的.apk的信息类,是通过WeakReference保存在一个ArrayMap的数组内,其中map的key是当前apk的packageName
performLaunchActivity等方法的内部都是通过getPackageInfoNoCheck方法来获取LoadApk对象的,LoadApk对象的创建过程

private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
            ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
            boolean registerPackage) {
        final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
        synchronized (mResourcesManager) {
            WeakReference<LoadedApk> ref;
            if (differentUser) {
                // Caching not supported across users
                ref = null;
            } else if (includeCode) {
                ref = mPackages.get(aInfo.packageName);
            } else {
                ref = mResourcePackages.get(aInfo.packageName);
            }

            LoadedApk packageInfo = ref != null ? ref.get() : null;
            if (packageInfo == null || (packageInfo.mResources != null
                    && !packageInfo.mResources.getAssets().isUpToDate())) {
                if (localLOGV) Slog.v(TAG, (includeCode ? "Loading code package "
                        : "Loading resource-only package ") + aInfo.packageName
                        + " (in " + (mBoundApplication != null
                                ? mBoundApplication.processName : null)
                        + ")");
                packageInfo =
                    new LoadedApk(this, aInfo, compatInfo, baseLoader,
                            securityViolation, includeCode &&
                            (aInfo.flags&ApplicationInfo.FLAG_HAS_CODE) != 0, registerPackage);
                            
        //省略代码
}
  1. AMS中的ActivityRecord是在ActivityStackSupervisor的startActivityLocked方法内创建的
    ActivityRecord的构造函数内会创建一个appToken = new Token(this, service);,这个Token实现了IApplicationToken.Stub接口
  2. 在ActivityStackSupervisor的startSpecificActivityLocked方法内会检查需要启动的Activity的进程是否存在,不存在就调用AMS的startProcess方法启动进程
mService.startProcessLocked(r.processName, r.info.applicationInfo, true, 0,
                "activity", r.intent.getComponent(), false, false, true);
  1. 在AMS的attachApplication()内,除了调用ApplicationThread的bindApplication外,还会启动栈顶的Activity
private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {
//省略代码  
            thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked());
//省略代码

// See if the top visible activity is waiting to run in this process...
        if (normalMode) {
            try {
            //启动栈顶的Activity
                if (mStackSupervisor.attachApplicationLocked(app)) {
                    didSomething = true;
                }
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }
//省略代码
}

//attachApplicationLock
boolean attachApplicationLocked(ProcessRecord app) throws RemoteException {
        final String processName = app.processName;
        boolean didSomething = false;
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
            ArrayList<ActivityStack> stacks = mActivityDisplays.valueAt(displayNdx).mStacks;
            for (int stackNdx = stacks.size() - 1; stackNdx >= 0; --stackNdx) {
                final ActivityStack stack = stacks.get(stackNdx);
                if (!isFrontStack(stack)) {
                    continue;
                }
                //获取栈顶
                ActivityRecord hr = stack.topRunningActivityLocked(null);
                if (hr != null) {
                    if (hr.app == null && app.uid == hr.info.applicationInfo.uid
                            && processName.equals(hr.processName)) {
                        try {
                        //启动Activity
                            if (realStartActivityLocked(hr, app, true, true)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            Slog.w(TAG, "Exception in new application when starting activity "
                                  + hr.intent.getComponent().flattenToShortString(), e);
                            throw e;
                        }
                    }
                }
            }
        }
        if (!didSomething) {
            ensureActivitiesVisibleLocked(null, 0);
        }
        return didSomething;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值