摘要:由于啟用硬件加速所需的資源增加,您的應用程序將消耗更多。之所以虛線會在大部分手機上繪制成實現是因為就是因為的方法不支持硬件加速。其實通過上表可以看到,在級別以后,就可以不用關閉硬件加速也可以繪制定義的虛線了。
首發公眾號:Android程序員日記前言
作者:賢榆的榆
如果喜歡,請 關注 | 贊賞 | 點在看
閱讀時間:4978字 8分鐘
今天剛好是《千與千尋》在中國首映的日子。所以放一張《千與千尋》的海報,我也沒想到過去這么久了,其實都都已經看過很多遍了。但還是想要在大屏幕上再看一次。小時候看動畫片,媽媽會說,這動畫片有什么好看的,你能看一輩子呀!真是一語成真,估計這輩子是逃不出動漫的坑了。(杠精就別糾結動畫片和動漫的不同了,在媽媽眼里,那都是一樣一樣的!),好了,娛樂休閑之前先學習一波兒!
正文前幾天做一個界面的時候,再一次出現了虛線顯式成實現的問題,我沒出息的又去搜解決方案了,為了記憶深刻,狠了狠心,深挖了一下。一起來看看吧:
我在xml布局文件中通過給一個View設置一個背景畫了一條虛線分割線代碼如下:
view中引用的common_line_draw_dash.xml代碼如下:
可是設備上的實際效果也預期效果并不一致,見下圖:
可能很多開發小伙伴都碰到過這個問題,也知道只需要在View的xml布局中添加如下一行代碼即可解決問題。
android:layerType="software"
古話說“知其然知其所以然”
從谷歌官方提供的關于硬件加速的資料顯示:
從Android 3.0(API級別11)開始,Android 2D渲染管道支持硬件加速,這意味著在View的畫布上執行的所有繪圖操作都使用GPU。 由于啟用硬件加速所需的資源增加,您的應用程序將消耗更多RAM。
并且文章中還講到Android 4.0(API級別14)開始默認開啟了硬件加速;但是
再往上找了一些關于硬件加速的文章比如這篇《關于硬件加速那點事兒》
地址:https://www.jianshu.com/p/9cd...
這是一篇Android硬件加速官方文章的譯文
里面介紹了不支持硬件加速的一些操作:
在里面看了一下之后就去掃View的源碼了,果然不出五分鐘就找了上圖中倒數第三的方法saveLayer();
看到background.draw(canvas)方法時,你可能想問我怎么知道這個虛線xml文件,最后實例化之后的Drawble對象對應的GradientDrawble的對象。看下面這張圖,你就明白了:
按照平常,文章寫道這里就已經結束了,一切都已經說通了。但是作為一名程序員,嚴謹是一種良好職業操守,于是我又去了google官網看了英文原版關于硬件加速的介紹。
地址:https://developer.android.com...
然后這一看,就看出問題了。當我看到上面這張圖的時候,我特么就尷尬了。怎么和之前我看到的那張圖不一樣了?saveLayer方法支持硬件加速?還是不支持?后來又用google搜索了一些資料,確實沒有一項有力的證件證明saveLayer方法是不支持硬件加速的;
既然這樣我們就需要重新去須按照其他的證據來證明View在畫虛線時,無法使用硬件加速,雖然上面圖中找到的saveLayer方法不能證明是需要關閉硬件加速的原因。但是這個View繪制背景的流程是沒有問題的,并且我們知道用
既然在繪制背景流程中沒有可疑的不支持硬件加速的方法,那么在生成Drawable對象的過程是否能找得到一些可疑的方法呢?上面流程圖中的mBackground對象又是怎么來的?
帶著這兩個問題,思考了一下。這個View是通過xml膨脹生成的,那么應該會調用View的2各參數或3個參數的構造方法,然后我就順著這思路找了一下mBackground對象是怎么生成:
一路找下去找到了,上圖中藍色框部分的代碼
final Drawable.ConstantState cs; if (isColorDrawable) { cs = sPreloadedColorDrawables.get(key); } else { cs = sPreloadedDrawables[mConfiguration.getLayoutDirection()].get(key); } Drawable dr; boolean needsNewDrawableAfterCache = false; if (cs != null) { if (TRACE_FOR_DETAILED_PRELOAD) { // Log only framework resources if (((id >>> 24) == 0x1) && (android.os.Process.myUid() != 0)) { final String name = getResourceName(id); if (name != null) { Log.d(TAG_PRELOAD, "Hit preloaded FW drawable #" + Integer.toHexString(id) + " " + name); } } } dr = cs.newDrawable(wrapper); } else if (isColorDrawable) { dr = new ColorDrawable(value.data); } else { dr = loadDrawableForCookie(wrapper, value, id, density, null); }
然后大概可以看明白當cs不為null時,Drawable是通過cs.newDrawable()方法生成的。cs在上面代碼中的第一行已經定義了,它是一個Drawable的靜態內部類Drawable.ConstantState;
既然前面我們已經知道用
GradientState類重寫了ConstantState的newDrawable方法,在該方法中通過調用GradientDrawable的構造方法構建了一個GradientDrawable實例。
在GradientDrawable構造方法中則進行了一些初始動作,其中調用的updateLocalState方法中的一段代碼(上圖藍色框)引起了我注意,最引人注目的還是那段紅色框里的的方法。這個方法好像在不支持硬件加速的操作表中。喜極而泣!明了,明了...。
這里再粘一下這段代碼:
if (state.mStrokeDashWidth != 0.0f) { final DashPathEffect e = new DashPathEffect( new float[] { state.mStrokeDashWidth, state.mStrokeDashGap }, 0); mStrokePaint.setPathEffect(e); }
它判斷了StrokeDashWidth是否有值,如果有這則根據虛線的的兩個重要屬性state.mStrokeDashWidth和state.mStrokeDashGap構造一個DashPathEffect對象,然后在通過Paint的setPathEffect(e)方法來繪制虛線。
到這里一切都水落石出了。之所以虛線會在大部分手機上繪制成實現是因為就是因為Paint的setPathEffect()方法不支持硬件加速。其實通過上表可以看到,在Android 9(API級別28)以后,就可以不用關閉硬件加速也可以繪制XML定義的虛線了。
后記好了這篇文章就寫到這里吧,大家在追源碼的時候給大家一個提醒:
晚上10點以后不宜閱讀源,因為你根本停不下來。
雖然有些滑稽,但卻是真是的哈哈。
另外,如果你是初學者,到沒有必要花費太多精力去探索。畢竟初學者完成一個App,對知識和技術的廣度認知比深度要重要的多。但是到了一定時候(我也說不清是什么時候,你自己應該會有感覺)——我個人覺得是做了兩三年吧,當你遇到問題時,就不應僅僅只停留在解決問題的層面,還應該深入了解一下為什么。哪怕一開始你就知道導致這個問題的原因是某個方法。但是找出這個方法,這一探索,研究的過程才是這個階段你成長的最大助力。與君共勉!
如果有想法可以留言;覺得有幫助,可以關注我的公眾號
推薦閱讀系列文章
「Do.006」實戰(1)——我想說“開始吧”
「Do.007」實戰(2)——使用Github進行版本管理
「Do.008」實戰((3)——Git 分支管理模型
「Do.009」實戰(4)——AndroidStudio插件推薦
「Do.014」實戰(5)—— gradle 配置release與debug環境分離
其他
「Do.016」圖解Win電腦下載騰訊視頻轉mp4
「Do.017」如何高效使用Win電腦?
「Do.018」接私活兒,是否有必要?
「Do.019」2018這一年——年終總結
「Do.020」程序員該如何在寒冬中自處
「Do.021」一文了解AndroidStudio3.4的全部更新
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/75026.html
摘要:源碼常用的圖標有種一種是的菊花一種是的環今天我們用實現的環動畫下節課實現的菊花注意幀數少的原因實際動畫效果是很平滑的首先我們定義的畫布尺寸為在瀏覽器中縮放為顯示這個你可以根據實際需要調整定義環的圓心坐標為半徑為算下周長大概為后面會用 源碼: https://github.com/any86/any-... ios/android web常用的loading圖標有2種, 一種是ios的菊...
摘要:因為依賴關系不強制,所以用虛線表示關聯關系關聯關系是類屬性依賴,很關鍵,所以使用實線表示。源碼地址類圖參考慕課網設計模式精講大話設計模式設計模式之類圖學習二類圖 類圖(Class diagram)主要用于描述系統的結構化設計。類圖也是最常用的UML圖,用類圖可以顯示出類、接口以及它們之間的靜態結構和關系。 0x01.類圖中的元素 1.類 Class / 接口 Interface sho...
摘要:開箱即用的源碼地址洋蔥數學同款雷達圖支持自定義屬性雷達網的半徑該屬性決定了的寬高各屬性表示的最大進度雷達網的顏色雷達網的線寬各屬性文字的顏色各屬性文字和中心處名字的字體路徑中心連接區域的顏色中心連接區域的邊框顏色中心處的名字中showImg(https://user-gold-cdn.xitu.io/2019/5/13/16ab091f638c526a); showImg(https://u...
閱讀 3120·2023-04-25 15:44
閱讀 1889·2019-08-30 13:11
閱讀 2850·2019-08-30 11:11
閱讀 3072·2019-08-29 17:21
閱讀 1318·2019-08-29 15:38
閱讀 965·2019-08-29 12:49
閱讀 1810·2019-08-28 18:19
閱讀 3236·2019-08-26 14:01