SurfaceFlinger学习笔记(一)应用启动流程

本系列是基于android Q即android10

SurfaceFlinger学习笔记(一)应用启动流程
SurfaceFlinger学习笔记(二)之Surface
SurfaceFlinger学习笔记(三)之SurfaceFlinger进程
SurfaceFlinger学习笔记(四)之HWC2
SurfaceFlinger学习笔记(五)之HWUI
SurfaceFlinger学习笔记(六)之View Layout Draw过程分析

用户在Launcher程序里点击应用图标时,会通知ActivityManagerService启动应用的入口Activity,ActivityManagerService则会通知Zygote进程孵化出应用进程,然后在这个应用进程里执行ActivityThread的main方法。应用进程接下来通知ActivityManagerService应用进程已启动,ActivityManagerService保存应用进程的一个代理对象,这样ActivityManagerService可以通过这个代理对象控制应用进程,然后ActivityManagerService通知应用进程创建入口Activity的实例,并执行它的生命周期方法

相关类简介

  • Instrumentation

frameworks/base/core/java/android/app/Instrumentation.java
用于实现应用程序测试代码的基类。当在打开仪器的情况下运行时,这个类将在任何应用程序代码之前为您实例化,允许您监视系统与应用程序的所有交互。可以通过AndroidManifest.xml的标签描述该类的实现。

  • ActivityManager

frameworks/base/core/java/android/app/ActivityManager.java
该类提供与Activity、Service和Process相关的信息以及交互方法, 可以被看作是ActivityManagerService的辅助类。

  • ActivityTaskManagerService

frameworks\base\services\core\java\com\android\server\wm\ActivityTaskManagerService.java
Android中最核心的服务,主要负责系统中四大组件的启动、切换、调度及应用程序的管理和调度等工作。在SDK-29(android10)之后,抛弃了曾经的ActivityManagerService,改用ActivityTaskManagerService

  • ActivityThread

frameworks/base/core/java/android/app/ActivityThread.java
管理应用程序进程中主线程的执行,根据Activity管理者的请求调度和执行activities、broadcasts及其相关的操作。

  • ActivityStack

frameworks\base\services\core\java\com\android\server\wm\ActivityStack.java
负责单个Activity栈的状态和管理。

  • ActivityStackSupervisor

frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
负责所有Activity栈的管理。内部管理了mHomeStack、mFocusedStack和mLastFocusedStack三个Activity栈。其中,mHomeStack管理的是Launcher相关的Activity栈;mFocusedStack管理的是当前显示在前台Activity的Activity栈;mLastFocusedStack管理的是上一次显示在前台Activity的Activity栈。

  • ClientLifecycleManager

frameworks\base\services\core\java\com\android\server\wm\ClientLifecycleManager.java
用来管理多个客户端生命周期执行请求的管理类。

启动过程源码调用时序图

启动过程源码调用时序图

  1. Activity::startActivityForResult调用mInstrumentation.execStartActivity调用ActivityManager.getService().startActivity
* frameworks/base/core/java/android/app/Activity.java
 public void startActivityForResult( String who, Intent intent, int requestCode, @Nullable Bundle options) {
       。。。
        Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity(this, mMainThread.getApplicationThread(), mToken, who,  intent, requestCode, options);
        if (ar != null) {
            mMainThread.sendActivityResult(mToken, who, requestCode, ar.getResultCode(), ar.getResultData());
        }
        cancelInputsAndStartExitTransition(options);
        。。。
    }

* frameworks/base/core/java/android/app/Instrumentation.java
public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
            。。。
         // SDK-28
		int result = ActivityManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
		// SDK-29
		int result = ActivityTaskManager.getService()
                .startActivity(whoThread, who.getBasePackageName(), intent,
                        intent.resolveTypeIfNeeded(who.getContentResolver()),
                        token, target != null ? target.mEmbeddedID : null,
                        requestCode, 0, null, options);
                        。。。
}

ActivityTaskManager.getService()返回的是IActivityTaskManager接口,这是远程调用的接口,执行IActivityTaskManager#startActivity之后相当于当前线程将启动Activity的消息发送出去了

  1. ActivityTaskManagerService::startActivityAsUser调用ActivityStartController.obtainStarter构造ActivityStarter,ActivityStarter.execute调用ActivityStarter.startActivityMayWait调用ActivityStarter.startActivity,ActivityStarter.startActivityUnchecked(这个方法里会根据启动标志位和Activity启动模式来决定如何启动一个Activity以及是否要调用deliverNewIntent方法通知Activity有一个Intent试图重新启动它),然后调用RootActivityContainer#resumeFocusedStacksTopActivities
* frameworks/base/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
 int startActivityAsUser(IApplicationThread caller, String callingPackage,
            Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
            int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
            boolean validateIncomingUser) {
        enforceNotIsolatedCaller("startActivityAsUser");
        userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
                Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser");
        // TODO: Switch to user app stacks here.
        return getActivityStartController().obtainStarter(intent, "startActivityAsUser")--构造ActivityStarter
                .setCaller(caller)
                .setCallingPackage(callingPackage)
                .setResolvedType(resolvedType)
                .setResultTo(resultTo)
                .setResultWho(resultWho)
                .setRequestCode(requestCode)
                .setStartFlags(startFlags)
                .setProfilerInfo(profilerInfo)
                .setActivityOptions(bOptions)
                .setMayWait(userId) -- 注意这个方法,在这个方法里有一句 mRequest.mayWait = true;
                .execute();

    }
  1. RootActivityContainer,调用ActivityStack#resumeTopActivityUncheckedLocked,然后调用resumeTopActivityInnerLocked,在这个函数里,会有两个重要的操作,一个是对应流程图里橙色的那条线,调用函数startPausingLocked,通知上一个Activity执行onPause;另一个是通知启动新的Activity,对应的是流程图中绿色的线
