真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

android深入理解,深入理解安卓系統(tǒng)

Android 深入理解單例模式

本文主要記錄使用單例模式的幾種形式,并分析各自的優(yōu)缺點(diǎn)。使用單例模式可以避免重復(fù)創(chuàng)建對象,以此來節(jié)省開銷,首先了解一下單例模式的四大原則:

創(chuàng)新互聯(lián)專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、孝南網(wǎng)絡(luò)推廣、微信平臺(tái)小程序開發(fā)、孝南網(wǎng)絡(luò)營銷、孝南企業(yè)策劃、孝南品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)為所有大學(xué)生創(chuàng)業(yè)者提供孝南建站搭建服務(wù),24小時(shí)服務(wù)熱線:18980820575,官方網(wǎng)址:www.cdcxhl.com

常用的單例模式有:餓漢模式、懶漢模式、雙重鎖懶漢模式、靜態(tài)內(nèi)部類模式、枚舉模式,我們來逐個(gè)解釋這些模式的區(qū)別。

關(guān)于 volatile 修飾符,又是一個(gè)內(nèi)容,需要理解:

參考(有例子,比較好理解): ,

靜態(tài)內(nèi)部類單例模式的優(yōu)點(diǎn):

那么有人會(huì)問了,如果有多個(gè)線程同時(shí)訪問 getInstance() 方法,會(huì)多次初始化類,然后創(chuàng)建多個(gè)對象嗎?答案是不會(huì)的,這我們需要了解一下類的加載機(jī)制:

虛擬機(jī)會(huì)保證一個(gè)類的clinit()方法在多線程環(huán)境中被正確地加鎖、同步,如果多個(gè)線程同時(shí)去初始化一個(gè)類,那么只會(huì)有一個(gè)線程去執(zhí)行這個(gè)類的clinit()方法,其他線程都需要阻塞等待,直到活動(dòng)線程執(zhí)行clinit()方法完畢。

所以如果一個(gè)類的clinit()方法中有耗時(shí)很長的操作,就可能造成多個(gè)進(jìn)程阻塞(需要注意的是,其他線程雖然會(huì)被阻塞,但線程喚醒之后不會(huì)再次進(jìn)入clinit()方法。因?yàn)樵谕粋€(gè)加載器下,一個(gè)類只會(huì)初始化一次。)

所以靜態(tài)內(nèi)部類單例模式不僅能保證線程的安全性、實(shí)例的唯一性、還延遲了單例的實(shí)例化。

但是靜態(tài)內(nèi)部類單例模式也有一個(gè) 缺點(diǎn) ,就是無法傳遞參數(shù)。因?yàn)樗峭ㄟ^靜態(tài)內(nèi)部類的形式去創(chuàng)建單例的,所以外部就無法傳遞參數(shù)進(jìn)去。

枚舉單例模式占用的內(nèi)存是靜態(tài)變量的兩倍,所以一般都不使用enum來實(shí)現(xiàn)單例。

單例有餓漢模式、懶漢模式、雙重鎖懶漢模式、靜態(tài)內(nèi)部類模式、枚舉模式這幾種形式。

餓漢模式在初始化類時(shí)就創(chuàng)建了對象,容易造成資源浪費(fèi);懶漢模式在多線程環(huán)境下有風(fēng)險(xiǎn);枚舉模式占用內(nèi)存過高。這三種模式都有明顯的弊端,所以一般不去采用。

雙重鎖懶漢模式使用了 volatile 修飾符,在性能上會(huì)差一點(diǎn)點(diǎn);靜態(tài)內(nèi)部類模式無法傳遞參數(shù)。但是這兩種方式都能保證實(shí)例的唯一性,線程的安全性,也不會(huì)造成資源的浪費(fèi)。所以我們在使用單例模式時(shí),可以在這兩種方式中酌情選擇。

參考文章:

深入理解android2-WMS,控件

title: '深入理解android2-WMS,控件-圖床版'

date: 2020-03-08 16:22:42

tags:

typora-root-url: ./深入理解android2-WMS-控件

typora-copy-images-to: ./深入理解android2-WMS-控件

WMS主要負(fù)責(zé)兩個(gè)功能, 一是負(fù)責(zé)窗口的管理,如窗口的增加刪除,層級.二是負(fù)責(zé)全局事件的派發(fā).如觸摸點(diǎn)擊事件.

先簡單介紹幾個(gè)重要的類

IWindowSession. 進(jìn)程唯一的.是一個(gè)匿名binder.通過他向WMS請求窗口操作

surface 繪畫時(shí),canvas會(huì)把內(nèi)容繪制到surface里.surface是有surfaceFlinger提供給客戶端的.

WindowManager.LayoutParams 集成自ViewGroup.LayoutParams.用來指明client端的窗口的一些屬性.最重要的是type. 根據(jù)這屬性來對多個(gè)窗口進(jìn)程ZOrder的排序.

windowToken.向WMS添加的窗口令牌.每個(gè)窗口都要有一個(gè)令牌.

IWindow. 是client提供給WMS的.繼承自binder.WMS通過IWindow對象來主動(dòng)發(fā)起client端的事件.

窗口的本周就是進(jìn)行繪制所使用的surface,客戶端向WMS添加窗口的過程,就是WMS為客戶端分配surface的過程.

ui框架層就是使用surface上繪制ui元素.及響應(yīng)輸入事件

WMS負(fù)責(zé)surface的分配.窗口的層級順序

surfaceFlinger負(fù)責(zé)將多個(gè)Surface混合并輸出.

WMS有SystemServer 進(jìn)程啟動(dòng).他和AMS其實(shí)是運(yùn)行于一個(gè)進(jìn)程中的.只是分別有各自的線程.

