当前位置: 首页 > java >正文

android 四大组件—Activity源码详解

onCreate

ActivityThread.handleLaunchActivity

/*** ActivityThread 收到 AMS 的 LAUNCH_ACTIVITY 事务后进入的入口。* 负责把 ActivityClientRecord 真正变成可交互的 Activity 对象并启动其生命周期。** @param r                封装了 AMS 要启动的 Activity 全部信息(Intent、package、config 等)* @param pendingActions   来自 AMS 的“后续待办”列表(如是否调用 onPostCreate、是否 report 空闲等)* @param customIntent     可选,AMS 侧再次修正的 Intent(优先级高于 r.intent)* @return                 已经走完 onCreate 的 Activity 实例;若启动失败返回 null*/
@Override
public Activity handleLaunchActivity(ActivityClientRecord r,PendingTransactionActions pendingActions,Intent customIntent) {// 真正创建 Activity 实例、创建 PhoneWindow、attach 基类、调用 onCreate 等final Activity a = performLaunchActivity(r, customIntent);// 此处省略后续代码:// 1. 设置 pendingActions 标记位// 2. 执行 onStart、onPostCreate、reportSizeConfigurations 等// 3. 通知 AMS 进入 RESUMED 状态// 4. 触发 IdleHandler、内存压力统计return a;
}

ActivityThread.performLaunchActivity