* frameworks\base\services\core\java\com\android\server\wm\RootActivityContainer.java
 boolean resumeFocusedStacksTopActivities(
        ActivityStack targetStack, ActivityRecord target, ActivityOptions targetOptions) {
        。。。。
        for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
       。。。
        if (!resumedOnDisplay) {
            final ActivityStack focusedStack = display.getFocusedStack();
            if (focusedStack != null) {
                focusedStack.resumeTopActivityUncheckedLocked(target, targetOptions);
            }
        }
    }
    return result;
}

* frameworks\base\services\core\java\com\android\server\wm\ActivityStack.java
boolean resumeTopActivityInnerLocked(ActivityRecord prev, ActivityOptions options) {
    // ......
    boolean pausing = getDisplay().pauseBackStacks(userLeaving, next, false);
    if (mResumedActivity != null) {
        if (DEBUG_STATES) Slog.d(TAG_STATES,
                "resumeTopActivityLocked: Pausing " + mResumedActivity);
        pausing |= startPausingLocked(userLeaving, false, next, false);
    }
    // ......
    if (next.attachedToProcess()) {
        try {
        // ......
            transaction.setLifecycleStateRequest(
                    ResumeActivityItem.obtain(next.app.getReportedProcState(),
                            getDisplay().mDisplayContent.isNextTransitionForward()));
            mService.getLifecycleManager().scheduleTransaction(transaction);
        } catch (Exception e) {
            // ......
            mStackSupervisor.startSpecificActivityLocked(next, true, false);
            return true;
        }
        // ......
    } else {
        // Whoops, need to restart this activity!
        if (!next.hasBeenLaunched) {
            next.hasBeenLaunched = true;
        } else {
            if (SHOW_APP_STARTING_PREVIEW) {
                next.showStartingWindow(null /* prev */, false /* newTask */,
                        false /* taskSwich */);
            }
            if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "Restarting: " + next);
        }
        if (DEBUG_STATES) Slog.d(TAG_STATES, "resumeTopActivityLocked: Restarting " + next);
        mStackSupervisor.startSpecificActivityLocked(next, true, true);
    }

    return true;
}
final boolean startPausingLocked(boolean userLeaving, boolean uiSleeping,
        ActivityRecord resuming, boolean pauseImmediately) {
    // ......
    if (prev.attachedToProcess()) {
        if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Enqueueing pending pause: " + prev);
        try {
            EventLogTags.writeAmPauseActivity(prev.mUserId, System.identityHashCode(prev),
                    prev.shortComponentName, "userLeaving=" + userLeaving);

            mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
                    prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
                            prev.configChangeFlags, pauseImmediately));
        } catch (Exception e) {
            // ......
        }
    } 
    // ......
}

栈顶Activity执行onPause方法退出流程

  1. ClientLifecycleManager的scheduleTransaction调用transactionWithState方法重新构造了ClientTransaction对象传入(ActivityLifecycleItem 继承自ClientTransaction),transactionWithState里面将PauseActivityItem通过setLifecycleStateRequest方法传入clientTransaction,之后就执行ClientTransaction#schedule
* frameworks\base\services\core\java\com\android\server\wm\ActivityStack.java
//PauseActivityItem对象将会在后面的IPC过程中传到Activity所在的进程
mService.getLifecycleManager().scheduleTransaction(prev.app.getThread(),
                    prev.appToken, PauseActivityItem.obtain(prev.finishing, userLeaving,
                            prev.configChangeFlags, pauseImmediately));

* frameworks\base\core\java\android\app\servertransaction\ClientTransaction.java
public void schedule() throws RemoteException {
    mClient.scheduleTransaction(this);
}
  1. ClientTransaction.schedule方法的mClient是一个IApplicationThread类型,ActivityThread的内部类ApplicationThread派生这个接口类并实现了对应的方法。所以直接跳转到ApplicationThread中的scheduleTransaction方法。ActivityThread类中并没有定义scheduleTransaction方法,所以调用的是他父类ClientTransactionHandler的scheduleTransaction方法
* frameworks\base\core\java\android\app\ActivityThread.java
private class ApplicationThread extends IApplicationThread.Stub {
    public void scheduleTransaction(ClientTransaction transaction) throws RemoteException {
        ActivityThread.this.scheduleTransaction(transaction);
    }
}

* frameworks\base\core\java\android\app\ClientTransactionHandler.java
void scheduleTransaction(ClientTransaction transaction) {
    transaction.preExecute(this);
    sendMessage(ActivityThread.H.EXECUTE_TRANSACTION, transaction);
}
  1. 在ClientTransactionHandler.scheduleTransaction方法中调用了sendMessage方法,这个方法是一个抽象方法,其实现在ClientTransactionHandler派生类的ActivityThread中,ActivityThread.sendMessage方法会把消息发送给内部名字叫H的Handler,Handler H的实例接收到EXECUTE_TRANSACTION消息后调用TransactionExecutor.execute方法切换Activity状态。