上邊傳入了兩個(gè)handler.這里就使用windowManager的handler來創(chuàng)建WMS.也就是在一個(gè)handerThread線程中創(chuàng)建

用來管理每個(gè)窗口的事件輸入.也就是把輸入事件轉(zhuǎn)發(fā)到正確的窗口

能獲取顯示系統(tǒng)的同步信號.用來驅(qū)動(dòng)動(dòng)畫的渲染

所有窗口動(dòng)畫的總管,在mChoreographer的驅(qū)動(dòng)下渲染所有動(dòng)畫

只有PhoneWindowManager一個(gè)實(shí)現(xiàn).定義了很多窗口相關(guān)的策略.是最重要的成員,比如負(fù)責(zé)窗口的zorder順序.

zorder就是各個(gè)窗口在z軸的值.越大越在屏幕上層.窗口就是根據(jù)zorder值一層一層堆在一起.

可以繪制的屏幕列表.默認(rèn)是只有1個(gè).

管理所以窗口的顯示令牌token,每個(gè)窗口都要屬于一個(gè)token.這里的IBinder 是

表示所有Activity的token. AppWindowToken是WindowToken的子類,這個(gè)list的順序和AMS中對mHistory列表中activity的順序是一樣的 .反應(yīng)了系統(tǒng)中activity的疊加順序.也就是說.所有窗口都有WindowToken.而Activity對應(yīng)的窗口則多了AppWindowToken.

每個(gè)窗口都對應(yīng)一個(gè)WindowState.存儲(chǔ)改窗口的狀態(tài)信息(這就和AMS中對每個(gè)activity抽象成ActivityRecord一樣)

這里的iBinder 是IWIndow類.

Session 是WMS提供給客戶端來與WMS進(jìn)行交互的,這是匿名binder.為了減輕WMS的負(fù)擔(dān).客戶端通過IWindowManager.openSession 拿到他的代理.然后通過代理與WMS交互.每個(gè)進(jìn)程唯一.

客戶端通過IWindowSession.add 來添加窗口. iWindowSession 是同aidl形成的.最終到了WMS.addWindow.

這里總的來說就是確立了客戶窗口的WindowToken.WindowState.和DisplayContent. 并都保存了起來.同時(shí)根據(jù)layoutparams.type進(jìn)行了些窗口等級的判斷.

WindowToken將同一個(gè)應(yīng)用組件的窗口安排在一起.一個(gè)應(yīng)用組件可以是Activity,InputMethod.

WindowToken使應(yīng)用組件在變更窗口時(shí)必須與自己的WindowToken匹配.

這里主要是為了處理窗口的層級關(guān)系而設(shè)立的.

只要是一個(gè)binder對象.都可以作為token向wms聲明.wms會(huì)把這個(gè)binder對應(yīng)起一個(gè)WindowToken.其實(shí)就是把客戶端的binder和wms里的一個(gè)WindowToken對象進(jìn)行了綁定.

因?yàn)锳ctivity比較復(fù)雜,因此WMS為Activity實(shí)現(xiàn)了WindowToken的子類 appwindowtoken.同時(shí)在AMS啟動(dòng)Activity的ActivityStack.startActivityLocked里聲明token.

然后在activityStack.realStartActivityLocked里在發(fā)給用戶進(jìn)程,然后用戶在通過這個(gè)binder和WMS交互時(shí)帶過來.

activity則在 activityStack 線程的handleResumeActivity 里把Activity 對應(yīng)的窗口,加入到wMS中

取消token 也是在AMS中 ,也就是說, AMS負(fù)責(zé)avtivity的token向WMS的添加和刪除.

當(dāng)然.Activity的 r.appToken 是 IApplicationToken.Stub ,他里邊有一系列的窗口相關(guān)的通知回調(diào).

這里總結(jié)下. AMS在創(chuàng)建Activity的ActivityRecord時(shí),創(chuàng)建了他的appToken,有把a(bǔ)ppToken傳送給WMS.WMS對應(yīng)匹配為APPWindowToken,最后還把這個(gè)appToken發(fā)送給activity.因此AMS就通過ActivityRecord就可有直接操作WMS對該窗口的繪制.如圖.

每個(gè)window在WMS里都抽象成了WindowState.他包含一個(gè)窗口的所有屬性.WindowState在客戶端對應(yīng)的則是iWidow.stub類.iWidow.stub有很多窗口通知的回調(diào).

WindowState被保存在mWindowMap里.這是整個(gè)系統(tǒng)所有窗口的一個(gè)全集.

HashMapIBinder, WindowToken mTokenMap .這里是 IApplicationToken(客戶端)和WindowToken的映射

HashMapIBinder, WindowState mWindowMap 這里是IWidow(客戶端)和WindowState的映射,并且WMS通過這個(gè)IWindow 來回調(diào)客戶端的方法.

上圖可以看出.每個(gè)activity 只有一個(gè)ActivityRecord.也只有一個(gè)AppToken,也就只有一個(gè)WindowToken.而一個(gè)acitvity可能有多個(gè)窗口.每個(gè)窗口對應(yīng)一個(gè)WindowState.

WindowToken用來和AMS交換. 而WindowState對應(yīng)的iWindow則是WMS來與客戶端交互的.

窗口顯示次序就是窗口在Z軸的排了.因?yàn)榇翱谑钳B加在一起的.因此就需要知道哪些顯示在上邊,哪些在下邊.這個(gè)由WindowState構(gòu)造時(shí)確定

