View

//前提怎么调用到performLaunchActivity
就是Activity.startActivity->
Instrumentation.execStartActivity(app 进程的 ActivtyManagerProxy,然后进入 system server 进程,到 ActivityManagerNative,最终到达 ActivityManagerService)->
ActivityManagerService.startActivity( system server 进程)->
ActivityStarter.startActivityMayWait->ActivityStackSupervisor.resolveIntent (去解析 Intent 和 [Activity)->
PackageManagerService.resolveIntent (resolveActivity() 方法的核心功能是找到相应的Activity 组件,并保存到 intent 对象。做的工作就是检查权限,从 Manifest 中读取 Activity 的配置)->
ActivityStarter.startActivityLocked()->
ActivityStack.startActivityLocked->
ActivityManagerService.startProcessLocked()->
ActivityManagerService.attachApplicationLocked
在 Framework篇 - 四大组件与进程启动的关系 这篇文章中,详细介绍了 ActivityManagerService.startProcessLocked() 整个过程,创建完新进程后会在新进程中调用 ActivityManagerProxy.attachApplication() ,该方法经过 Binder IPC 后调用到ActivityManagerService.attachApplicationLocked()。->
ApplicationThreadProxy.scheduleLaunchActivity()->
IPC 到 ActivityManagerNative 的 onTransaction():

@Override
    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException {
        //...
        case SCHEDULE_LAUNCH_ACTIVITY_TRANSACTION:
        {
            scheduleLaunchActivity(intent, b, ident, info, curConfig, overrideConfig, compatInfo,
                    referrer, voiceInteractor, procState, state, persistentState, ri, pi,
                    notResumed, isForward, profilerInfo);
            return true;
        }

-> ActivityThread (内部有 ApplicationThread 内部类)
ActivityThread的ApplicationThread

private class ApplicationThread extends ApplicationThreadNative{
           case LAUNCH_ACTIVITY: {
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;
会发送消息到 ActivityThread 的 H 类:
private class H extends Handler {
    //...
                case LAUNCH_ACTIVITY: {
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
                    final ActivityClientRecord r = (ActivityClientRecord) msg.obj;
 
                    r.packageInfo = getPackageInfoNoCheck(
                            r.activityInfo.applicationInfo, r.compatInfo);
                    handleLaunchActivity(r, null, "LAUNCH_ACTIVITY");
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                } break;              
}

->
ActivityThread.handleLauchActivity():->
ActivityThread.performLaunchActivity()->


image.png

点击桌面 App 图标,Launcher 进程采用 Binder IPC 向 system_server 进程发起 startActivity 请求;
system_server 进程接收到请求后,向 zygote 进程发送创建进程的请求;
Zygote 进程 fork 出新的子进程,即 App 进程;
App 进程,通过 Binder IPC 向 sytem_server 进程发起 attachApplication 请求;
system_server 进程在收到请求后,进行一系列准备工作后,再通过 binder IPC 向 App 进程发送 scheduleLaunchActivity 请求;
App 进程的 Binder 线程 (ApplicationThread) 在收到请求后,通过 handler 向主线程发送 LAUNCH_ACTIVITY 消息;
主线程在收到 Message 后,通过发射机制创建目标 Activity,并回调 Activity.onCreate() 等方法;
到此,App 便正式启动,开始进入 Activity 生命周期,执行完 onCreate/onStart/onResume 方法,UI 渲染结束后便可以看到App 的主界面。

https://www.cnblogs.com/JMatrix/p/8296427.html

public class View绘制流程 {

    /**
     * 前提在 在activity performLaunchActivity的时候就创建了 phonewindow decoreView
     */

    /*** {android/app/ActivityThread.java}**/
    @Override
    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward, String reason) {
        // TODO Push resumeArgs into the activity for consideration
        final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
        final Activity a = r.activity;
        View decor = r.window.getDecorView();
        decor.setVisibility(View.INVISIBLE);
        ViewManager wm = a.getWindowManager();
        a.mDecor = decor;
        if (r.activity.mVisibleFromClient) {
            //// 添加视图
            r.activity.makeVisible();
        }
    }

    /*** {android/app/Activity.java}***/
    void makeVisible() {
        // 如果Window没有被添加,则addView添加decorView
        if (!mWindowAdded) {
            ViewManager wm = getWindowManager();
            // 进入WindowManagerGlobal.addView,这边是添加DecorView,根view
            wm.addView(mDecor, getWindow().getAttributes());
            mWindowAdded = true;
        }
        // 设置decorView可见
        mDecor.setVisibility(View.VISIBLE);
    }

    /*** {android/view/WindowManagerGlobal.java}**/
    public void addView(View view, ViewGroup.LayoutParams params,
                        Display display, Window parentWindow, int userId) {
        final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
        ViewRootImpl root;
        View panelParentView = null;
        // 每次调用global.addView()都会创建一个ViewRootImpl,它是decorView与WMS沟通的桥梁
        root = new ViewRootImpl(view.getContext(), display);
        view.setLayoutParams(wparams);
        mViews.add(view);
        // ViewRootImpl设置View
        root.setView(view, wparams, panelParentView, userId);
    }

    /*** {android/view/ViewRootImpl.java}**/
    public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView,
                        int userId) {
        ////View的绘制流程
        requestLayout();
        //创建InputChannel
        InputChannel inputChannel = new InputChannel();
        //通过WindowSession进行IPC调用,将View添加到Window上
        //mWindow即W类,用来接收WmS信息
        //同时通过InputChannel接收触摸事件回调
        res = mWindowSession.addToDisplayAsUser(mWindow, mSeq, mWindowAttributes,
                getHostVisibility(), mDisplay.getDisplayId(), userId, mTmpFrame,
                mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
                mAttachInfo.mDisplayCutout, inputChannel,
                mTempInsets, mTempControls);
        //处理触摸事件回调
        mInputEventReceiver = new WindowInputEventReceiver(mInputChannel,
                Looper.myLooper());
    }

    /*** {android/view/ViewRootImpl.java}**/
    public void requestLayout() {
        if (!mHandlingLayoutInLayoutRequest) {
            checkThread(); //checkThread():只能在主线程更新 UI。
            mLayoutRequested = true;
            scheduleTraversals();
        }
    }

    /*** {android/view/ViewRootImpl.java}**/
    void scheduleTraversals() {
        if (!mTraversalScheduled) {
            mChoreographer.postCallback(
                    Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
        }
    }

    /*** {android/view/ViewRootImpl.java}**/
    final class TraversalRunnable implements Runnable {
        @Override
        public void run() {
            doTraversal();
        }
    }

    final TraversalRunnable mTraversalRunnable = new TraversalRunnable();

    /*** {android/view/ViewRootImpl.java}**/
    void doTraversal() {
        performTraversals();
    }

    /*** {android/view/ViewRootImpl.java}**/

    private void performTraversals() {
        int childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
        int childHeightMeasureSpec = getRootMeasureSpec(mHeight, lp.height);
        // 测量
        performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
        // 布局
        performLayout(lp, mWidth, mHeight);
        // 绘制
        performDraw();
        // ...
    }

    /*** {android/view/ViewRootImpl.java}**/
    private void performMeasure(int childWidthMeasureSpec, int childHeightMeasureSpec) {
        //根视图开始 measure 了,所以就是 decorView 了。decorView 是个 FrameLayout,
        // 所以我们就来看 FrameLayout 的measure() 方法。FrameLayout 里面没有 measure(),
        // 只有 onMeasure(),measure() 方法在其父类 View 里,measure() 方法中会调用 onMeasure()
        mView.measure(childWidthMeasureSpec, childHeightMeasureSpec);
    }

    /*** {android/view/ViewRootImpl.java}**/
    private void performLayout(WindowManager.LayoutParams lp, int desiredWindowWidth,
                               int desiredWindowHeight) {// ...
        final View host = mView;
        //执行到view  layout
        host.layout(0, 0, host.getMeasuredWidth(), host.getMeasuredHeight());
    }

    /*** {android/view/ViewRootImpl.java}**/
    private void performDraw() {
        draw(fullRedrawNeeded);
    }

    /*** {android/view/ViewRootImpl.java}**/
    private void draw(boolean fullRedrawNeeded) {
        if (!drawSoftware(surface, mAttachInfo, xOffset, yOffset, scalingRequired, dirty)) {
            return;
        }
    }

    /*** {android/view/ViewRootImpl.java}**/
    private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int xoff, int yoff,
                                 boolean scalingRequired, Rect dirty) {
        // 执行到根布局view了 就可以往下分发了
        mView.draw(canvas);
    }

    /*** {android/view/ViewRootImpl.java}**/
    public void draw(Canvas canvas) {
        // 画背景
        if (!dirtyOpaque) {
            drawBackground(canvas);
        }
        if (!verticalEdges && !horizontalEdges) {
            // 回调 onDraw()
            if (!dirtyOpaque) onDraw(canvas);
            // 分发 draw()
            dispatchDraw(canvas);
            // 绘制 foreground
            onDrawForeground(canvas);
            return;
        }
        // ... 后面情况也是这几个步骤
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容