* frameworks\base\core\java\android\app\ActivityThread.java
 private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
    if (DEBUG_MESSAGES) {
        Slog.v(TAG,
                "SCHEDULE " + what + " " + mH.codeToString(what) + ": " + arg1 + " / " + obj);
    }
    Message msg = Message.obtain();
    msg.what = what;
    msg.obj = obj;
    msg.arg1 = arg1;
    msg.arg2 = arg2;
    if (async) {
        msg.setAsynchronous(true);
    }
    mH.sendMessage(msg);
}
///
case EXECUTE_TRANSACTION:
    final ClientTransaction transaction = (ClientTransaction) msg.obj;
    mTransactionExecutor.execute(transaction);
    if (isSystem()) {
    	// Client transactions inside system process are recycled on the client side
        // instead of ClientLifecycleManager to avoid being cleared before this 
        // message is handled.
        transaction.recycle();
    }
    break;
  1. TransactionExecutor.execute方法里面先执行Callbacks,然后改变Activity当前的生命周期状态。此处由于没有Callback所以直接跳转executeLifecycleState方法。在executeLifecycleState方法里面,会先去调用TransactionExecutor.cycleToPath执行当前生命周期状态之前的状态,然后执行ActivityLifecycleItem.execute方法。由于是从ON_RESUME状态到ON_PAUSE状态切换,中间没有其他状态,cycleToPath这个情况下没有做什么实质性的事情,直接执行execute方法。前面在ActivityStack.startPausingLocked方法里面scheduleTransaction传递的是PauseActivityItem对象,所以executeLifecycleState方法里调用的execute方法其实是PauseActivityItem.execute方法
 *frameworks\base\core\java\android\app\servertransaction\TransactionExecutor.java
 public void execute(ClientTransaction transaction) {
    // ......
    executeCallbacks(transaction);
    executeLifecycleState(transaction);
    mPendingActions.clear();
    if (DEBUG_RESOLVER) Slog.d(TAG, tId(transaction) + "End resolving transaction");
}
private void executeLifecycleState(ClientTransaction transaction) {
    final ActivityLifecycleItem lifecycleItem = transaction.getLifecycleStateRequest();
    // ......
    // Cycle to the state right before the final requested state.
    cycleToPath(r, lifecycleItem.getTargetState(), true /* excludeLastState */, transaction);
    lifecycleItem.execute(mTransactionHandler, token, mPendingActions);
    lifecycleItem.postExecute(mTransactionHandler, token, mPendingActions);
}
  1. 在PauseActivityItem.execute方法中会调用ClientTransactionHandler #handlePauseActivity方法,ActivityThread继承自ClientTransactionHandler ,实际上这个client就是ActivityThread,所以调用ActivityThread.handlePauseActivity方法,经过handlePauseActivity -> performPauseActivity -> performPauseActivity,在这个方法中会先去判断是否需要调用callActivityOnSaveInstanceState方法来保存临时数据,然后执行performPauseActivityIfNeeded,后调用Instrumentation.callActivityOnPause方法继续执行pasue流程。
* frameworks/base/core/java/android/app/servertransaction/PauseActivityItem.java
public void execute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
    Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityPause");
    client.handlePauseActivity(token, mFinished, mUserLeaving, mConfigChanges, pendingActions,
            "PAUSE_ACTIVITY_ITEM");
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
  1. 最终通过Instrumentation调用到Activity#performPause,经过了一大圈Activity的onPause最终在这里被调用。

Activity所在的应用进程启动过程

  1. 回到ActivityStack#resumeTopActivityInnerLocked,在这里执行startPausingLocked(userLeaving, false, next, false);之后再往后走就准备创建新的Activity。会执行到mStackSupervisor#startSpecificActivityLocked。ActivityStackSupervisor.startSpecificActivityLocked方法,在这个方法中会去根据进程和线程是否存在判断App是否已经启动,如果已经启动,就会调用realStartActivityLocked方法继续处理。如果没有启动则调用ActivityManagerService.startProcessLocked方法创建新的进程处理
* frameworks\base\services\core\java\com\android\server\wm\ActivityStackSupervisor.java
void startSpecificActivityLocked(ActivityRecord r, boolean andResume, boolean checkConfig) {
    // Is this activity's application already running?
    final WindowProcessController wpc =
            mService.getProcessController(r.processName, r.info.applicationInfo.uid);
    boolean knownToBeDead = false;
    if (wpc != null && wpc.hasThread()) {
        try {
            realStartActivityLocked(r, wpc, andResume, checkConfig);
            return;
        } catch (RemoteException e) {
            Slog.w(TAG, "Exception when starting activity "
                    + r.intent.getComponent().flattenToShortString(), e);
        }
        knownToBeDead = true;
    }
    // ......
    final Message msg = PooledLambda.obtainMessage(
                    ActivityManagerInternal::startProcess, mService.mAmInternal, r.processName,
                    r.info.applicationInfo, knownToBeDead, "activity", r.intent.getComponent());
            mService.mH.sendMessage(msg);//mService为ActivityTaskManagerService 
            
    // ......
}
  1. ActivityManagerInternal::startProcess,这里的::其实是java8的新特性,语法含义是调用ActivityManagerInternal类的startProcess方法。后面的那些变量就是传递到startProcess的参数,至于mService.mH.sendMessage(msg);它的作用其实是发送msg给ActivityTaskManagerService的内部类Handler,调用AppTimeTracker的deliverResult方法。作用应该是统计用户使用APP的相关时间。ActivityManagerInternal是一个抽象类,startProcess的具体实现是在ActivityManagerService内部类LocalService
frameworks\base\services\core\java\com\android\server\am\ActivityManagerService

final class LocalService extends ActivityManagerInternal{
		// ...省略部分代码
		@Override
        public void startProcess(String processName, ApplicationInfo info,
                boolean knownToBeDead, String hostingType, ComponentName hostingName) {
                synchronized (ActivityManagerService.this) {
                    startProcessLocked(processName, info, knownToBeDead, 0 /* intentFlags */,
                            new HostingRecord(hostingType, hostingName),
                            false /* allowWhileBooting */, false /* isolated */,
                            true /* keepIfLarge */);
                }
        }
        // ...省略部分代码
        final ProcessRecord startProcessLocked(String processName,
            ApplicationInfo info, boolean knownToBeDead, int intentFlags,
            HostingRecord hostingRecord, boolean allowWhileBooting,
            boolean isolated, boolean keepIfLarge) {
        return mProcessList.startProcessLocked(processName, info, knownToBeDead, intentFlags,
                hostingRecord, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
                null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
                null /* crashHandler */);
    }
}

  1. ActivityManagerService.startProcessLocked执行了ProcessList的startProcessLocked方法,最终调用Process的start方法来为应用创建进程。经过一步步调用,可以发现其最终调用了Zygote并通过socket通信的方式让Zygote进程fork出一个新的进程,并根据传递的”android.app.ActivityThread”字符串,反射出该对象并执行ActivityThread的main方法对其进行初始化