可見.分配規(guī)則是由WindowManagerPolicy mPolicy來決定的.產(chǎn)生 mBaseLayer和mSubLayer. mBaseLayer決定該窗口和他的子窗口在所有窗口的顯示位置. mSubLayer決定子窗口在同級的兄弟窗口的顯示位置.值越高.顯示約靠上.

WindowState 產(chǎn)生了他自己這個(gè)窗口的layer值后.在添加窗口的時(shí)候就會(huì)把所有窗口按layer排序插入mWindows列表中,在通過 adjustWallpaperWindowsLocked();進(jìn)行層級調(diào)整.

當(dāng)客戶端通過IWindowsession.add后,客戶端還沒有獲得Surface.只有在執(zhí)行IWindowsession.relayout后.客戶端才獲得了一塊Surface. IWindowsession.relayout根據(jù)客戶端提供的參數(shù),為客戶端提供surface.具體實(shí)現(xiàn)是WMS.relayoutWindow

總的來說就是根據(jù)用戶傳入的參數(shù),更新WindowState.然后遍歷所有窗口布局.在設(shè)置合適的Surface尺寸,在返回給用戶端

performLayoutAndPlaceSurfacesLocked 會(huì)循環(huán)調(diào)用6次.里邊的邏輯大概如下

這里主要下,因?yàn)橹凹恿随i.requestTraversalLocked他又會(huì)重復(fù)執(zhí)行performLayoutAndPlaceSurfacesLocked();因此會(huì)重復(fù)循環(huán)執(zhí)行布局.

布局這部分就記個(gè)原理吧

布局完成后.客戶端的尺寸和surface都得到了.就可以繪制 了.WMS會(huì)通知客戶端布局發(fā)送變化

總結(jié),WMS 負(fù)責(zé)管理所有的窗口.包括系統(tǒng)窗口和APP窗口,而窗口必須有一個(gè)WindowToken所為標(biāo)識符.同時(shí)WMS為每個(gè)窗口創(chuàng)建一個(gè)WindowState類,這是窗口在服務(wù)端的抽象.WindowState則綁定了一個(gè)客戶端的IWindow類,WMS通過這個(gè)IWindow 向APP發(fā)送消息.

AMS在啟動(dòng)Activity的時(shí)候.把ActivityRecord.token 通過wms.addtoken 注冊到WMS.又把這個(gè)token發(fā)送到APP端.因此三方可以通過這個(gè)token正確找到對應(yīng)的數(shù)據(jù).

WMS負(fù)責(zé)給所以窗口按ZOrder排序,確定窗口的尺寸,提供繪畫用的surface.

Activity的窗口是先wms.addtoken 建立windowToken關(guān)系 . wms.addWindow. 添加串口, WMS.relayout獲取surface. 完成 .

一個(gè)windowToken對應(yīng)一個(gè)Activity. 但是可能對應(yīng)多個(gè)windowSatate.也就是對應(yīng)多個(gè)窗口.

是view樹的根實(shí)現(xiàn)類是viewRootImpl.但是他不是view.他是用來和WMS進(jìn)行交流的管理者.viewRootImpl內(nèi)部有個(gè)IWindowSession,是WMS提供的匿名binder,同時(shí)還有個(gè)iWindow子類,用來讓W(xué)MS給viewr發(fā)消息. view通過ViewRoot向WMS發(fā)消息.WMS在通過IWIndow 向APP發(fā)消息. 每個(gè)View樹只有一個(gè)ViewRoot,每個(gè)Activity也只有一個(gè)ViewRoot. UI繪制,事件傳遞.都是通過ViewRoot.

.實(shí)現(xiàn)類是PhoneWindow . Activity和View的溝通就是通過Window.Activity實(shí)現(xiàn)window的各種回調(diào).一個(gè)Activity也對應(yīng)一個(gè)PhoneWindow.也對應(yīng)一個(gè)View樹.

Docerview 就是View樹的根.這是一個(gè)View. 他由PhoneWindow管理. 下文的WindowManager也由phoneWindow管理.

他還管理window的屬性 WindowManager.layoutparams.

他是一個(gè)代理類.他集成自ViewManager.他的實(shí)現(xiàn)是WindowManagerImpl.這是每個(gè)Activity都有一個(gè).但是他只是把工作委托給了 WindowManagerGlobal來實(shí)現(xiàn). 他負(fù)責(zé)添加刪除窗口,更新窗口.并控制窗口的補(bǔ)件屬性WindowManager.Layoutparams.

是進(jìn)程唯一的.負(fù)責(zé)這個(gè)進(jìn)程的窗口管理.他里邊有三個(gè)集合.保存這個(gè)進(jìn)程所有窗口的數(shù)據(jù).這里的每個(gè)數(shù)據(jù)根據(jù)index得到的是同一個(gè)Activity屬性.所有的WindowManager的操作都轉(zhuǎn)到他這里來.

private final ArrayListView mViews 每個(gè)view是個(gè)跟節(jié)點(diǎn)

private final ArrayListViewRootImpl mRoots view對應(yīng)的viewRoot

private final ArrayListWindowManager.LayoutParams mParams 窗口的layoutparams屬性.每個(gè)窗口一個(gè)

對于一個(gè)acitivity對象永遠(yuǎn)對應(yīng)一個(gè)PhoneWindow,一個(gè)WindowManagerImpl,一個(gè)WMS端的APPWindowToken,一個(gè)AMS里的ActivityRecord(但是如果一個(gè)activity在棧里有多個(gè)對象,就有多個(gè)ActivityRecord和AppWindowToken),acitvity 的默認(rèn)窗口的view樹是DocerView.

