Android Framework學習二:Activity創建及View繪制流程

文章目錄

  • Window繪制流程
    • Window Manager Service(WMS)
    • Surface
    • SurfaceFlinger
  • 安卓View層次結構
    • Activity
    • PhoneWindow
    • Activity與PhoneWindow兩者之間的關系
    • ViewRootImpl
    • DecorView
      • DecorView 的作用
      • DecorView 的結構
      • 總結
  • Activity創建流程
  • View invalidate調用流程

Window繪制流程

在這里插入圖片描述
在安卓系統中,Window Manager Service(WMS)和 Surface 是與窗口管理和圖形顯示相關的重要概念。

Window Manager Service(WMS)

  • 功能概述:WMS 是安卓系統中負責管理窗口的系統服務。它主要負責窗口的創建、銷毀、布局、顯示順序以及與用戶交互等方面的管理。
  • 工作原理:當一個應用程序創建一個窗口(例如 Activity 的界面)時,它會向 WMS 發送請求。WMS 會為該窗口分配一個唯一的標識,并根據窗口的屬性(如大小、位置、層級等)將其添加到窗口管理列表中。在繪制窗口時,WMS 會協調各個窗口的位置和顯示順序,確保它們按照正確的方式顯示在屏幕上。當用戶進行觸摸屏幕等交互操作時,WMS 會根據觸摸事件的位置和窗口的布局,將事件分發給相應的窗口進行處理。

Surface

  • 概念:Surface 是安卓圖形系統中的一個重要概念,它代表了一個可繪制的區域,用于在屏幕上顯示圖形內容。可以將 Surface 看作是一塊畫布,應用程序可以在上面繪制各種圖形、圖像和文本等內容。
  • 作用:每個窗口都有一個或多個 Surface 與之關聯。當應用程序需要繪制窗口的內容時,它會通過 Surface 來獲取繪圖的上下文,然后使用圖形庫(如 OpenGL)在 Surface 上進行繪制。繪制完成后,Surface 會將繪制的結果提交給系統的圖形合成器(通常是 Surface Flinger),由圖形合成器將各個窗口的 Surface 進行合成,最終顯示在屏幕上。
  • 與 WMS 的關系:WMS 負責管理窗口的整體布局和顯示順序,而 Surface 則是窗口內容繪制的載體。WMS 會根據窗口的狀態和用戶的操作,通知應用程序更新其 Surface 的內容。例如,當窗口大小發生變化時,WMS 會通知應用程序重新繪制 Surface 以適應新的大小。同時,WMS 也會與 Surface Flinger 協作,確保各個 Surface 能夠按照正確的順序和方式進行合成和顯示。

SurfaceFlinger

SurfaceFlinger是 Android 系統中的一個關鍵服務,主要負責將不同應用程序的 2D、3D surface 進行組合,并將最終合成的圖像發送到顯示設備進行顯示。

安卓View層次結構

Activity包含PhoneWindow、DecorView、ViewRootImpl等
在這里插入圖片描述

Activity

Activity屬于安卓應用程序的四大組件之一,它為用戶提供了一個可視化的界面,讓用戶能夠與應用進行交互。每一個Activity都代表著一個屏幕畫面,像是登錄界面、主界面等。
在安卓中,Activity是由ActivityManagerService(AMS,活動管理器服務) 創建的 。
以下是Activity的一個簡單示例:

import android.app.Activity;
import android.os.Bundle;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}
}

PhoneWindow

PhoneWindow是Window類的具體實現,Window類在安卓系統里代表著一個頂級的視覺容器,它負責管理窗口的樣式、背景以及標題欄等。PhoneWindow主要處理窗口的具體顯示邏輯,例如設置窗口的背景、標題欄、內容視圖等。

Activity與PhoneWindow兩者之間的關系

  • 包含關系:Activity包含一個PhoneWindow對象,在Activity的創建過程中,會默認創建一個PhoneWindow對象。
  • 視圖關聯:Activity通過PhoneWindow來設置和管理其視圖。Activity的setContentView()方法實際上是調用了PhoneWindow的setContentView()方法。
// Activity類中的setContentView方法
@Override
public void setContentView(@LayoutRes int layoutResID) {getWindow().setContentView(layoutResID);initWindowDecorActionBar();
}

Activity是用戶交互的界面載體,負責處理用戶的操作和業務邏輯;PhoneWindow則是窗口的具體實現,負責窗口的顯示和管理。它們緊密協作,共同構成了安卓應用程序的用戶界面。