frameworks\base\core\java\android\os\Process
frameworks\base\core\java\android\os\ZygoteProcess
  1. 在ActivityThread.main方法中对ActivityThread进行了初始化,创建了主线程的Looper对象并调用Looper.loop()方法启动Looper,把自定义Handler类H的对象作为主线程的handler。接下来跳转到ActivityThread.attach方法
public static void main(String[] args) {
        .....
        Looper.prepareMainLooper();
        .....
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }
        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
        Looper.loop();
        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
  1. 在ActivityThread.attach方法中,首先会通过ActivityTaskManagerService为这个应用绑定一个Application,然后添加一个垃圾回收观察者,每当系统触发垃圾回收的时候就会在run方法里面去计算应用使用了多少内存,如果超过总量的四分之三就会尝试释放内存。最后,为根View添加config回调接收config变化相关的信息
  2. ActivityTaskManagerService的attachApplication调用RootActivityContainer.attachApplication,然后调用ActivityStackSupervisor.realStartActivityLocked
frameworks/base/services/core/java/com/android/server/wm/RootActivityContainer.java
 boolean attachApplication(WindowProcessController app) throws RemoteException {
 ...
 final ActivityRecord activity = mTmpActivityList.get(i);
                    if (activity.app == null && app.mUid == activity.info.applicationInfo.uid
                            && processName.equals(activity.processName)) {
                        try {
                            if (mStackSupervisor.realStartActivityLocked(activity, app,
                                    top == activity /* andResume */, true /* checkConfig */)) {
                                didSomething = true;
                            }
                        } catch (RemoteException e) {
                            Slog.w(TAG, "Exception in new application when starting activity "
                                    + top.intent.getComponent().flattenToShortString(), e);
                            throw e;
                        }
                    }
                  ....
 }
  1. 如果应用已经启动,则直接进入到这一步处理,在ActivityStackSupervisor.realStartActivityLocked方法中为ClientTransaction对象添加LaunchActivityItem的callback,然后设置当前的生命周期状态,最后调用ClientLifecycleManager.scheduleTransaction方法执行,执行流程参考onPause的第四步。注意这里的LaunchActivityItem是通过clientTransaction#addCallback注入到clientTransaction里面,而之前的PauseActivityItem是通过clientTransaction.setLifecycleStateRequest。另外LaunchActivityItem继承自ClientTransactionItem,而PauseActivityItem继承自ActivityLifecycleItem
frameworks/base/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
boolean realStartActivityLocked(ActivityRecord r, WindowProcessController proc,
        boolean andResume, boolean checkConfig) throws RemoteException {

        try {
            if (!proc.hasThread()) {
                throw new RemoteException();
            }

            // Create activity launch transaction.
            final ClientTransaction clientTransaction = ClientTransaction.obtain(
                    proc.getThread(), r.appToken);

            final DisplayContent dc = r.getDisplay().mDisplayContent;
            clientTransaction.addCallback(LaunchActivityItem.obtain(new Intent(r.intent),
                    System.identityHashCode(r), r.info,
                    // TODO: Have this take the merged configuration instead of separate global
                    // and override configs.
                    mergedConfiguration.getGlobalConfiguration(),
                    mergedConfiguration.getOverrideConfiguration(), r.compat,
                    r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(),
                    r.icicle, r.persistentState, results, newIntents,
                    dc.isNextTransitionForward(), proc.createProfilerInfoIfNeeded(),
                            r.assistToken));

            // Set desired final state.
            final ActivityLifecycleItem lifecycleItem;
            if (andResume) {
                lifecycleItem = ResumeActivityItem.obtain(dc.isNextTransitionForward());
            } else {
                lifecycleItem = PauseActivityItem.obtain();
            }
            clientTransaction.setLifecycleStateRequest(lifecycleItem);

            // Schedule transaction.
            mService.getLifecycleManager().scheduleTransaction(clientTransaction);
            //...
        } catch (RemoteException e) {
           //...
        }
    } finally {
        endDeferResume();
    }
    // ......
    return true;
}
  1. callback后跳转到LaunchActivityItem.execute,然后执行到ActivityThread.handleLaunchActivity
frameworks/base/core/java/android/app/servertransaction/LaunchActivityItem.java
public void execute(ClientTransactionHandler client, IBinder token,
        PendingTransactionActions pendingActions) {
    Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityStart");
    ActivityClientRecord r = new ActivityClientRecord(token, mIntent, mIdent, mInfo,
            mOverrideConfig, mCompatInfo, mReferrer, mVoiceInteractor, mState, mPersistentState,
            mPendingResults, mPendingNewIntents, mIsForward,
            mProfilerInfo, client, mAssistToken);
    client.handleLaunchActivity(r, pendingActions, null /* customIntent */);
    Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}

// frameworks/base/core/java/android/app/ActivityThread.java
public Activity handleLaunchActivity(ActivityClientRecord r,
        PendingTransactionActions pendingActions, Intent customIntent) {
    // ......

    final Activity a = performLaunchActivity(r, customIntent);
    // ......
    return a;
}

  1. 在ActivityThread.performLaunchActivity方法中首先对Activity的ComponentName、ContextImpl、Activity以及Application对象进行了初始化,根据加载java类,Instrumentation.newActivity根据类名以Java反射的方法创建一个Activity,然后调用Activity的attach方法,并跟前面初始化内容相互关联,然后设置Activity主题,最后调用Instrumentation.callActivityOnCreate方法。然后跳转到Activity.performCreate方法,在这里我们看到了Activity.onCreate方法