一個(gè)窗口 對應(yīng)一個(gè)ViewRoot,一個(gè)View樹.一個(gè)WindowManager.LayoutParams,一IWindow(WMS回調(diào)app).一個(gè)WSM端的WindowSatate.

但是一個(gè)Activity可以有多個(gè)窗口,因此對應(yīng)WMS里可能有多個(gè)WindowSatate.這些WindowState都對應(yīng)一個(gè)AppWindowToken.

一個(gè)Activity可能被加載多次.因此在AMS中可能有多個(gè)ActivityRecord對應(yīng)這個(gè)activit的多個(gè)對象.

但是一個(gè)進(jìn)程則對應(yīng)一個(gè)WindowManagerGlobal.一個(gè)ActivityThread(主線程).一個(gè)ApplicationThread(AMS調(diào)用app).一個(gè)iWindowSession(viewroot向WMS發(fā)消息)

這里的區(qū)別就是 app與AMS 的交互是以進(jìn)程之間進(jìn)行通信.而App與WMS的交互.則是以窗口作為通信基礎(chǔ).

當(dāng)Activity由AMS啟動(dòng)時(shí).ActivityThread 通過handleResumeActivity執(zhí)行resume相關(guān)的操作.這個(gè)函數(shù)首先是執(zhí)行activity.resume, 此時(shí)activity 對應(yīng)的view樹已經(jīng)建立完成(oncreate中建立,PhoneWindow也創(chuàng)建了).需要把a(bǔ)ctivity的窗口添加到WMS中去管理.

這里的wm是WindowManager.是每個(gè)activity一個(gè).他內(nèi)部會(huì)調(diào)用WindowManagerGlobal.addView

WindowManagerGlobal.addView

這里會(huì)為窗口創(chuàng)建ViewRootImpl. 并把view.ViewRootImpl.WindowMa.LayoutParams都保存在WindowManagerGlobal中, 并通過ViewRootImpl向WMS添加窗口

如果這個(gè)窗口是子窗口(wparams.type = WindowManager.LayoutParams.FIRST_SUB_WINDOW

wparams.type = WindowManager.LayoutParams.LAST_SUB_WINDOW)

就把子窗口的token設(shè)為父窗口的token否則就是所屬activity的token.

在來個(gè)圖

在這里我們看到.我們通過mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 拿到的并不是遠(yuǎn)程的WMS.而是本地的WindowManagerImpl. 他又把請求轉(zhuǎn)發(fā)給WindowManagerGlobal ,而WindowManagerGlobal作為進(jìn)程單實(shí)例.又是吧請求轉(zhuǎn)給對應(yīng)窗口的ViewRootImpl.ViewRootImpl通過WMS的IWindowSession 把數(shù)據(jù)發(fā)給WMS.

ViewRootImpl用來溝通View和WMS.并接受WMS的消息.這是雙向的binder通信.作為整個(gè)空間樹的根部,控件的測量,布局,繪制,輸入時(shí)間的派發(fā)都由ViewRootImpl來觸發(fā).

ViewRootImpl由WindowManagerGlobal創(chuàng)建,是在activityThread.handleResumeActivity時(shí),先執(zhí)行activity.resume.在調(diào)用wm.addView. 就會(huì)執(zhí)行WindowManagerGlobal.addView里.創(chuàng)建ViewRootImpl,此時(shí)是在ui線程中.

ViewRootImpl里的mView屬性.host屬性,就是view樹

添加窗口時(shí)通過requestLayout();向ui線程發(fā)送消息.最后回調(diào)到ViewRootImpl.performTraversals.他是整個(gè)ui控件樹,measure.layout.draw的集合.

這里分為五個(gè)階段.

預(yù)測量階段.進(jìn)行第一次測量,獲得view.getMeasuredWitdh/Height,此時(shí)是控件樹期望的尺寸.會(huì)執(zhí)行View的onMeasure

布局階段,根據(jù)預(yù)測量的結(jié)果,通過IWindowSession.relayout向WMS請求調(diào)整窗口的尺寸這會(huì)使WMS對窗口重新布局,并把結(jié)果返回給ViewRootImpl.

最終測量階段, 預(yù)測量的結(jié)果是view樹期望的結(jié)果.WMS可能會(huì)進(jìn)行調(diào)整,在這里WMS已經(jīng)把結(jié)果通知了ViewRootImpl.因此這里會(huì)窗口實(shí)際尺寸performTraversals進(jìn)行布局.view及子類的onMeasure會(huì)被回調(diào)

布局階段. 測量完成后獲得空間的尺寸,布局要確定控件的位置,View及子類的onLayout會(huì)被回調(diào).

繪制階段,使用WMS提供的surface.進(jìn)行繪制,View及子類的onDraw會(huì)被回調(diào).

通常我們看到的都是 先measure,在layout在draw. 這里看到.其實(shí)measure先得到期望值,在和WMS溝通.WMS在調(diào)整后,返回確定值,在根據(jù)確定值進(jìn)行mesure.

measureHierarchy里會(huì)通過三次協(xié)商.執(zhí)行performMeasure 來確認(rèn)合適的尺寸.

performMeasure 會(huì)調(diào)用view 的measure 優(yōu)會(huì)調(diào)用onMeasure. 我們可重寫onMeasure來實(shí)現(xiàn)測量.而measure 方法是final的.onMeasure 的結(jié)果通過setMeasuredDimension方法保存.

對于view. onMeasure.比較容易. 對于ViewGroup.則還要遍歷調(diào)用他所以子view的measure. 并且需要考慮padding和子view 的margin. padding是控件外內(nèi)邊距. margin 是控件外邊距.

