Android UI 宇宙:Activity 与 Window 的协作传奇

44 阅读4分钟

一、城市管理局:核心服务的分工

在 Android 的 UI 宇宙中,有三个关键管理局共同维持秩序:

  1. AMS(Activity 管理局) :负责 Activity 的生命周期管理和任务栈调度,如同城市中的民政部门。

  2. WMS(窗口管理局) :管理所有窗口的位置、层级和显示状态,如同城市规划局。

  3. SurfaceFlinger(表面渲染师) :将窗口内容渲染到屏幕,如同城市中的美工团队。

java

// 核心服务的协作关系(简化示意)
public class UINiverse {
    void startActivity(ActivityRecord activity) {
        AMS.manageLifecycle(activity); // 民政部门处理生命周期
        WMS.createWindow(activity);   // 规划局创建窗口
        SurfaceFlinger.render(activity.getSurface()); // 美工渲染到屏幕
    }
}

二、Activity 的造房过程:从申请到入住

1. Activity 申请建房(创建 Window)

Activity 就像居民申请建造房屋(UI 界面),需要通过 WindowManager 向 WMS 提交申请:

java

// Activity造房过程
public class Activity {
    private PhoneWindow mWindow; // 房屋设计图
    private WindowManager mWindowManager; // 建房施工队
    
    void createWindow() {
        mWindow = new PhoneWindow(this); // 设计房屋
        mWindowManager = getWindowManager(); // 获取施工队
        mWindow.setContentView(R.layout.activity_main); // 装修房屋
    }
    
    void showWindow() {
        mWindowManager.addView(mWindow.getDecorView(), new WindowManager.LayoutParams()); // 施工队建房
    }
}

2. WMS 审批与规划

WMS 作为规划局,收到建房申请后会创建对应的 WindowState(房屋档案):

java

// WMS处理建房申请
public class WindowManagerService {
    private HashMap<IBinder, WindowState> mWindowMap; // 房屋档案库
    
    void createWindow(IBinder token, WindowManager.LayoutParams params) {
        WindowState windowState = new WindowState(this, token, params); // 创建房屋档案
        mWindowMap.put(token, windowState); // 存档
        windowState.attachToDisplay(); // 规划房屋位置
    }
}

3. ViewRootImpl:房屋施工队长

每个 Window 都有一个施工队长 ViewRootImpl,负责协调施工并与 WMS 沟通:

java

// 施工队长的工作
public class ViewRootImpl {
    private IWindowSession mWindowSession; // 与规划局的通信员
    private IWindow mWindow; // 施工队的工作汇报接口
    
    ViewRootImpl(IWindowSession session) {
        mWindowSession = session;
        mWindow = new W(); // 施工队的汇报接口实现
    }
    
    void build() {
        mWindowSession.addToDisplay(mWindow, ...); // 向规划局汇报施工进度
        scheduleTraversals(); // 安排施工流程
    }
    
    // 施工队的汇报接口
    private class W extends IWindow.Stub {
        @Override
        public void onWindowResized(...) { /* 汇报房屋尺寸变化 */ }
        // 其他施工进度汇报方法...
    }
}

三、Binder 通信:跨部门协作的秘密通道

各管理局之间通过 Binder 机制通信,如同城市部门间的加密电话:

java

// Binder通信关系图
public class BinderCommunication {
    // system_server进程中的服务端
    WindowManagerService extends IWindowManager.Stub {
        @Override
        public IWindowSession openSession(...) {
            return new Session(this); // 给App端发放通信许可证
        }
    }
    
    // App进程中的客户端
    class WindowManagerGlobal {
        private IWindowManager mService; // 规划局的电话热线
        private IWindowSession mSession; // 通信许可证
        
        void connectToWMS() {
            mService = IWindowManager.Stub.asInterface(
                ServiceManager.getService("window")); // 获取规划局热线
            mSession = mService.openSession(...); // 申请通信许可证
        }
    }
}

关键通信节点:

部门角色通信接口所在进程功能描述
WMSIWindowManagersystem_server接收 App 的窗口管理请求
SessionIWindowSessionsystem_server为 App 进程分配通信通道
ViewRootImpl.WIWindowapp 进程汇报窗口状态变化
ActivityRecordIApplicationTokensystem_server通知 WMS 关于 Activity 状态

四、房屋与居民的数量关系

  1. 一对一关系:一个 Activity 对应一个 PhoneWindow,如同一个居民对应一套房屋。

  2. 一对多关系:一个 App 可能有多个 Activity(多套房屋),但共享同一个 WindowManagerGlobal(同一个施工公司)。

  3. 特殊情况:没有 Activity 的悬浮窗 Service,如同没有居民的公共建筑,也需要向 WMS 申请窗口。

java

// 数量关系示意图
public class Relationship {
    void showRelations() {
        Activity activity1 = new Activity();
        Activity activity2 = new Activity();
        
        // 每个Activity有自己的Window
        PhoneWindow window1 = activity1.getWindow();
        PhoneWindow window2 = activity2.getWindow();
        
        // 同一App的Activity共享WindowManager
        WindowManager wm1 = activity1.getWindowManager();
        WindowManager wm2 = activity2.getWindowManager();
        System.out.println(wm1 == wm2); // 输出true,共享同一施工公司
    }
}

五、窗口的生命周期:从施工到拆迁

1. 窗口创建流程

图片

代码

Activity.onCreate

创建PhoneWindow

WindowManager.addView

ViewRootImpl创建

WMS创建WindowState

SurfaceFlinger分配Surface

Activity.onCreate

创建PhoneWindow

WindowManager.addView

ViewRootImpl创建

WMS创建WindowState

SurfaceFlinger分配Surface

豆包

你的 AI 助手,助力每日工作学习

2. 窗口销毁流程

当 App 进程死亡时,WMS 会收到死亡通知并清理窗口:

java

// WindowState中的死亡回调
public class WindowState {
    private DeathRecipient mDeathRecipient = new DeathRecipient() {
        @Override
        public void binderDied() {
            synchronized (mService.mWindowMap) {
                mService.removeWindowLocked(this); // 拆除房屋
                Slog.i(TAG, "WIN DEATH: 清理废弃房屋");
            }
        }
    };
    
    void registerDeathRecipient() {
        mClient.asBinder().linkToDeath(mDeathRecipient, 0); // 监听App进程死亡
    }
}

六、总结:UI 宇宙的运作法则

  1. Activity 是居民:负责业务逻辑,需要申请 Window 作为 UI 载体。

  2. WMS 是规划局:管理所有窗口的位置和显示规则。

  3. ViewRootImpl 是施工队长:协调窗口的绘制和更新。

  4. Binder 是通信网络:让各部门高效协作。

java

// 完整协作流程
public class UIFlow {
    public static void main(String[] args) {
        // 1. Activity申请建房
        Activity activity = new Activity();
        activity.createWindow();
        
        // 2. 施工队向规划局汇报
        ViewRootImpl root = new ViewRootImpl(activity.getWindowSession());
        root.build();
        
        // 3. 规划局存档并安排渲染
        WindowManagerService wms = WindowManagerService.getInstance();
        wms.createWindow(activity.getToken(), activity.getWindowParams());
        
        // 4. 美工团队渲染到屏幕
        SurfaceFlinger flinger = SurfaceFlinger.getInstance();
        flinger.render(activity.getSurface());
    }
}

通过这种分工协作,Android 的 UI 宇宙实现了从 Activity 启动到界面显示的完整流程,每个环节都有明确的角色和职责,确保 UI 交互的流畅和稳定。