* frameworks/base/core/java/android/app/ActivityThread.java
/**  Core implementation of activity launch. */
    private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {
        。。。。
        ContextImpl appContext = createBaseContextForActivity(r);
        try {
            java.lang.ClassLoader cl = appContext.getClassLoader();
            //源文件为Instrumentation.java, 它在newActivity函数中根据Activity的类名通过Java反射机制来创建对应的Activity
            activity = mInstrumentation.newActivity(
                    cl, component.getClassName(), r.intent);
           。。。。
        } catch (Exception e) {
            。。。。
        }
        try {
            Application app = r.packageInfo.makeApplication(false, mInstrumentation);
            if (activity != null) {
                。。。。。
                appContext.setOuterContext(activity);
                activity.attach(appContext, this, getInstrumentation(), r.token,
                        r.ident, app, r.intent, r.activityInfo, title, r.parent,
                        r.embeddedID, r.lastNonConfigurationInstances, config,
                        r.referrer, r.voiceInteractor, window, r.configCallback,
                        r.assistToken);

             。。。。。
                int theme = r.activityInfo.getThemeResource();
                if (theme != 0) {
                    activity.setTheme(theme);
                }
                activity.mCalled = false;
                //下面这个函数会调用Activity的onCreate函数
                if (r.isPersistable()) {
                    mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);
                } else {
                    mInstrumentation.callActivityOnCreate(activity, r.state);
                }
               。。。。
                r.activity = activity;
            }
            r.setState(ON_CREATE);
            synchronized (mResourcesManager) {
                mActivities.put(r.token, r);
            }
        } catch (SuperNotCalledException e) {
            throw e;
        } catch (Exception e) {
           。。。。
        }
        return activity;
    }
frameworks/base/core/java/android/app/Instrumentation.java
public Activity newActivity(Class<?> clazz, Context context, 
            IBinder token, Application application, Intent intent, ActivityInfo info, 
            CharSequence title, Activity parent, String id,
            Object lastNonConfigurationInstance) throws InstantiationException,
            IllegalAccessException {
        Activity activity = (Activity)clazz.newInstance();
        //关键函数attach!!
        ActivityThread aThread = null;
        // Activity.attach expects a non-null Application Object.
        if (application == null) {
            application = new Application();
        }
        activity.attach(context, aThread, this, token, 0 /* ident */, application, intent,
                info, title, parent, id,
                (Activity.NonConfigurationInstances)lastNonConfigurationInstance,
                new Configuration(), null /* referrer */, null /* voiceInteractor */,
                null /* window */, null /* activityConfigCallback */, null /*assistToken*/);
        return activity;
    }
  1. Activity的attach创建PhoneWindow,并设置到mWindow
@UnsupportedAppUsage
    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, ActivityConfigCallback activityConfigCallback, IBinder assistToken) {
        attachBaseContext(context);
      。。。
        mWindow = new PhoneWindow(this, window, activityConfigCallback);
        mWindow.setWindowControllerCallback(this);
        mWindow.setCallback(this);
        mWindow.setOnWindowDismissedCallback(this);
        mWindow.getLayoutInflater().setPrivateFactory(this);
        if (info.softInputMode != WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED) {
            mWindow.setSoftInputMode(info.softInputMode);
        }
        if (info.uiOptions != 0) {
            mWindow.setUiOptions(info.uiOptions);
        }
        mUiThread = Thread.currentThread();

    。。。。
        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();
。。。。
    }
* frameworks/base/core/java/android/view/Window.java
public void setWindowManager(WindowManager wm, IBinder appToken, String appName,
            boolean hardwareAccelerated) {
        mAppToken = appToken;
        mAppName = appName;
        mHardwareAccelerated = hardwareAccelerated;
        if (wm == null) {
            wm = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
        }
        mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this);
    }
  1. activity的onCreate调用setContentView。getWindow返回Window,Window是一个抽象基类,由PhoneWindow实现,用于控制顶层窗口的外观和行为。做为顶层窗口它有什么特殊的职能呢?即绘制背景和标题栏、默认的按键处理等
* frameworks/base/core/java/android/app/Activity.java
public void setContentView(@LayoutRes int layoutResID) {
        getWindow().setContentView(layoutResID);
        initWindowDecorActionBar();
    }
public Window getWindow() {
        return mWindow;
    }

* frameworks/base/core/java/com/android/internal/policy/PhoneWindow.java
@Override
public void setContentView(int layoutResID) {
        // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
        // decor, when theme attributes and the like are crystalized. Do not check the feature
        // before this happens.
        if (mContentParent == null) {
            installDecor();
        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            mContentParent.removeAllViews();
        }
}

@Override
    public void setContentView(View view, ViewGroup.LayoutParams params) {
        // Note: FEATURE_CONTENT_TRANSITIONS may be set in the process of installing the window
        // decor, when theme attributes and the like are crystalized. Do not check the feature
        // before this happens.
        //mContentParent是一个ViewGroup类型,它从View中派生,所以也是一个UI单元
        if (mContentParent == null) {
            installDecor();
        } else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            mContentParent.removeAllViews();
        }
        if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
            view.setLayoutParams(params);
            final Scene newScene = new Scene(mContentParent, view);
            transitionTo(newScene);
        } else {
            mContentParent.addView(view, params);
        }
}

在这里插入图片描述
12. PhoneWindow的setContentView调用installDecor创建mDecor,它为DecorView类型,从FrameLayout派生

Activity所在的应用进程Resume过程

  1. ActivityStackSupervisor的realStartActivityLocked在调用LaunchActivityItem后调用ResumeActivityItem.obtain(dc.isNextTransitionForward());然后执行ResumeActivityItem的execute,调用handleResumeActivity,后进入ActivityThread.handleResumeActivity