ViewGroup需要先測量完子view.在根據(jù)子view的測量值得到自己的寬高.舉例,如果只有一個(gè)子view.那么ViewGroup的寬= 子view的寬+子view的margin+viewg的padding. 至少是這個(gè)值.

繼續(xù)回到performTraversals

這里就是提前測量了一下.得到控件樹希望的尺寸大小,

通過relayoutWindow來布局窗口. ViewRootImpl 通過IWindowSession 來通知WMS進(jìn)行窗口布局.

這里主要下. 調(diào)用WMS后.WMS會(huì)調(diào)整窗口的尺寸. 同時(shí)會(huì)生成surface返回給ViewRootImpl. 因此后續(xù)的繪畫就有了畫布了.可以看到最后的參數(shù)是mSurface.這是本地的surface. 這里會(huì)和wms的進(jìn)行綁定.

接下來繼續(xù)performTraversals,綁定WMS返回的surface.然后更新尺寸.

最后進(jìn)行最終測量. 上邊過程太亂了. 了解下就行.還是看常見的控件繪制流程.

繪制由viewRootImpl.performTraversals觸發(fā), 抽取出來后,就是這樣

就是直接調(diào)用view樹的根的measure方法. 傳入到View

該方法是final .意味著無法重寫.這里又會(huì)調(diào)用onMeasure.

因此.對于view.在onMeasure中調(diào)整好高度,通過setMeasuredDimension設(shè)置好自己的測量寬高就可以了.

對應(yīng)ViewGroup.則在onMeasure中,先要遍歷子view.調(diào)用他們的measure(注意一定是調(diào)用子類的measure,measure又會(huì)調(diào)用onMeasure), 子view寬高都知道后,在根據(jù)子view的寬高來設(shè)置自己.也就是ViewGroup的寬高受子view影響.

可以看到view的measure又調(diào)用了onMeasure, 如果是view 則可以直接重新onMeasure來設(shè)定大小.而對于ViewGroup, 則需要重寫onMeasure來先遍歷子view.設(shè)定大小.然后再設(shè)定viewGroup的大小. ViewGroup并沒有重寫onMeasure.因?yàn)槊總€(gè)ViewGroup要實(shí)現(xiàn)的效果不同,需要自己完成.但ViewGroup提供了幾個(gè)方法供ViewGroup的繼承類來遍歷子view.

view的寬高由自己的layoutParams和父view提供的 widthMeasureSpec|heightMeasureSpec共同決定.

View 自己的寬高,是保存在LayoutParams中對,以寬舉例 LayoutParams.width 有三種情況,精確值(就是指定大小),MATCH_PARENT. WRAP_CONTENT,模式則有fuview提供.有 unspecified,exactly,at_most三種.

匹配如下.

其實(shí)這個(gè)很好理解. 如果子view自己指定了寬高.就用他的值就可以.如果子view是match_parent.那就使用父view提供的寬高. 如果子view是wrap_content,那就不能超過父view的值.

看下ViewGroup為子view繪制而提供的方法,可以看到.ViewGroup會(huì)減去padding和margin,來提供子view的寬高.

上步measure過程未完成后,整個(gè)view書的 測量寬高都得到了.也就是view.getMeasuredWidth()和getMeasuredHeight()

performLayout中會(huì)調(diào)用mView.layout. 這樣就把事件從ViewRootImpl傳遞到了view.而layout中又會(huì)調(diào)用onLayout.ViewGroup需要重寫onLayout為子view進(jìn)行布局,遍歷調(diào)用子view的layout.因此就完成整個(gè)view樹的laylut過程.

豎向的實(shí)現(xiàn), 豎向的就行把view從上到下一次排開

這里注意區(qū)分.measure過程是先得到子view的測量值,在設(shè)定父ViewGroup的值.而layout過程則是先傳入父view的左上右下值,來計(jì)算子view的左上右下的位置值.這里應(yīng)該具有普遍性.但不知道是否絕對.

performDraw 中的調(diào)用draw.又調(diào)用mView.draw.然后就進(jìn)入view樹的繪制了.

view的draw 又會(huì)調(diào)用onDraw ,viewGroup又調(diào)用dispatchDraw()把draw分發(fā)到子view里 繪制的畫布就是canvas. 這是從surface.lockCanvas中獲得的一個(gè)區(qū)域.

而在ViewGroup.dispatchDraw中.重要的一點(diǎn)是getChildDrawingOrder 表示子view的繪制順序.默認(rèn)是與ziview的添加順序一樣.我們也可以改變他.最后繪制的會(huì)顯示在最上邊,而這也影響view的事件傳遞順序.

view.draw. 就是一層一層的畫內(nèi)容.先畫北京,在onDraw.在畫裝飾什么的.

canvas.translate(100,300)通過平移坐標(biāo)系.使之后的內(nèi)容可以直接在新坐標(biāo)系中繪制.

這就是ViewGroup在向子view傳遞canvas的時(shí)候.方便多了. 會(huì)之前先對其ziview的左上角.那么子view就可以直接從自己坐標(biāo)軸的(0,0)開始繪制, 繪制完成后ViewGroup在還原原有坐標(biāo)系.

canvas.save. canvas.restore 用來保存還原坐標(biāo)系.

view.invalidate.

當(dāng)某個(gè)view發(fā)送變化需要重繪時(shí),通過view.invalidate向上通知到ViewRootImpl.從這個(gè)view到ViewRootImpl的節(jié)點(diǎn)都標(biāo)記為藏區(qū)域.dirty area. ViewRootimpl再次從上到下重繪時(shí),只繪制這些臟區(qū)域.效率高.