ViewRootImpl

  • 概述:ViewRootImpl是View與WindowManager之間的橋梁,它不是一個真正的View,但它管理著一個View樹的根節點,在Android系統中,每個Window都對應著一個ViewRootImpl實例。
    作用
  • 視圖繪制管理:負責協調View樹的繪制過程,包括測量(measure)、布局(layout)和繪制(draw)三個階段。它會根據屏幕的刷新頻率,通過Choreographer來觸發視圖的重繪,確保界面能夠及時更新。
  • 事件分發:接收系統傳遞的輸入事件,如觸摸事件、按鍵事件等,并將這些事件分發給View樹中的各個View進行處理。它是事件從系統到應用View的重要傳遞環節。
  • 與窗口管理器交互:與WindowManagerService(WMS)進行通信,負責處理窗口的創建、銷毀、大小調整等操作。例如,當Activity啟動時,ViewRootImpl會與WMS交互來創建窗口,并將DecorView添加到窗口中。

DecorView

在 Android 系統中,DecorView 是窗口(Window)的最頂層視圖(頂級 ViewGroup),它作為整個窗口的根視圖,包含了系統的裝飾(如狀態欄、導航欄)和應用程序的內容視圖(如 Activity 的布局)。

DecorView 的作用

  • 窗口的根容器:每個 Activity 的窗口(PhoneWindow)都包含一個 DecorView,它是 View 層級的最頂層。
  • 管理系統 UI:DecorView 負責處理系統窗口裝飾(如狀態欄、ActionBar/Toolbar)和應用程序內容的協調。
  • 內容視圖的父容器:開發者通過 setContentView() 設置的布局會被添加到 DecorView 的一個子 ViewGroup(通常是 FrameLayout,ID 為 android.R.id.content)中。

DecorView 的結構

DecorView是每個Activity界面的頂層視圖,它是一個FrameLayout。
DecorView 通常包含以下兩部分:

  • 系統裝飾部分
    狀態欄(Status Bar)、導航欄(Navigation Bar)等系統 UI。
    由主題(Theme)控制是否顯示(如全屏模式會隱藏系統裝飾)。
  • 應用內容部分
    通過 setContentView() 設置的布局會被添加到 android.R.id.content 這個子 FrameLayout 中。

總結

DecorView 是 Android 窗口系統的核心組件,作為連接系統 UI 和應用內容的橋梁。理解它的結構和功能有助于處理全屏、鍵盤交互、窗口屬性等高級場景。實際開發中,通常只需通過 setContentView() 操作內容部分,而無需直接操作 DecorView。

Activity創建流程

Activity中AMS創建的。
在這里插入圖片描述

  • window的初始化是在 Acticity 創建的時候初始化, 在Acticity對象創建后,會調用attach方法,Windows對象就是這個時候創建的。
  • Activity的setContentView其實調用的是PhoneWindow的setContentView。
  • setContentView中調用installDecor()進行DecorView的初始化。
  • onResume中會調用WindowMangerImpl的addView, ViewRootImpl就是在這個addView中創建的。
  • addView會調用ViewRootImpl的setView,setView調用WMS的addView并調用requestLayout。
  • requestLayout調用scheduleTraversals(會創建surface),scheduleTraversals調用見下段invalidate流程后段會有講到主要是調用measure,layout,draw。

如下圖為addView流程
在這里插入圖片描述

View invalidate調用流程

在這里插入圖片描述

  1. 起始調用
    當我們希望重繪某個View時,直接調用其invalidate方法 。比如在自定義View的事件處理方法(如onClick) 或者數據更新邏輯中調用。invalidate方法會轉而調用invalidate(true) ,這里的參數表示是否同時使繪圖緩存無效,一般全量刷新時為true。
  2. invalidateInternal方法
    invalidate(true)會調用invalidateInternal方法,此方法會進行以下操作:
    判斷是否需要重繪:調用skipInvalidate方法判斷該View是否不需要重繪,不需要重繪的條件是該View不可見并且未進行動畫。
  • 處理重繪標志位:進一步判斷View是否需要繪制,如判斷表達式(mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) ,若滿足重繪條件,則處理相關標志位,將當前View標記為 “臟” ,即設置mPrivateFlags中的相關標志,表明該View需要重繪。
  • 確定重繪區域:對于開啟硬件加速的應用程序,調用父視圖的invalidateChild函數繪制整個區域;否則只繪制指定的dirty區域(r變量所指區域)。這是一個向上回溯的過程,每一層的父View都將自己的顯示區域與傳入的刷新Rect做交集。
  1. ViewGroup中的調用
  • invalidateChild方法:在ViewGroup中,invalidateChild方法會從當前的布局View向上不斷遍歷其父布局。它會先處理子View重繪相關邏輯,比如根據子View情況設置一些標志位,然后調用父布局的invalidateChildInParent方法。
  • invalidateChildInParent方法:該方法會計算需要重繪的區域 ,涉及到location數組(表示自身左邊、上邊距離父組件的距離,確立在坐標系的相對位置 )和dirty矩形(包含自身寬高,確立需要重繪的面積大小 )。計算后會繼續向上請求父布局重繪,直到父布局為ViewRootImpl 。
  1. ViewRootImpl中的處理
  • invalidateChildInParent方法:ViewRootImpl中的invalidateChildInParent方法會檢查線程是否正確 ,若dirty為null,表示要重繪整個區域,直接調用invalidate;若dirty為空且沒有動畫,就不需要重繪,直接返回。否則會對重繪區域進行進一步處理,如根據滾動偏移等情況調整區域。
  • invalidate方法:調用invalidate方法后,會通過scheduleTraversals方法安排一次視圖遍歷。
  1. 視圖遍歷與繪制
  • scheduleTraversals方法:安排視圖遍歷工作,將任務添加到消息隊列,待合適時機(比如下一次繪制周期 )執行。
  • performTraversals方法:視圖遍歷的核心方法,依次執行測量(performMeasure ,調用measure ,最終到onMeasure )、布局(performLayout ,調用layout ,最終到onLayout )、繪制(performDraw ,調用draw ,最終到onDraw )等步驟 ,完成整個View樹的更新繪制 。其中performDraw會進一步調用drawSoftware ,最終觸發View的draw方法,開始實際繪制。
    在這里插入圖片描述
    Android Framework學習一:系統框架、啟動過程
    Android Framework學習二:Activity創建及View繪制流程
    作者:帥得不敢出門

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/903908.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/903908.shtml
英文地址,請注明出處:http://en.pswp.cn/news/903908.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于ssm的智慧養老平臺(全套)