* frameworks/base/core/java/android/app/servertransaction/ResumeActivityItem.java
@Override
    public void execute(ClientTransactionHandler client, IBinder token,
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
        client.handleResumeActivity(token, true /* finalStateRequest */, mIsForward,
                "RESUME_ACTIVITY");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
  1. 在handleResumeActivity中,获取DecorView,然后获取ViewManager,即为WindowManagerImpl,然后调用addView,进而调用WindowManagerGlobal.addView,WindowManagerGlobal的addView会创建ViewRootImpl,并把DecorView添加进去
@Override
    public void handleResumeActivity(IBinder token, boolean finalStateRequest, boolean isForward,String reason) {
        ...
        final ActivityClientRecord r = performResumeActivity(token, finalStateRequest, reason);
       .....
        if (r.window == null && !a.mFinished && willBeVisible) {
            r.window = r.activity.getWindow();
             //获得一个View对象
            View decor = r.window.getDecorView();
            decor.setVisibility(View.INVISIBLE);
            //获得ViewManager对象
            ViewManager wm = a.getWindowManager();
            WindowManager.LayoutParams l = r.window.getAttributes();
            a.mDecor = decor;
            l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
            l.softInputMode |= forwardBit;
            if (r.mPreserveWindow) {
                a.mWindowAdded = true;
                r.mPreserveWindow = false;
                // Normally the ViewRoot sets up callbacks with the Activity
                // in addView->ViewRootImpl#setView. If we are instead reusing
                // the decor view we have to notify the view root that the
                // callbacks may have changed.
                ViewRootImpl impl = decor.getViewRootImpl();
                if (impl != null) {
                    impl.notifyChildRebuilt();
                }
            }
            if (a.mVisibleFromClient) {
                if (!a.mWindowAdded) {
                    a.mWindowAdded = true;
                    //把刚才的decor对象加入到ViewManager中
                    wm.addView(decor, l);
                } else {
                    a.onWindowAttributesChanged(l);
                }
            }
        } else if (!willBeVisible) {
            r.hideForNow = true;
        }
        ...
        // 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) {
           ...
            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.nextIdle = mNewActivities;
        mNewActivities = r;
        if (localLOGV) Slog.v(TAG, "Scheduling idle handler for " + r);
        Looper.myQueue().addIdleHandler(new Idler());
    }
* frameworks/base/core/java/android/view/WindowManagerGlobal.java
public void addView(View view, ViewGroup.LayoutParams params,
            Display display, Window parentWindow) {
            ...
            final WindowManager.LayoutParams wparams = (WindowManager.LayoutParams) params;
            ...
            ViewRootImpl root;
            ...
            root = new ViewRootImpl(view.getContext(), display);
            view.setLayoutParams(wparams);
            mViews.add(view);
            mRoots.add(root);
            mParams.add(wparams);
            //setView,其中view是刚才我们介绍的DecorView
            root.setView(view, wparams, panelParentView);
}

在这里插入图片描述
3. ViewRootImpl有一个成员变量叫mSurface,它是Surface类型,负责SurfaceFlinger交互,还有一个W类型的mWindow和一个View类型的mView变量,W是ViewRootImpl定义的一个静态内部类继承IWindow.Stub,是IWindow的Bn端,负责WMS回调到应用进程用的,初始化时getWindowSession在WindowManagerService创建一个session,然后再次经过 Binder 将数据写回 app 进程,则获取的便是 Session 的代理对象 IWindowSession,这个会话被App进程用于和WMS通信
ViewRootImpl和WMS的关系

* frameworks/base/core/java/android/view/ViewRootImpl.java
public final class ViewRootImpl implements ViewParent,
        View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks {
    ...
    final Surface mSurface = new Surface(); //创建 Surface,此时 Surface 创建完什么都没有,详见下面分析
    ...
    public ViewRootImpl(Context context, Display display) {
        mContext = context;
        //获取 IWindowSession 的代理类
        mWindowSession = WindowManagerGlobal.getWindowSession();
        mDisplay = display;
        mThread = Thread.currentThread(); //主线程
        mWindow = new W(this);
        mChoreographer = Choreographer.getInstance();
        ...
    }
}
* frameworks/base/core/java/android/view/WindowManagerGlobal.java
public static IWindowSession getWindowSession() {
        。。。
                    IWindowManager windowManager = getWindowManagerService();
                    //经过 Binder 调用,最终调用 WMS
                    sWindowSession = windowManager.openSession(
                            new IWindowSessionCallback.Stub() {
                                @Override
                                public void onAnimatorScaleChanged(float scale) {
                                    ValueAnimator.setDurationScale(scale);
                                }
                            });
        。。。
            return sWindowSession;
    }
* frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
    public IWindowSession openSession(IWindowSessionCallback callback) {
        return new Session(this, callback);
    }

  1. 创建完 ViewRootImpl 对象后,接下来调用该对象的 setView() 方法
* frameworks/base/core/java/android/view/ViewRootImpl.java
public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {
  synchronized (this) {
  
    requestLayout(); //详见下面分析
    ...
    //通过 Binder调用,进入 system 进程的 Session
    res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
          getHostVisibility(), mDisplay.getDisplayId(),
          mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,
          mAttachInfo.mOutsets, mInputChannel);
    ...
  }
}

* frameworks/base/services/core/java/com/android/server/wm/Session.java
lass Session extends IWindowSession.Stub implements IBinder.DeathRecipient {
    public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
            int viewVisibility, int displayId, Rect outFrame, Rect outContentInsets,
            Rect outStableInsets, Rect outOutsets,
            DisplayCutout.ParcelableWrapper outDisplayCutout, InputChannel outInputChannel,
            InsetsState outInsetsState) {
        return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId, outFrame,
                outContentInsets, outStableInsets, outOutsets, outDisplayCutout, outInputChannel,
                outInsetsState);
    }
}
  1. 创建完 ViewRootImpl 对象后,接下来调用该对象的 setView()