本來安卓兼容使用鍵盤,也支持,觸摸.二者的輸入事件派發(fā)不一樣.使用鍵盤時(shí)會(huì)有個(gè)控件處于獲得焦點(diǎn)狀態(tài).處于觸摸模式則由用戶決定. 因此控件分為兩類.任何情況下都能獲得焦點(diǎn).如輸入文本框.只有在鍵盤操作時(shí)才能獲得焦點(diǎn).如菜單,按鈕.

安卓里有觸摸模式.當(dāng)發(fā)送任意觸摸時(shí)進(jìn)入觸摸模式.當(dāng)發(fā)送方向鍵和鍵盤或者執(zhí)行View.requestRocusFromTouch時(shí),退出觸摸模式.

獲取焦點(diǎn). view.request.

先檢查是否能獲取焦點(diǎn),

然后設(shè)置獲取簡單的標(biāo)記,

向上傳遞到ViewRootimpl.保證只能有一個(gè)控件獲取焦點(diǎn).

通知焦點(diǎn)變化的監(jiān)聽者.

更新view的drawable狀態(tài),

requestChildFocus會(huì)把焦點(diǎn)事件層層上報(bào)取消原來有焦點(diǎn)的控件.最后的效果就是從viewrootimpl中.到最終有焦點(diǎn)的view.構(gòu)成一條 mFoucued 標(biāo)識的鏈條.來個(gè)圖就明白了.每個(gè)view的mFocused總是指向他的直接下級.

獲取focus的傳遞是從底層view到頂層的ViewRootImpl.而取消focus測試從頂層的ViewRootimpl到底層原來那個(gè)獲得焦點(diǎn)的view.

而如果是ViewGroup請求獲取焦點(diǎn),會(huì)根據(jù)FLAG_MASK_FOCUSABILITY特性來做不同方式,分別有先讓自己獲取焦點(diǎn),或者安卓view的索引遞增或者遞減來匹配view.

ViewRootImpl 中的.WindowInputEventReceiver接受輸入事件.他會(huì)把事件包裝成一個(gè)QueuedInputEvent.然后追加到一個(gè)單鏈表的末尾.接著重頭到尾的處理輸入事件,并通過deliverInputEvent完成分發(fā).這里會(huì)把單鏈表所有事件都處理完.

deliverInput中又會(huì)把觸摸事件執(zhí)行到通過 ViewPreImeInputStage.processKeyEvent. 轉(zhuǎn)入mView.dispatchPointerEvent(event).這里又進(jìn)入 dispatchTouchEvent

MotionEvent是觸摸事件的封裝.getAction可以拿到動(dòng)作的類型和觸控點(diǎn)索引號.

getX(),getY().拿到動(dòng)作的位置信息.通過getPointID拿到觸控點(diǎn)的id. 動(dòng)作以down 開頭.跟多個(gè)move.最后是up.

,當(dāng)事件返回true.表示事件被消費(fèi)掉了.

《深入理解Android:WiFi,NFC和GPS卷》pdf下載在線閱讀全文,求百度網(wǎng)盤云資源

《深入理解Android:WiFi,NFC和GPS卷》百度網(wǎng)盤pdf最新全集下載:

鏈接:

?pwd=xs5b 提取碼:xs5b

簡介:本書從實(shí)際應(yīng)用的需求出發(fā),適合所有Android系統(tǒng)工程師、Android應(yīng)用開發(fā)工程師和BSP開發(fā)工程師閱讀。本書是經(jīng)典暢銷書“深入理解Android”系列的新作,由資深A(yù)ndroid系統(tǒng)專家鄧凡平先生撰寫,全志和高通等公司資深專家擔(dān)任技術(shù)審校并強(qiáng)烈推薦。從通信專業(yè)知識和Android系統(tǒng)代碼實(shí)現(xiàn)的角度,對Netd、Wi-Fi、NFC和GPS等模塊的代碼進(jìn)行深入的剖析,旨在深刻揭示其實(shí)現(xiàn)原理和工作流程。其中涉及大量通信相關(guān)的專業(yè)知識,因此特意邀請全志和高通等著名芯片公司的資深專家擔(dān)任技術(shù)審校。

深入理解Android:SystemServer進(jìn)程的作用

看了一段時(shí)間關(guān)于SystemServer進(jìn)程的博客,有點(diǎn)小理解,寫一篇關(guān)于SystemServer的小筆記,然后走一遍過程。

ZygoteInit通過startSystemServer方法fork了一個(gè)SS進(jìn)程。這個(gè)進(jìn)程有啥作用呢。

handlerSystemServerProcess()方法只要是以下三個(gè)方法:

其中 applicationInit() 很有意思很重要。該方法中有一個(gè),invokeStaticMain方法通過反射調(diào)用main方法:

run方法最終通過反射調(diào)用SystemServer的main方法,作用是:

通過以上分析其實(shí)main方法的主要作用是:

1、調(diào)整系統(tǒng)時(shí)間

2、設(shè)置屬性persist.sys.dalvik.vm.lib.2的值為當(dāng)前虛擬機(jī)的運(yùn)行庫路徑

3、裝載libandroid_servers.so庫,初始化native層service

4、初始化系統(tǒng)Context

5、創(chuàng)建SystemServiceManager對象

6、調(diào)用startBootstrapServices(),startCoreServices(),startOtherServices()啟動(dòng)所有的Java服務(wù)

另外也可以看到為什么說handler默認(rèn)是主線程,以及android 應(yīng)用本身就是基于handler/Looper/Message的

startBootstrapServices():啟動(dòng)java層的各種服務(wù)。framwork層的服務(wù)。例如AMS

startCoreServices:啟動(dòng)核心服務(wù):

