新聞中心
Android進(jìn)階——百分比布局及擴(kuò)展
CSDN博客地址:
創(chuàng)新互聯(lián)專注于企業(yè)成都全網(wǎng)營銷、網(wǎng)站重做改版、長垣網(wǎng)站定制設(shè)計、自適應(yīng)品牌網(wǎng)站建設(shè)、H5開發(fā)、商城系統(tǒng)網(wǎng)站開發(fā)、集團(tuán)公司官網(wǎng)建設(shè)、外貿(mào)網(wǎng)站建設(shè)、高端網(wǎng)站制作、響應(yīng)式網(wǎng)頁設(shè)計等建站業(yè)務(wù),價格優(yōu)惠性價比高,為長垣等各大城市提供網(wǎng)站開發(fā)制作服務(wù)。
一、Android官方推出的百分比布局的使用
1、導(dǎo)入依賴
2、提供了如下的屬性
更多請參考: (需要正確上網(wǎng))
二、Android官方增強(qiáng)版百分比布局的使用——推薦使用
注:在官方的基礎(chǔ)上增加了布局PercentLinearLayout,支持百分比設(shè)置正方形,未改變官方原有的使用,支持設(shè)置字體的百分比,因此更推薦使用
1、導(dǎo)入依賴
2、支持的布局有
3、支持的屬性有
4、使用實例
效果圖
效果圖
效果圖
效果好像與直接使用xx%差不多,但是交換過來好像就不一樣了
效果圖
更多使用請參考:
android進(jìn)階-AIDL之接口注冊/解注冊
AIDL-基本使用
AIDL-自定義數(shù)據(jù)類型
AIDL-修飾符in,out,inout
AIDL-重連方法
AIDL-接口注冊/解注冊
AIDL-連接池
為什么要特意講解一下接口的注冊與取消注冊呢,因為在使用AIDL進(jìn)程跨進(jìn)程通信的時候, 每次傳遞的接口對象在內(nèi)存中的地址都是不一樣的 ,所以在注冊了之后,無法使用常規(guī)的方式去取消, 因為注冊和解注冊傳遞的接口地址都不一樣 ,系統(tǒng)無法識別
由于上面的問題,AIDL中提供了一個專門解決上述情況的類 RemoteCallbackList ,其工作原理就是:
首先,在前面講解 AIDL的基本使用 的基礎(chǔ)上先增加新的AIDL接口以及注冊和解注冊方法:
然后就是 RemoteCallbackList 的使用方法了:
注冊/解注冊很簡單
接著是使用接口的方式:
ps: 需要注意的是 beginBroadcast() 方法和 finishBroadcast() 方法 必須配合使用 ,哪怕只是簡單的獲取集合大小
使用AIDL進(jìn)行跨進(jìn)程間通信中,往往我們是需要注冊監(jiān)聽,讓服務(wù)端通知的,但是服務(wù)端也必須提供解注冊的方法,不然客戶端如果離開某個界面不想再接受消息了,雖然直接離開不做處理客戶端這邊不會出錯,但是服務(wù)端那邊的監(jiān)聽集合還存在之前的,那么就會浪費系統(tǒng)資源,所以有注冊監(jiān)聽的時候,最好也要實現(xiàn)解注冊的方法
《Android開發(fā)藝術(shù)探索》
Android 開發(fā)進(jìn)階:Kotlin Coroutines 使用詳解
還記得第一次聽到 Coroutines 的時候,納悶了一下,口瑞停,這是什么新的番號招式(誤),之后其實也沒有多在意了,好一段時間,因為一個檔案的 I/O 會把 UI Thread 卡住,必須要用異步程序去處理,寫 Handler Thread 可以避免,這也是最基礎(chǔ)的方式,缺點也很明顯某些時候還是避不掉,寫 RX 又總覺得微妙感覺有點殺雞用牛刀的感覺,后來看了一下決定用 Coroutines ,于是有了本篇文章。
普通情況下,執(zhí)行的順序會是很直白的 functionA() - functionB() - functionC() 。
如果只有一個 thread ,這樣很順暢沒問題。
但假如這是一個跑在 main thread 上,而 ·function A· 是需要另一個 thread 的處理結(jié)果,而該結(jié)果是需要該 thread 耗費長時間作業(yè)才可以獲得的。這邊姑且稱為 IO thread 好了。那不就意味著 function A 得等到 IO thread 處理結(jié)束并告知結(jié)果才能繼續(xù)執(zhí)行 function A 乃至 function B 之后才是 function C 呢?
那在等待 function A 的時候 main thread 啥事都不能做,只能 idle 在那邊動也不動。
這如果是在 Android main thread 上,這樣的行為會讓畫面 freeze ,時間稍微長一點就會 ANR 被 OS 當(dāng)作壞掉進(jìn)行異常排除了。
其實這個異步問題解決方案很多,諸如自己寫一個 callback ,或者自干 Handler thread 去控管或者是用 RX ,去訂閱之類。某些時候顯得不直觀,或者使用起來麻煩,總有種殺雞何需使用牛刀的感覺。
那有沒有可能?我就寫成上面那樣,但是當(dāng) function A 在等待 IO thread 時,讓 main thread 去做其他的事情,等到 IO thread 結(jié)束耗時處理后,再回來繼續(xù)執(zhí)行 function A , function B 、 function C 呢?
是的,可以,這個解決方案便是 Coroutine 。
Coroutines ,這個單字會被標(biāo)成錯字,理由是他其實是兩個單字合并而成的,分別是 cooperation + routine, cooperation 意指合作,routine 意指例行作業(yè)、慣例,照這里直接翻譯就會是合作式例行作業(yè)。
想到輝夜姬讓人想告白提到了慣例行為,也是念作 routine
那我們看到的翻譯多半會是協(xié)程、協(xié)作程序…這樣講沒啥前后感,誰協(xié)助程序?協(xié)助啥程序? 總之就是滿頭的問號。
這里 routine 指得是程序中被呼叫的 function、method ,也就是說,我們將 function 、method 協(xié)同其他更多的 function、method 共同作業(yè)這件事情稱為 Coroutines 。
協(xié)同作業(yè)聽起來還是很抽象,具體協(xié)同什么呢?
這便是 Coroutines 最典型的特色,允許 method 被暫停( suspended)執(zhí)行之后再回復(fù)(resumed)執(zhí)行,而暫停執(zhí)行的 method 狀態(tài)允許被保留,復(fù)原后再以暫停時的狀態(tài)繼續(xù)執(zhí)行。
換句話說,就是我在 main thread 執(zhí)行到 function A 需要等 IO thread 耗時處理的結(jié)果,那我先暫停 function A , 協(xié)調(diào)讓出 main thread 讓 main thread 去執(zhí)行其他的事情,等到 IO thread 的耗時處理結(jié)束后得到結(jié)果后再回復(fù) function A 繼續(xù)執(zhí)行,已得到我要的結(jié)果,這便是 Coroutines 的概念,這聽起來不是很簡單了呢?
事實上這個概念早在 1964 年就已經(jīng)被提出了,而很多語言也都有這樣的概念,只是 Android 上頭類似的東西一直沒有被積極推廣,直到 Kotlin 成為官方語言后, Coroutines 以 Support Library 的形式被推廣才又在 Android 業(yè)界流行起來。
首先,因為 Kotlin 的 Coroutine 并沒有包含在原有包裝中,而是以 Support Library 的形式提供開發(fā)者使用,所以需要另外導(dǎo)入該 Library。
這里選用這個版本進(jìn)行演示,實際中可以根據(jù)自己的需要修改版本。
那因為是在 Android 上使用的, Android 上頭的 main thread 跟普通 java 有點不一樣,所以還需要另一個 implementation,不然會報錯。
導(dǎo)入之后就可以開始使用了。
這邊我想做的是畫面上有一個會倒數(shù)的 Text ,用 Coroutines 可以簡單地做到
那跑起來結(jié)果就像這樣:
這樣如果要 Thread 有相同的結(jié)果可以寫成這樣:
這樣會有什么問題就是另一個故事了,至少現(xiàn)在這樣不會馬上出現(xiàn) Exception (最常見的就是使用者離開畫面沒多久就出現(xiàn)一個 Exception),不過也并不是說用 Coroutines 就不會發(fā)生這些問題,記得這些做法沒有什么優(yōu)劣,差別在都選擇就是了。
說回 Coroutines ,那跟 Thread 一樣,某些時候我們會想要臨時把它停住,那 GlobalScope.launch 會回傳一個 Job class 的玩意
想要把它停住的話就用 cancel 即可
Scope 指得是范圍, Coroutines 可以作用的范圍。在 Main thread 上或是 IO thread 上,又或者希望開更多的 Worker thread,然后是可以在某個控制流(e.g Activity 的生命周期)中可被控制的。
原則上,在 Kotlin 里頭使用任何標(biāo)記 suspend 的 method(后面會提)都會在 Scope 里面,這樣才可以控制 Coroutines 的行進(jìn)與存活與否。
那這邊舉的例子, GlobalScope 繼承自 CoroutineScope 。它是 CoroutineScope 的一個實作,它的概念就是最高層級的 Coroutines ,它的作用的范圍伴隨著 Application 的生命周期,那其實他的概念與 Dispatch.Unconfined 相同(待會會提到),用他其實可以避免 Coroutines 被過早結(jié)束,但也要記得是,這個用法類似直接呼叫靜態(tài)函數(shù),需要注意。
那如果直接實作 CoroutineScope 呢?
那會要求實作一個 CoroutineContext ,這是什么玩意?指的就是 Coroutines 作用的情景,這邊可以指定他是在 Main thread 上或者就直接弄一個 Job 給他:
這樣 launch 的時候就會使用這個 Job 來操作了,如果沒有特別定義,那這個 Job 就是跑在 Worker thread 上了,用它更新 UI 會出現(xiàn) Exception ,這方面可以依據(jù)自己的需求去做調(diào)整。
不過更多時候我會希望他能夠跑在 Main Thread 上, Koltinx Coroutine 有提供 CoroutineScope 的實作 - MainScrope
Android進(jìn)階解密③—Hook
源碼的執(zhí)行是按照一定流程思路進(jìn)行的,hook就是在源碼的執(zhí)行流程之間插入一步操作,起到攔截,替換的作用;被改變的對象稱為hook點,一般將不易發(fā)生變化的類作為hook點;
學(xué)習(xí)hook必須了解代理模式,可以參考我這篇文章: 反射和動態(tài)代理
首先需要知道startactivity的流程: Android進(jìn)階解密①——activity的啟動過程
我們知道startActivity會通過mInstrumentation這個類,我們可以將這個類作為hook點;
自定義一個Instrumentation,在activity的工作過程中通過反射替換原來的Instrumentation,將原來的Instrumentation傳到代理類里面,通過method invoke保證原來的功能不變,然后可以添加自己的自定義操作;
首先拿到activity原來的Instrumentation對象,通過原來的Instrumentation構(gòu)建出一個InstrumentationProxy對象,將Proxy設(shè)置給activity,然后只要在startActivity()之前調(diào)用這個方法替換就可以了;
分享題目:android進(jìn)階,Android進(jìn)階之旅NDK實戰(zhàn)篇
網(wǎng)址分享:http://www.dlmjj.cn/article/hoijdc.html