* /frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
public int addWindow(Session session, IWindow client, int seq, WindowManager.LayoutParams attrs, int viewVisibility, int displayId, Rect outContentInsets, Rect outStableInsets, Rect outOutsets, InputChannel outInputChannel) {
    ...
    final WindowState win = new WindowState(this, session, client, token, parentWindow,
                    appOp[0], seq, attrs, viewVisibility, session.mUid,
                    session.mCanAddInternalSystemWindow);
	...
	WindowToken token = displayContent.getWindowToken(
                    hasParent ? parentWindow.mAttrs.token : attrs.token);
    ...
    final DisplayPolicy displayPolicy = displayContent.getDisplayPolicy();
            displayPolicy.adjustWindowParamsLw(win, win.mAttrs, Binder.getCallingPid(),
                    Binder.getCallingUid());
            win.setShowToOwnerOnlyLocked(mPolicy.checkShowToOwnerOnly(attrs));
    res = displayPolicy.prepareAddWindowLw(win, attrs);
 	final WindowState win = new WindowState(this, session, client, token, parentWindow,
                    appOp[0], seq, attrs, viewVisibility, session.mUid,
                    session.mCanAddInternalSystemWindow);
    ...
    win.attach();
    mWindowMap.put(client.asBinder(), win);
    ...
    win.applyAdjustForImeIfNeeded();
    ...
    if (win.canReceiveKeys()) {
    //当该窗口能接收按键事件,则更新聚焦窗口
                focusChanged = updateFocusedWindowLocked(UPDATE_FOCUS_WILL_ASSIGN_LAYERS,
                        false /*updateInputWindows*/);
                ...
            }
   win.getParent().assignChildLayers();

frameworks/base/services/core/java/com/android/server/wm/WindowState.java
void attach() {
        mSession.windowAddedLocked(mAttrs.packageName);
    }
  1. WindowState的attach调用Session的windowAddedLocked,创建SurfaceSession,并将当前 Session 添加到 WMS.mSessions 成员变量
frameworks/base/services/core/java/com/android/server/wm/Session.java
void windowAddedLocked(String packageName) {
        mPackageName = packageName;
        mRelayoutTag = "relayoutWindow: " + mPackageName;
        if (mSurfaceSession == null) {
            if (WindowManagerService.localLOGV) Slog.v(
                TAG_WM, "First window added to " + this + ", creating SurfaceSession");
            mSurfaceSession = new SurfaceSession();
            if (SHOW_TRANSACTIONS) Slog.i(
                    TAG_WM, "  NEW SURFACE SESSION " + mSurfaceSession);
            mService.mSessions.add(this);
            if (mLastReportedAnimatorScale != mService.getCurrentAnimatorScale()) {
                mService.dispatchNewAnimatorScaleLocked(this);
            }
        }
        mNumWindow++;
    }
  1. SurfaceSession 的创建会调用 JNI,在 JNI 调用 nativeCreate,创建 SurfaceComposerClient 对象, 作为跟 SurfaceFlinger 通信的代理对象
* frameworks/base/core/jni/android_view_SurfaceSession.cpp
static jlong nativeCreate(JNIEnv* env, jclass clazz) {
    SurfaceComposerClient* client = new SurfaceComposerClient();
    client->incStrong((void*)nativeCreate);
    return reinterpret_cast<jlong>(client);
}

* frameworks/native/libs/gui/SurfaceComposerClient.cpp
void SurfaceComposerClient::onFirstRef() {
	//getComposerService() 将返回 SF 的 Binder 代理端的 BpSurfaceFlinger 对象
	sp<ISurfaceComposer> sf(ComposerService::getComposerService());
    if (sf != nullptr && mStatus == NO_INIT) {
        sp<ISurfaceComposerClient> conn;
        //先调用 SF 的 createConnection()
        conn = sf->createConnection();
        if (conn != nullptr) {
            mClient = conn;
            mStatus = NO_ERROR;
        }
    }
}

下面内容请参考SurfaceFlinger学习笔记(二)之HWUI

  • 题外:
    ViewRootImpl 内部有一个W类型的对象,它也是一个基于Binder通信的类,W是IWindow的Bn端,用于响应请求。IWindow定义在另一个aidl文件IWindow.aidl中。IWindow是WMS用来做事件通知的。每当发生一些事情时,WMS就会把这些事告诉某个IWindow
    每个App进程都会和WMS建立一个IWindowSession会话。这个会话被App进程用于和WMS通信
    按键、触屏等事件是如何被分发的?
  1. WMS所在的SystemServer进程接收到按键事件
  2. WMS找到UI位于屏幕顶端的进程所对应的IWindow对象,这是一个Bp端对象
  3. 调用这个IWindow对象的dispatchKey。IWindow对象的Bn端位于ViewRootImpl 中,ViewRootImpl 再根据内部View的位置信息找到真正处理这个事件的View,最后调用dispatchKey函数完成按键的处理
  4. 在Windows中应用程序的按键处理流程是每一个按键事件都会转化成一个消息,这个消息将由系统加入到对应进程的消息队列中。该进程的消息在派发处理时,会根据消息的句柄找到对应的Window(窗口),继而该消息就由这个Window处理了

Activity的UI绘制

  1. ViewRootImpl 的setView函数中,会调用requestLayout,调用scheduleTraversals往handler中发送了一个消息,然后执行TraversalRunnable调用到doTraversal,doTraversal中调用performTraversals,然后调用relayoutWindow和performDraw,performDraw中进而调用draw(boolean fullRedrawNeeded)函数开始绘制
* frameworks/base/core/java/android/view/ViewRootImpl.java
void scheduleTraversals() {
        if (!mTraversalScheduled) {
            mTraversalScheduled = true;
            mTraversalBarrier = mHandler.getLooper().getQueue().postSyncBarrier();
            mChoreographer.postCallback(
                    Choreographer.CALLBACK_TRAVERSAL, mTraversalRunnable, null);
            。。。
        }
    }

private void performTraversals() {
	final View host = mView;//这个mView就是DecorView

	。。。
	boolean hwInitialized = false;
    boolean contentInsetsChanged = false;
    boolean hadSurface = mSurface.isValid();
    。。。
    relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
    。。。
    performDraw();
}
  1. relayoutWindow中会调用IWindowSession的relayout函数,进入到WMS的流程
* frameworks/base/core/java/android/view/ViewRootImpl.java
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
     boolean insetsPending) throws RemoteException {
     。。。
     //调用IWindowSession的relayOut
     int relayoutResult = mWindowSession.relayout(mWindow, mSeq, params,
                (int) (mView.getMeasuredWidth() * appScale + 0.5f),
                (int) (mView.getMeasuredHeight() * appScale + 0.5f), viewVisibility,
                insetsPending ? WindowManagerGlobal.RELAYOUT_INSETS_PENDING : 0, frameNumber,
                mTmpFrame, mPendingOverscanInsets, mPendingContentInsets, mPendingVisibleInsets,
                mPendingStableInsets, mPendingOutsets, mPendingBackDropFrame, mPendingDisplayCutout,
                mPendingMergedConfiguration, mSurfaceControl, mTempInsets);
     if (mSurfaceControl.isValid()) {
         mSurface.copyFrom(mSurfaceControl);
     } else {
         destroySurface();
     }
     。。。
}
  1. draw负责界面的绘制流程