一、系統架構 前端:jsp | js | jquery | css 后端:spring | springmvc | mybatis 環境:jdk1.8 | mysql | maven | tomcat 二、代碼及數據庫 三、功能介紹 01. 登錄 02. 管理員-主頁 03. 管理員-個人中心 04. 管理員-…

計算機視覺技術的發展歷程

計算機視覺技術的發展歷程可以分為以下幾個階段: 早期探索階段(1960s-1980s) 1960年代:計算機視覺的概念開始形成,研究者嘗試讓計算機識別和理解圖像,主要集中在基礎的圖像處理,如邊緣檢測和特…

2025五一杯B題五一杯數學建模思路代碼文章教學: 礦山數據處理問題

完整內容請看文章最下面的推廣群 問題1. 根據附件1中的數據和,建立數學模型,對數據A進行某種變換,使得變換后的結果與數據盡可能接近。計算變換后的結果與數據的誤差,并分析誤差的來源(如數據噪聲、模型偏差等&#xf…

.NET 平臺詳解

什么是 .NET? .NET 是一個由微軟開發的跨平臺、開源的開發者平臺,用于構建多種類型的應用程序。它提供了一致的編程模型和豐富的類庫,支持多種編程語言(如 C#、F#、Visual Basic)。 .NET 的核心組成 運行時環境 CLR …

ICRA 2025 基于觸覺反饋的閉環分層控制框架——開放環境下通用門開啟的智能規劃與操作

在機器人領域,讓機器人在開放環境中與日常物品交互一直是個難題,其中開門任務極具挑戰性。門的設計、機械結構和推拉方式多種多樣,現有方法存在諸多局限。基于運動學的方法依賴已知門模型,面對未知門時難以發揮作用;幾…

阿里云服務遷移實戰: 07-其他服務遷移

概述 當完成了服務器、數據庫、IP、OSS等遷移后,剩下的就是其他服務了。 短信網關 短信模板只能一個個創建,不能批量操作。但是可以使用以下方式優化操作。 在原賬號導出模板列表 概述 當完成了服務器、數據庫、IP、OSS等遷移后,剩下的…

(六——下)RestAPI 毛子(Http resilience/Refit/游標分頁/異步大文件上傳)

文章目錄 項目地址一、Refit1.1 安裝需要的包1.2 創建接口IGitHubApi1.3 創建RefitGitHubService1. 實現接口2. 注冊服務 1.4 修改使用方法 二、Http resilience2.1 安裝所需要的包2.2 創建resilience pipeline簡單版2.3 創建全局的resilience處理1. 創建清理全局ResilienceHan…

leetcode 977. Squares of a Sorted Array

題目描述 雙指針法一 用right表示原數組中負數和非負數的分界線。 nums[0,right-1]的是負數&#xff0c;nums[right,nums.size()-1]是非負數。 然后用合并兩個有序數組的方法。合并即可。 class Solution { public:vector<int> sortedSquares(vector<int>&…

在 API 模擬階段:Apipost vs. Faker.js vs. Postman —— 為什么 Apipost 是最優選擇

在構建 API 的過程中&#xff0c;模擬數據的能力至關重要。就像你在做飯時等待食材送達一樣——沒有原料&#xff0c;菜也沒法完成。 但是&#xff0c;當你的后端還在開發中&#xff0c;而前端又急需真實的 API 響應進行開發時&#xff0c;該怎么辦&#xff1f;這時候&#xf…

一種快速計算OTA PSRR的方法(Ⅰ)

序言:最近碰到了一道有趣的習題&#xff0c;讓我重新思考了下如何計算運放的PSRR&#xff0c;再結合相關論文&#xff0c;現將所思所想分享出來&#xff0c;歡迎大家討論。 1.從Razavi的一道習題引入 題目要求計算電路的PSRR&#xff0c;已知PSRR定義為信號增益除以電源增益&am…

第十二屆藍橋杯 2021 C/C++組 空間

目錄 題目&#xff1a; 題目描述&#xff1a; 題目鏈接&#xff1a; 思路&#xff1a; 思路詳解&#xff1a; 代碼&#xff1a; 代碼詳解&#xff1a; 題目&#xff1a; 題目描述&#xff1a; 題目鏈接&#xff1a; 空間 - 藍橋云課 思路&#xff1a; 思路詳解&#…

TensorFlow深度學習實戰——基于循環神經網絡的情感分析模型

TensorFlow深度學習實戰——基于循環神經網絡的情感分析模型 0. 前言1. 數據處理2. 模型構建與訓練3. 模型評估相關鏈接 0. 前言 情感分析 (Sentiment Analysis) 是自然語言處理中的一項技術&#xff0c;旨在識別和提取文本中的情感信息&#xff0c;通常是分析一段文本中是否存…

eslint相關報錯收集

[vue/no-multiple-template-root]The template root requires exactly one element.eslint-plugin-vuejsx報錯&#xff1a;jsx報錯Parsing error: Unexpected token &#xff1c;eslint&#xff1b;ts報錯&#xff1a;Parsing error: Unexpected token {eslintmodule報錯 ‘mod…

【論文推薦】深度學習賦能地質災害分析:數據、模型、應用與機遇(用于地質災害分析的深度學習:數據源)

【論文推薦】深度學習賦能地質災害分析&#xff1a;數據、模型、應用與機遇&#xff08;用于地質災害分析的深度學習&#xff1a;數據源&#xff09; 【論文推薦】深度學習賦能地質災害分析&#xff1a;數據、模型、應用與機遇&#xff08;用于地質災害分析的深度學習&#xf…

判斷用戶選擇的Excel單元格區域是否跨頁?

VBA應用程序開發過程中&#xff0c;經常需要處理用戶選中的單元格區域&#xff0c;有的應用場景中&#xff0c;需要限制用戶選中區域位于同一頁中&#xff08;以打印預覽顯示的分頁劃分&#xff09;&#xff0c;但是VBA對象模型中并沒有提供相應的接口&#xff0c;用于快速查詢…

題解:洛谷 CF2091E Interesting Ratio

思路推導 我們先對 32 32 32 和 96 96 96 進行二進制拆分。 相同部分&#xff08;用 α \alpha α 表示&#xff09;&#xff1a; 5 5 5 個 2 2 2。 不同部分&#xff08;用 β \beta β 表示&#xff09;&#xff1a; 1 1 1 和 3 3 3。 gcd ? ( 32 , 96 ) \gcd(32,9…

linux安裝配置PostgreSQL

環境&#xff1a;centos7、SpringBoot、PostgreSQL15 PostgreSQL: Linux downloads (Red Hat family) PostgreSQL安裝 1.安裝 PostgreSQL Yum 倉庫 RPM 包 sudo rpm -ivh https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noar…

docker安裝jenkins v2.504.1集群

1 概述 Jenkins是一款開源的、基于Java開發的持續集成&#xff08;CI&#xff09;與持續交付&#xff08;CD&#xff09;工具&#xff0c;旨在通過自動化構建、測試和部署流程&#xff0c;提升軟件開發效率與質量。 ? 1.1 核心功能與特點 持續集成與交付? Jenkins支持自動化…

5月2日日記

今天看了爸爸推薦的書&#xff0c;叫&#xff1a;“高效能人士的七個習慣” 現在剛看完50頁&#xff0c;感覺確實有點東西&#xff0c; 七個習慣分別是&#xff1a; 個人層面1積極主動 2要事第一 3以終為始 社交層面 4知彼解己5 統效綜合 6雙贏思維 7不斷更新 目前還沒有…

Aws S3上傳優化

上傳大約 3.4GB 的 JSON 文件&#xff0c;zip算法壓縮后約為 395MB&#xff0c;上傳至 S3 效率優化&#xff0c;有一些優化方案可以提高上傳速率。下面是幾種可能的優化方式&#xff0c;包括選擇壓縮算法、調整上傳方式、以及其他可能的方案。 方案 1. 選擇更好的壓縮算法 壓…