/*** 把 AMS 传来的“要启动的 Activity” 真正变成 Java 对象并走完 onCreate 生命周期。* 返回已初始化完成的 Activity 实例;若失败返回 null。*/
private Activity performLaunchActivity(ActivityClientRecord r, Intent customIntent) {Activity activity = null;/* ---------- 1. 反射创建 Activity 对象 ---------- */try {java.lang.ClassLoader cl = appContext.getClassLoader();// 通过 Instrumentation 反射调用无参构造,实例化 Activityactivity = mInstrumentation.newActivity(cl, component.getClassName(), r.intent);} catch (Exception e) {// 异常会抛回 AMS,应用崩溃...}/* ---------- 2. 建立 Activity 与系统侧的关联 ---------- */// 把新生成的 Activity 塞进 ContextImpl,实现 getBaseContext()appContext.setOuterContext(activity);// attach 给 Activity 注入 PhoneWindow、主线程 Handler、Token、配置等// 这一步之后 Activity 才有 Window 可用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.activityConfigCallback,r.assistToken, r.shareableActivityToken);/* ---------- 3. 执行生命周期 onCreate ---------- */if (r.isPersistable()) {// 支持持久化存储的场景(API 21+)mInstrumentation.callActivityOnCreate(activity, r.state, r.persistentState);} else {// 普通场景mInstrumentation.callActivityOnCreate(activity, r.state);}return activity;   // 回到 handleLaunchActivity,继续走 onStart、onResume
}

Activit.attach 

在attach的时候创建了PhoneWindow

mWindow = new PhoneWindow(this, window, activityConfigCallback);

attach() 时 PhoneWindow 先创建好 mDecor 空壳

Activit.setContentView ->PhoneWindow.setContentView 

    public void setContentView(@LayoutRes int layoutResID) {getWindow().setContentView(layoutResID);initWindowDecorActionBar();}

PhoneWindow.setContentView 

/*** Activity/Dialog 的入口方法:把 layoutResID 对应的 XML 填充成真正可见的 View 树。* 首次调用时负责初始化 DecorView;同时把DecorView和PhoneWindow绑定* mDecor.setWindow(this);支持过渡动画(FEATURE_CONTENT_TRANSITIONS)。*/
public void setContentView(int layoutResID) {/* 1. 还没有 DecorView 就创建一个(含 TitleBar/ActionBar/状态栏背景等系统区域) */if (mContentParent == null) {installDecor();          // 生成 DecorView,并给 mContentParent 赋值} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {/* 2. 普通模式:先清掉旧内容,避免重复添加 */mContentParent.removeAllViews();}/* 3. 判断是否启用“内容过渡动画”(Transition) */if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {/* 3.1 用 Scene/TransitionManager 做切换动画(API 19+) */final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID, getContext());transitionTo(newScene);          // 旧 Scene → 新 Scene,自动执行过渡} else {/* 3.2 普通模式:直接把 XML inflate 到 mContentParent */mLayoutInflater.inflate(layoutResID, mContentParent);}/* 4. 通知 View 树重新计算 WindowInsets(状态栏/导航栏边距) */mContentParent.requestApplyInsets();/* 5. 回调告知 Activity/Dialog:内容已更换(供主题、ActionBar 等做后续调整) */final Callback cb = getCallback();if (cb != null && !isDestroyed()) {cb.onContentChanged();}/* 6. 标记:开发者已主动调用过 setContentView,后续某些逻辑可跳过默认填充 */mContentParentExplicitlySet = true;
}

onResume

ActivityThread.handleResumeActivity

public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,boolean isForward, String reason) {//执行activity的onResume,如果在这里添加messge,消息是先于加入wms的performTraversals,所有获取不到view的高度
//handleResumeActivity() → performResumeActivity() → Activity.performResume() → Instrumentation.callActivityOnResume() → Activity.onResume()if (!performResumeActivity(r, finalStateRequest, reason)) {return;
}// 条件:Activity 还没把窗口真正添加进 WMS
// 1. r.window == null            : 之前没有创建 PhoneWindow(第一次 resume)
// 2. !a.mFinished               : Activity 没有被 finish
// 3. willBeVisible              : 系统认为接下来需要可见
if (r.window == null && !a.mFinished && willBeVisible) {// 1. 从 Activity 中拿到 PhoneWindow;第一次 resume 时这里才真正拿到引用r.window = r.activity.getWindow();// 2. 取出 DecorView(此时已经 inflate 完成)View decor = r.window.getDecorView();// 先设为 INVISIBLE,等真正 ready 时再显示,避免闪屏decor.setVisibility(View.INVISIBLE);// 3. 准备 WindowManager(其实就是 Activity 内部的 WindowManagerImpl)ViewManager wm = a.getWindowManager();WindowManager.LayoutParams l = r.window.getAttributes();// 4. 缓存到 ActivityClientRecord,方便后续直接访问a.mDecor = decor;/* ===== 设置窗口属性 ===== */l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; // 普通应用窗口l.softInputMode |= forwardBit;   // 保留/叠加软键盘模式标志/* ===== 复用窗口的特殊处理 ===== */// r.mPreserveWindow = true 表示“热启动”场景:Activity 重建但 DecorView 复用if (r.mPreserveWindow) {a.mWindowAdded = true;  // 标记为“已添加”r.mPreserveWindow = false;// 通知 ViewRootImpl:Activity 回调(比如 onAttachedToWindow)可能已经变化ViewRootImpl impl = decor.getViewRootImpl();if (impl != null) {impl.notifyChildRebuilt();}}/* ===== 真正把 DecorView 添加到 WMS ===== */if (a.mVisibleFromClient) {          // 客户端希望可见if (!a.mWindowAdded) {           // 尚未 addViewa.mWindowAdded = true;wm.addView(decor, l);        // 真正向 WMS 添加窗口} else {// 已经 addView 过,但 LayoutParams 可能变化// 触发一次 onWindowAttributesChanged 让 Activity 有机会处理a.onWindowAttributesChanged(l);}}// 如果窗口已添加,但在 resume 过程中又启动了别的 Activity,// 则暂时保持 INVISIBLE,由后续逻辑决定何时真正显示。
}

ActivityThread.performResumeActivity

/*** 在 ActivityThread 中把指定 Activity 推进到 ** resumed ** 状态的核心方法。* 会被 handleResumeActivity() 调用,完成 onResume 生命周期并注册跟踪。** @param r               要恢复的 Activity 记录(token、Activity 实例、配置等)* @param finalStateRequest 是否来自 AMS 的最终状态请求(true 表示必须走到 resumed)* @param reason          触发原因字符串(如 "handleResumeActivity" 或 "activityIdle"),用于日志/调试* @return                如果 Activity 正常走完 onResume 返回 true;若中途销毁则返回 false*/
public boolean performResumeActivity(ActivityClientRecord r, boolean finalStateRequest,String reason) {/* 1. 先检查状态:确保 Activity 尚未被 finish 或销毁 */r.activity.onStateNotSaved();          // 清除“已保存状态”标记,允许 Fragment 事务提交/* 2. 真正调用生命周期:onRestart → onStart → onResume */r.activity.performResume(r.startsNotResumed, reason);// 内部流程://   · 若处于 stopped 状态,先走 onRestart() → onStart()//   · 无论之前状态,都走 onResume()//   · 通知 Fragment 进入 RESUMED//   · 设置 mResumed = true//   · 向 AMS 报告 idle(若需要)/* 3. 后续在 handleResumeActivity 还会:*    - 把 DecorView 添加到 WindowManager*    - 设置可见性 View.VISIBLE*    - 注册接收按键、触摸事件*/return true;   // 若未抛异常即视为成功
}

Activity.performResume

mInstrumentation.callActivityOnResume(this);

Instrumentation.callActivityOnResume

public void callActivityOnResume(Activity activity) {activity.mResumed = true;activity.onResume();if (mActivityMonitors != null) {synchronized (mSync) {final int N = mActivityMonitors.size();for (int i=0; i<N; i++) {final ActivityMonitor am = mActivityMonitors.get(i);am.match(activity, activity, activity.getIntent());}}}
}

http://www.xdnf.cn/news/20159.html

相关文章:

  • 沪深300股指期权包含上证50期权吗?
  • Chatwith:定制你的AI 聊天机器人
  • 如何从chrome中获取会话id
  • 三坐标测量机在汽车制造行业中的应用
  • 用得更顺手的 Protobuf 文件后缀、流式多消息、大数据集与“自描述消息”实战
  • 禁毒教育展厅互动设备-禁毒教育基地-禁毒体验馆方案-VR禁毒教育软件
  • 设计模式从入门到精通之(六)策略模式
  • 资源管理-dd命令
  • 《嵌入式硬件(三):串口通信》
  • Jenkins 监控方案:Prometheus + Grafana 实践
  • Java 学习笔记(进阶篇2)
  • 《Cocos Creator的2D、3D渲染使用记录》
  • 使用自定义固定公网URL地址远程访问公司内网OA办公系统,本地无需公网IP和专线让外网访问
  • 【Python基础】 19 Rust 与 Python if 语句对比笔记
  • Unity学习----【进阶】Addressables(二)--加载资源与打包及更新
  • Github | MoneyPrinterTurbo:自动化视频内容生成系统
  • 医疗AI中GPU集群设计与交付实践
  • Windows蓝屏解决方案(扩展)
  • C++进阶——继承 (1)
  • Dify on DMS,快速构建开箱即用的客服对话数据质检服务
  • Cursor Pair Programming:在前端项目里用 AI 快速迭代 UI 组件
  • STM32使用HAL库驱动铁电存储FM25CL64
  • 用 Shields.io 定制 README 个性徽章
  • 嵌入式铁头山羊stm32-SAR型ADC模块介绍、采样时间、转换时间-Day24
  • Web与Nginx
  • MCP 和 Fuction Call 有什么不同
  • Python基础(①④内存管理机制)
  • 【Element Plus 表单组件样式统一 CSS 文字特效实现指南】
  • 啥是两化融合?
  • 算法模板(Java版)_哈希表