startOtherServices也與上面一樣啟動(dòng)各種服務(wù)。

總結(jié)下:SystemServer進(jìn)程最終會(huì)執(zhí)行到SystemServer類中的main方法中,初始化各種服務(wù)器,其中第一個(gè)初始化的就是ActivityManagerService。當(dāng)我們點(diǎn)擊啟動(dòng)app的時(shí)候。Zygote會(huì)對這個(gè)消息進(jìn)行處理,最終執(zhí)行到applicationInit。那么是在哪里調(diào)用方法啟動(dòng)應(yīng)用的呢?

《深入理解Android卷I》epub下載在線閱讀,求百度網(wǎng)盤云資源

《深入理解Android:Wi-Fi、NFC和GPS卷》(鄧凡平)電子書網(wǎng)盤下載免費(fèi)在線閱讀

資源鏈接:

鏈接:

提取碼: edhg ?

書名:深入理解Android:Wi-Fi、NFC和GPS卷

作者:鄧凡平

豆瓣評分:8.7

出版社:機(jī)械工業(yè)出版社

出版年份:2014-4-15

頁數(shù):575

內(nèi)容簡介:

本書是經(jīng)典暢銷書“深入理解Android”系列的新作,由資深A(yù)ndroid系統(tǒng)專家鄧凡平先生撰寫,全志和高通等公司資深專家擔(dān)任技術(shù)審校并強(qiáng)烈推薦。從通信專業(yè)知識和Android系統(tǒng)代碼實(shí)現(xiàn)的角度,對Netd、Wi-Fi、NFC和GPS等模塊的代碼進(jìn)行深入的剖析,旨在深刻揭示其實(shí)現(xiàn)原理和工作流程。其中涉及大量通信相關(guān)的專業(yè)知識,因此特意邀請全志和高通等著名芯片公司的資深專家擔(dān)任技術(shù)審校。本書從實(shí)際應(yīng)用的需求出發(fā),適合所有Android系統(tǒng)工程師、Android應(yīng)用開發(fā)工程師和BSP開發(fā)工程師閱讀。

全書共9章。第1章介紹本書的內(nèi)容組成、工具使用以及參考源碼的下載方法。第2章介紹Netd及相關(guān)的背景知識。第3~5章介紹Wi-Fi基礎(chǔ)知識,重點(diǎn)分析了wpa_supplicant的實(shí)現(xiàn),以及Android平臺(tái)中特有的Wi-Fi服務(wù)模塊WifiService。第6~7章講解了Wi-Fi聯(lián)盟推出的兩項(xiàng)重要技術(shù)Wi-Fi Simple Configuration和Wi-Fi P2P,以及它們在Android平臺(tái)中的代碼實(shí)現(xiàn)。第8章詳細(xì)介紹了NFC基礎(chǔ)知識,以及NFC在Android平臺(tái)中的代碼實(shí)現(xiàn)。第9章講解了GPS原理及Android平臺(tái)中的位置管理服務(wù)架構(gòu)。

本書主要內(nèi)容及特色:

本書所講解的Wi-Fi、NFC以及GPS模塊的背后都涉及非常多的專業(yè)知識,例如與Wi-Fi相關(guān)的802.11協(xié)議、Wi-Fi Alliance(Wi-Fi聯(lián)盟)定義的Wi-Fi Simple Configuration和Wi-Fi P2P協(xié)議、NFC Forum定義的一整套與NFC相關(guān)的協(xié)議、與GPS相關(guān)的衛(wèi)星導(dǎo)航原理、AGPS和OMA-SUPL協(xié)議等。顯然,如果不了解這些專業(yè)知識,就不可能真正掌握它們在Android平臺(tái)中的代碼實(shí)現(xiàn)。

考慮到這些專業(yè)知識的重要性,本書在講解Android平臺(tái)中Wi-Fi、NFC和GPS模塊的實(shí)現(xiàn)之前,先重點(diǎn)介紹與代碼相關(guān)的專業(yè)知識。當(dāng)然,這些專業(yè)知識內(nèi)容如此豐富,在一本書中無法全部涵蓋。為了方便讀者進(jìn)一步深入學(xué)習(xí),本書每章的最后都會(huì)列舉筆者在撰寫各章時(shí)所閱讀的參考資料。

以下是本書的內(nèi)容概述。

第1章介紹本書的內(nèi)容組成、使用的工具以及參考源碼的下載方法。

第2章介紹Netd以及相關(guān)的背景知識。

第3章介紹Wi-Fi基礎(chǔ)知識。Wi-Fi是本章的重點(diǎn),而且也是當(dāng)下最熱門的技術(shù)。

第4章介紹wpa_supplicant,它是Wi-Fi領(lǐng)域中最核心的軟件實(shí)現(xiàn)。

第5章介紹WifiService,它是Android平臺(tái)中特有的Wi-Fi服務(wù)模塊。

第6章和第7章介紹Wi-Fi Alliance推出的兩項(xiàng)重要技術(shù)——Wi-Fi Simple Configuration和Wi-Fi P2P,以及它們在Android平臺(tái)中的代碼實(shí)現(xiàn)。

第8章介紹NFC背景知識以及NFC在Android平臺(tái)中的代碼實(shí)現(xiàn)。NFC也是歷史比較悠久的技術(shù),希望它能隨著Android的普及而走向大眾。

第9章介紹GPS原理及Android平臺(tái)中的位置管理服務(wù)架構(gòu)。

附錄為筆者和審稿專家之一的吳勁良先生關(guān)于本書定位、學(xué)習(xí)方法等方面的討論。相信這些討論內(nèi)容能引起讀者的共鳴。