private boolean draw(boolean fullRedrawNeeded) {
        Surface surface = mSurface;
        。。。
        if (!drawSoftware(surface, mAttachInfo, xOffset, yOffset,
                        scalingRequired, dirty, surfaceInsets)) {
                    return false;
                }
        。。。。
}

private boolean drawSoftware(Surface surface, AttachInfo attachInfo, int xoff, int yoff,
            boolean scalingRequired, Rect dirty, Rect surfaceInsets) {
         // // Draw with software renderer.
        final Canvas canvas;
        。。。
        canvas = mSurface.lockCanvas(dirty);//从mSurface中lock一块Canvas
        。。。
        mView.draw(canvas);//调用DecorView的draw函数
        。。。
        surface.unlockCanvasAndPost(canvas);
}

Surface 创建过程
Surface 创建过程

  • 3
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: SurfaceFlingerAndroid系统中的一个重要组件,负责管理和显示所有的图形界面。它的显示流程如下: 1. 应用程序创建一个Surface对象,将图形数据发送给SurfaceFlinger。 2. SurfaceFlinger将图形数据存储在一个称为SurfaceTexture的缓冲区中。 3. SurfaceFlinger使用OpenGL ES对图形数据进行处理和渲染。 4. SurfaceFlinger将渲染后的图像发送到显示器。 5. 如果有多个应用程序同时发送图形数据,SurfaceFlinger会根据优先级和Z轴深度对它们进行排序和合成。 6. 最终,SurfaceFlinger将所有图形数据合成为一个图像,并将其显示在屏幕上。 总之,SurfaceFlingerAndroid系统中的一个非常重要的组件,它负责管理和显示所有的图形界面,保证了Android系统的流畅性和稳定性。 ### 回答2: SurfaceFlingerAndroid的图形渲染引擎,负责掌控所有图形对象的显示。下面是SurfaceFlinger的显示流程。 1. 确定显示设备:SurfaceFlinger首先要确定使用哪个硬件设备来显示图像。 2. 提取图形对象:SurfaceFlinger会提取界面中包含的所有图形对象,这些对象可以是应用程序创建的窗口,也可以是系统悬浮窗、状态栏、壁纸等。 3. 图形对象组装:SurfaceFlinger会将所有被提取的图形对象组装成层(layer),按照层级关系维护图形对象的顺序。 4. 图形对象合成:SurfaceFlinger会使用OpenGL ES对所有层进行合成,生成一张完整的帧缓存。 5. 帧缓存提交:SurfaceFlinger将生成的帧缓存提交给硬件设备进行显示。 整个显示过程中,SurfaceFlinger还负责处理窗口跨越的动画效果,以及处理图形对象的动态增加或删除等情况。 需要注意的是,在上述流程中,层级关系对于图形对象的显示非常重要。较上层的对象会覆盖掉较下层的对象,这个特性在界面中用于实现窗口的遮挡和浮动效果。而不同的层级可以有不同的属性,例如透明度等,这些属性也会影响它们在合成帧缓存时的表现。此外,每个图形对象在SurfaceFlinger内部都会有一个对应的Surface对象,Surface对象内部保存了该图形对象的像素数据,SurfaceFlinger会使用这些数据进行图形对象的合成和显示。 ### 回答3: SurfaceFlingerAndroid操作系统用于显示图形的一个重要组件,它负责管理系统中所有显示的界面,包括应用程序UI、系统UI、动画效果及其它与显示相关的任务。下面我们简单介绍一下SurfaceFlinger的工作流程。 SurfaceFlinger在系统启动时便会启动,它通过系统调用EGL创建一个屏幕缓冲区(framebuffer),这个缓冲区是硬件加速的显存空间,它用于显示内容。应用程序或系统UI产生的每一个图形子集必须是基于帧缓冲区中的Surface对象,这些Surface对象可以是不同应用或UI组件的输出。这些输出通常是在本地内存中被创建或花费大量的CPU时间计算,但是它们最终都会被发送到SurfaceFlinger进行显示处理。 在处理单个图形子集之前,SurfaceFlinger使用双缓冲技术来管理整个帧缓冲区的更新。当一帧完全渲染后,SurfaceFlinger直接交换当前帧缓冲区与另一个缓冲区的指针,实现页面刷新的无缝过渡。这种技术可以避免一些出现残影和撕裂的问题。 处理一个图形子集通常分为三个阶段:更新、合并和显示。在更新阶段,渲染线程会对传入的图形数据进行处理,并将其写入屏幕缓冲区的一个Surface中。在合并阶段,SurfaceFlinger会将所有正在显示的Surface的像素数据合并到屏幕缓冲区的输出Surface中,并应用混合和过滤效果。最后,在显示阶段,渲染引擎会将输出Surface中的像素数据转发到帧缓冲区中,然后输出到屏幕上显示给用户。 除了处理图形子集外,SurfaceFlinger还负责处理用户输入,并将其传递给正在显示的应用程序或UI组件。用户输入通常包括触摸事件、按键事件、语音输入和手写输入等。 总之,SurfaceFlingerAndroid系统中一个重要且复杂的组件,担负着管理和协调所有显示图像的任务,对于保证用户体验和操作流畅度起到了至关重要的作用。每个应用程序与SurfaceFlinger交互时,必须要遵循先进先出的原则,并且应用程序中应该尽可能地减少对SurfaceFlinger的请求,以保证更高的流畅度和性能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值