【Android源码】官方源码学习

一. CoroutineContext 协程上下文

public interface CoroutineContext {
    public operator fun <E : CoroutineContext.Element> get(key: Key<E>): E?
    
    public fun <R> fold(initial: R, operation: (R, CoroutineContext.Element) -> R): R
    
    public operator fun plus(context: CoroutineContext): CoroutineContext =
        if (context === EmptyCoroutineContext) this else context.fold(this) { ...}
        
    public fun minusKey(key: Key<*>): CoroutineContext

    //注意这里,这个key很关键
    public interface Key <E : CoroutineContext.Element>
    
     public interface Element : CoroutineContext {
        public val key: Key<*>
    
        public override operator fun <E : Element> get(key: Key<E>): E? =
            if (this.key == key) this as E else null
        
        public override fun <R> fold(initial: R, operation: (R, Element) -> R): R =
            operation(initial, this)
            
        public override fun minusKey(key: Key<*>): CoroutineContext =
            if (this.key == key) EmptyCoroutineContext else this
         }
}

二. View类的dispatchTouchEvent源码

public boolean dispatchTouchEvent(MotionEvent event) {
    // 处理辅助功能相关
    if (mOnTouchListener != null && (mViewFlags & ENABLED_MASK) == ENABLED &&
            mOnTouchListener.onTouch(this, event)) {
        return true;
    }
    return onTouchEvent(event);
}

2.1 Android 中的典型设计模式:位掩码(Bitmask)

为什么不直接用 viewFlags = true/false 来表示是否启用(enabled),而是要用位运算的方式(如 (viewFlags & ENABLED_MASK) == DISABLED)?

  • 节省内存
    一个布尔值(boolean)在 Java 中虽然逻辑上是 true/false,但在 JVM 中实际上占用 1 字节(8 bit)。
    如果为每个状态都单独使用一个布尔变量,那么这些状态将占用 多个字节。
    而如果使用 一个 int 型变量(32 bit) 来存储多个状态标志,就可以将这些状态压缩到 一个变量中,大大节省内存。
  • 提高访问效率
    CPU 对整型数据的访问和位运算效率远高于访问多个布尔变量。位运算(如 &、|、~)是底层硬件直接支持的,执行速度非常快。
  • 便于扩展和组合
    使用位掩码可以很方便地 组合多个状态:

三. Dialog源码

3.1 show方法

public void show() {
    // 如果对话框已经在显示状态
    if (mShowing) {
        // 如果装饰视图(DecorView)存在
        if (mDecor != null) {
            // 如果窗口具有 FEATURE_ACTION_BAR 特性,则刷新 ActionBar 的菜单
            if (mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
                mWindow.invalidatePanelMenu(Window.FEATURE_ACTION_BAR);
            }
            // 将 DecorView 设置为可见状态
            mDecor.setVisibility(View.VISIBLE);
        }
        // 直接返回,不重复显示
        return;
    }

    // 重置取消标志为 false,表示对话框未被取消
    mCanceled = false;

    // 如果对话框尚未创建,则调用 onCreate 方法
    if (!mCreated) {
        dispatchOnCreate(null);
    } else {
        // 如果已经创建过,但 DecorView 被移除过,需要处理配置变更(如屏幕旋转)
        final Configuration config = mContext.getResources().getConfiguration();
        mWindow.getDecorView().dispatchConfigurationChanged(config);
    }

    // 调用 onStart 生命周期方法
    onStart();
    // 获取 DecorView
    mDecor = mWindow.getDecorView();

    // 如果 ActionBar 为 null 并且窗口支持 ActionBar,则创建 WindowDecorActionBar
    if (mActionBar == null && mWindow.hasFeature(Window.FEATURE_ACTION_BAR)) {
        final ApplicationInfo info = mContext.getApplicationInfo();
        mWindow.setDefaultIcon(info.icon); // 设置默认图标
        mWindow.setDefaultLogo(info.logo);  // 设置默认 Logo
        mActionBar = new WindowDecorActionBar(this); // 创建 ActionBar
    }

    // 获取窗口布局参数
    WindowManager.LayoutParams l = mWindow.getAttributes();
    boolean restoreSoftInputMode = false;

    // 检查软键盘输入模式是否未设置 FORWARD_NAVIGATION 标志
    if ((l.softInputMode
            & WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION) == 0) {
        // 添加 FORWARD_NAVIGATION 标志
        l.softInputMode |= WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
        restoreSoftInputMode = true;
    }

    // 将 DecorView 添加到 WindowManager 显示出来
    mWindowManager.addView(mDecor, l);

    // 如果之前修改了软键盘模式,则恢复
    if (restoreSoftInputMode) {
        l.softInputMode &= ~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
    }

    // 标记对话框为正在显示状态
    mShowing = true;

    // 发送显示完成的消息,可能用于通知监听器
    sendShowMessage();
}

四. ActivityThread

4.1 main方法

public static void main(String[] args) {
    // 开始性能追踪,标记为 "ActivityThreadMain",用于调试和性能分析
    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");

    // 安装选择性系统调用拦截器,用于增强安全性或监控系统调用
    AndroidOs.install();

    // 关闭 CloseGuard(资源未关闭检测机制),避免日志过多
    // 后续在调试构建中可通过 StrictMode 有选择地启用
    CloseGuard.setEnabled(false);

    // 初始化当前用户的运行环境(如路径、存储等)
    Environment.initForCurrentUser();

    // 确保证书存储模块使用正确的用户配置目录来加载 CA 证书
    final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
    TrustedCertificateStore.setDefaultUserDirectory(configDir);

    // 调用初始化与进程相关的 Mainline 模块(用于模块化系统更新)
    initializeMainlineModules();

    // 设置进程名称为 "<pre-initialized>",便于调试时识别
    Process.setArgV0("<pre-initialized>");

    // 为主线程准备 Looper,用于处理消息队列(MessageQueue)
    Looper.prepareMainLooper();

    // 从命令行参数中查找 "seq=xxx" 格式的进程启动序号
    long startSeq = 0;
    if (args != null) {
        for (int i = args.length - 1; i >= 0; --i) {
            if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
                startSeq = Long.parseLong(
                        args[i].substring(PROC_START_SEQ_IDENT.length()));
            }
        }
    }

    // 创建 ActivityThread 实例(Android 应用主线程的核心类)
    ActivityThread thread = new ActivityThread();
    // 将当前线程附加到系统进程中,传入启动序号
    thread.attach(false, startSeq);

    // 如果主线程的 Handler 未初始化,则获取当前线程的 Handler
    if (sMainThreadHandler == null) {
        sMainThreadHandler = thread.getHandler();
    }

    // 可选:开启消息日志打印(默认关闭)
    if (false) {
        Looper.myLooper().setMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
    }

    // 结束性能追踪
    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);

    // 启动主线程的消息循环,开始处理 UI 事件、Activity 生命周期等
    Looper.loop();

    // 如果 Looper.loop() 意外退出,抛出异常,主线程不应退出
    throw new RuntimeException("Main thread loop unexpectedly exited");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值