本書通過理論和代碼相結(jié)合的方式進(jìn)行講解,旨在引領(lǐng)讀者一步步了解Wi-Fi、NFC和GPS模塊的工作原理??傊P者希望讀者在閱讀完本書后能有以下收獲。

初步掌握Wi-Fi、NFC和GPS的專業(yè)知識。

根據(jù)其實(shí)現(xiàn)代碼,進(jìn)一步加深對這些專業(yè)知識的理解。

讀者對象:

適合閱讀本書的讀者包括:

Android系統(tǒng)開發(fā)工程師

系統(tǒng)開發(fā)工程師常常需要深入理解系統(tǒng)的運(yùn)轉(zhuǎn)過程,而本書所涉及的內(nèi)容正是他們在工作和學(xué)習(xí)中最想了解的。對具體模塊感興趣的讀者也可單刀直入,閱讀相關(guān)章節(jié)。

Wi-Fi、NFC或GPS的BSP開發(fā)工程師

BSP開發(fā)工程師更需要對Android平臺(tái)中這些模塊的工作原理及背景知識有深入的理解。雖然本書沒有介紹這些模塊在Linux Kernel層的實(shí)現(xiàn),但了解它們在用戶空間的工作流程也將極大幫助BSP開發(fā)工程師拓展自己的知識面。

對Wi-Fi、NFC和GPS感興趣的在校高年級本科生、研究生和其他讀者

在掌握理論的基礎(chǔ)上,如何在實(shí)際代碼中來實(shí)現(xiàn)或使用它們也許是眾多學(xué)子最想知道的。希望這本理論與代碼實(shí)現(xiàn)深度結(jié)合的書籍會(huì)助您一臂之力。

作者簡介:

鄧凡平 資深A(yù)ndroid系統(tǒng)工程師,對Android系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn)有非常深入的研究,曾擔(dān)任Tieto公司高級軟件架構(gòu)師。暢銷書“深入理解Android”系列的總策劃和主筆,出版有暢銷書《深入理解Android:卷I》和《深入理解Android:卷II》。喜歡鉆研,樂于分享,活躍于CSDN、51CTO和開源中國等專業(yè)技術(shù)社區(qū),撰寫的Android Framework源碼分析的系列文章深受讀者歡迎。2013年榮獲51CTO讀書頻道評選的“最受讀者喜愛的IT圖書作者獎(jiǎng)”。

《深入理解 Android卷 I I I》txt下載在線閱讀全文,求百度網(wǎng)盤云資源

《深入理解Android 卷III》(張大偉)電子書網(wǎng)盤下載免費(fèi)在線閱讀

鏈接:

提取碼: gjr8

書名:深入理解Android 卷III

作者:張大偉

豆瓣評分:9.0

出版社:機(jī)械工業(yè)出版社

出版年份:2015-8-1

頁數(shù):539

內(nèi)容簡介:

深入理解Android(卷3)》是Android經(jīng)典暢銷書系(對Android系統(tǒng)源代碼的分析最為系統(tǒng)和細(xì)致)“深入理解Android”系列Framework卷的第III卷,從源代碼的角度,對Android系統(tǒng)的Audio和UI兩大功能的相關(guān)模塊的實(shí)現(xiàn)原理和工作機(jī)制做了系統(tǒng)且詳細(xì)的分析,填補(bǔ)了市場的空白。

《深入理解Android(卷3)》在邏輯上分為4個(gè)部分:

Part 01(第1~2章):這是本書的基礎(chǔ)部分,首先介紹了Android源碼環(huán)境的搭建、編譯和調(diào)試;然后講解了Android進(jìn)程間通信與任務(wù)調(diào)度的工具Binder與MessageQueue。這兩項(xiàng)基礎(chǔ)工作是深入研究Android前必須做的功課。

Part 02(第3章):詳細(xì)分析了AudioService服務(wù)的實(shí)現(xiàn),包括音量管理、音頻外設(shè)管理、AudioFocus機(jī)制的實(shí)現(xiàn)等內(nèi)容。

Part 03(第4~6章):這是本書的核心內(nèi)容之一,詳細(xì)分析了Android UI的通用實(shí)現(xiàn),依次剖析了WindowManagerService、Android輸入系統(tǒng)、Android控件系統(tǒng)的工作原理。

Part 04(第7~8章):主要分析了SystemUI和Android壁紙相關(guān)服務(wù)的實(shí)現(xiàn),包括StatusBarManagerService與NotificationManagerService兩個(gè)系統(tǒng)服務(wù),以及WallpaperManagerService系統(tǒng)服務(wù)、動(dòng)態(tài)壁紙與靜態(tài)壁紙的工作原理等內(nèi)容。

作者簡介:

張大偉,資深A(yù)ndroid系統(tǒng)開發(fā)工程師,現(xiàn)就職于索尼移動(dòng)。從2011年開始從事Android開發(fā),專注于Android系統(tǒng)源代碼的研究、定制與維護(hù)工作,對Android的架構(gòu)設(shè)計(jì)與運(yùn)行原理有著深入的認(rèn)識與實(shí)踐經(jīng)驗(yàn),其中對UI相關(guān)模塊、多媒體系統(tǒng)尤為擅長。曾主持了Android多窗口、多任務(wù)以及單手操作等系統(tǒng)定制的開發(fā)工作。此外對于其他開發(fā)平臺(tái)如.NET亦有相當(dāng)?shù)慕?jīng)驗(yàn)。


網(wǎng)站題目:android深入理解,深入理解安卓系統(tǒng)
URL地址:http://weahome.cn/article/phsiii.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部