mvc mvp mvvm
mvc是最基礎(chǔ)的架構(gòu)牵素,最開始是從web引用過來的,但是在android里面膊畴,C就在activity里,activity其實(shí)是屬于view層病游,本身是不能做大量業(yè)務(wù)邏輯處理的唇跨,mvc在安卓中就會(huì)顯得笨拙,使activity變的繁雜不易維護(hù)和拓展衬衬,但是小項(xiàng)目又比較合適买猖,正因?yàn)榇箜?xiàng)目使用mvc把a(bǔ)ctivity作用變得不易維護(hù)所以衍生出了mvp,mvp是把a(bǔ)ctivity里的業(yè)務(wù)抽出來放到 Presenter里面滋尉,把a(bǔ)ctivity的位置還原到view層玉控,去實(shí)現(xiàn)用戶的所有操作接口,但是這里又會(huì)有個(gè)問題狮惜,presenter和activity也就是view的交互會(huì)很頻繁高诺,而這些操作都是用接口連接的,所以項(xiàng)目會(huì)增加很多接口文件碾篡,雖然現(xiàn)在有控件可以直接一鍵生成這樣的接口虱而,但是每次增加一個(gè)業(yè)務(wù)的時(shí)候就會(huì)比較繁瑣,會(huì)寫很多接口和實(shí)現(xiàn)類开泽,但是總的來說用mvp在中大型項(xiàng)目上用的時(shí)候可能覺得麻煩一點(diǎn)牡拇,但是在單元測(cè)試,拓展穆律,維護(hù)上會(huì)方便很多惠呼,而且一個(gè)presenter可以用于多個(gè)activity,可重用性更高峦耘,mvvm是改良版的mvp剔蹋,它用viewmodel代替了presenter,用dadabinding 做view和viewmode的數(shù)據(jù)綁定贡歧,數(shù)據(jù)發(fā)生改變view就會(huì)跟著改變滩租,因?yàn)閘ivedata 生命周期通過lifecycle和activity綁定赋秀,所以一定程度上app了頁面的內(nèi)存泄露問題,mvvm是現(xiàn)在主流的架構(gòu)也是Google主推的架構(gòu)
多線程
http網(wǎng)絡(luò)請(qǐng)求多線程律想,照片上傳多線程猎莲,人像比對(duì)多線程 多線程主要是要處理線程之間的共享變量,比如幾個(gè)線程同時(shí)請(qǐng)求技即,而請(qǐng)求結(jié)果需要做一個(gè)回調(diào)著洼,每個(gè)線程請(qǐng)求成功需要做一個(gè)計(jì)數(shù)器,而這個(gè)計(jì)數(shù)器就是共享變量而叼,多線程操作共享變量需要加鎖synconizied身笤,并且用volatile修飾保證變量操作的唯一性
join:調(diào)用join就是調(diào)用當(dāng)前線程的wait方法,等待join線程執(zhí)行完畢在調(diào)用當(dāng)前線程的notify方法恢復(fù)執(zhí)行葵陵,join方法必須要在線程運(yùn)行之后才有效
如何保證你的線程執(zhí)行完
(如何保證你的線程執(zhí)行完https://blog.csdn.net/wzy_1988/article/details/46875343液荸,用WakeLock,可以在鎖屏狀態(tài)下保持CPU的正常運(yùn)行脱篙,這個(gè)WakeLock是用來執(zhí)行一些關(guān)鍵代碼的娇钱,用完需要釋放,不然app會(huì)很耗電)后來發(fā)現(xiàn)是我配置的問題绊困,rxjava和retrofit的activity生命周期配置
kotlin
很多只是寫法變了文搂,關(guān)鍵字變了,邏輯還是差不多的秤朗,比如switch變成了when煤蹭,for循環(huán)變成for in,還有就是一些權(quán)限修飾符變了取视,默認(rèn)權(quán)限是final硝皂,open標(biāo)識(shí)可繼承,可重寫贫途,增加了新的權(quán)限internal標(biāo)識(shí)在當(dāng)前module中使用用起來比java方便吧彪,省掉了很多代碼,比如那種非空判斷只需要語句中加個(gè)問號(hào)就行丢早,邏輯都是差不多的
kotlin沒有static的變量姨裸,只能用companion派生對(duì)象關(guān)鍵字修飾,全局靜態(tài)對(duì)象用Object關(guān)鍵字(Util工具類)const常量
高階函數(shù)
forEach 遍歷數(shù)組
map 數(shù)組轉(zhuǎn)換
flatmap 多維數(shù)組轉(zhuǎn)換
let 變量定義作用域怨酝,非空判斷 返回最后一行
with 傳入對(duì)象傀缩,作用域最后一行是返回值
run 只接受lambda函數(shù) 返回最后一行
apply,返回函數(shù)本身作用域农猬,減少重復(fù)引用 不改變值
tcp/ip http
這些協(xié)議原理還是很深的赡艰,首先他們的層級(jí)是不一樣的,ip協(xié)議是用于網(wǎng)絡(luò)層的斤葱,tcp是傳輸層慷垮,http是應(yīng)用層揖闸,然后tcp又涉及到三次握手,對(duì)于這些協(xié)議我沒有研究的很深料身,平常用的多的還是http協(xié)議汤纸,http協(xié)議是建立在tcp上的一種應(yīng)用,他的特點(diǎn)就是每次發(fā)出請(qǐng)求都需要服務(wù)端回送響應(yīng)芹血,建立連接和關(guān)閉連接叫做一次連接 可以參考(https://blog.csdn.net/DavidStar1988/article/details/80400020)
rxjava
rxjava的話贮泞,其實(shí)大部分的項(xiàng)目,可以說90%在項(xiàng)目里用rxjava都是用在retrofit的adapter上幔烛,因?yàn)榇蟛糠猪?xiàng)目業(yè)務(wù)流程都比較簡(jiǎn)單啃擦,不用rxjava也就只是多幾個(gè)回調(diào)方法而已,但是我用rxjava的目的主要還是那種鏈?zhǔn)骄幊炭梢允鬼?xiàng)目的邏輯變得清晰饿悬,因?yàn)楹芏噙壿嬋绻短滋嗟脑挄r(shí)間長(zhǎng)了維護(hù)起來會(huì)很難看懂令蛉,所以我是覺得能使邏輯變清晰的框架都適合我,rxjava關(guān)鍵字很多乡恕,我用的比較多的是map言询,和flatmap,作用就是你可以像流水線一樣從Observable開始層層處理得到你想要的數(shù)據(jù)(兩個(gè)都是轉(zhuǎn)換數(shù)據(jù)傲宜,但是flatmap可以轉(zhuǎn)換成Observable類型的數(shù)據(jù),相當(dāng)于for循環(huán)內(nèi)又可以再for循環(huán))還有很多關(guān)鍵字比如just夫啊,from函卒,timer,interval撇眯,這些用到的時(shí)候不懂再去查一下很快就可以上手了报嵌,還是挺簡(jiǎn)單的
zip 合并observable
其他操作符https://blog.csdn.net/chaoyangsun/article/details/80373203
創(chuàng)建類型
concat 將Observable依次發(fā)送
merge 交錯(cuò),不按順序發(fā)送
ust 原樣發(fā)射
from 將數(shù)組分成單個(gè)依次發(fā)射
Interval 間隔發(fā)射
timer 延遲發(fā)射
轉(zhuǎn)換類型
map 轉(zhuǎn)換數(shù)據(jù) 比如給我的是url熊榛,但是我需要的是bitmap锚国,這時(shí)候就用map
filter 篩選,按條件篩選玄坦,比如篩選出非空的url
flatmap 相對(duì)于map血筑,可以多對(duì)多,比如在轉(zhuǎn)換數(shù)據(jù)的集合里進(jìn)行拆分
just 和from區(qū)別: just是設(shè)置什么就返回什么煎楣,from是把數(shù)組分成單獨(dú)的發(fā)送
https://blog.csdn.net/moonpure/article/details/78402347
retrofit
其實(shí)retrofit不是一個(gè)網(wǎng)絡(luò)請(qǐng)求庫豺总,它是一個(gè)請(qǐng)求庫上面的一個(gè)封裝,建立在okhttp上的一個(gè)庫择懂,特點(diǎn)就是你可以用注解去構(gòu)建一個(gè)網(wǎng)絡(luò)請(qǐng)求喻喳,他先是用接口去實(shí)現(xiàn)一個(gè)帶有注解的類,然后用retrofit的create去創(chuàng)建一個(gè)實(shí)體困曙,我看了一下源碼表伦,這個(gè)create里面是用了動(dòng)態(tài)代理來實(shí)現(xiàn)的他就是通過反射在一個(gè)class方法的前后增加邏輯代碼谦去,這些邏輯代碼就是用到okhttp的庫,最后生成一個(gè)請(qǐng)求的request蹦哼,里面設(shè)計(jì)感還是很強(qiáng)的哪轿,工廠模式,適配器模式還提供了rxjava的支持翔怎,和rxjava結(jié)合還是用的很爽的http://www.reibang.com/p/a8b98e66b1b8
Glide
和其他圖片加載框架差不多窃诉,glide都有三級(jí)緩存,但是glide比較強(qiáng)大的是能加載gif赤套,還有g(shù)lide的with方法傳入的context會(huì)進(jìn)行檢查飘痛,他會(huì)添加一個(gè)隱藏的fragment來監(jiān)聽生命周期,達(dá)到自動(dòng)回收?qǐng)D片的目的
Volley
volley的封裝比較簡(jiǎn)單是輕量級(jí)的容握,volley也支持okhttp宣脉,但是volley不支持post大文件數(shù)據(jù)
Dagger
dagger是一個(gè)注解處理器,幫助項(xiàng)目解耦少用new關(guān)鍵字剔氏,和spring的作用差不多塑猖,但是他是編譯期間通過apt插件預(yù)生成一些代碼,而spring是在運(yùn)行期間谈跛,它主要可以幫助你做一些初始化的操作羊苟,缺點(diǎn)就是編譯時(shí)間邊長(zhǎng)了,每次運(yùn)行要多很長(zhǎng)時(shí)間http://www.reibang.com/p/cc54c5ec9897
事件分發(fā)
數(shù)據(jù)庫增加字段
sqllite增加字段只能重新建表感憾,方法就是把表重命名蜡励,新建一張帶有該字段的表,然后復(fù)制數(shù)據(jù)
數(shù)據(jù)庫框架比較
數(shù)據(jù)庫框架分為關(guān)系型數(shù)據(jù)庫和對(duì)象型數(shù)據(jù)庫阻桅,關(guān)系型數(shù)據(jù)庫最好的庫是greendao凉倚,對(duì)象型數(shù)據(jù)庫比較好的也是用的最多的是realm,底層是c語言實(shí)現(xiàn)的嫂沉,性能相對(duì)較好就是包會(huì)比較大但是業(yè)務(wù)量不大的話用android的sqlite就行了稽寒,功能簡(jiǎn)單,也方便拓展
數(shù)據(jù)庫性能優(yōu)化
數(shù)據(jù)庫操作基本由三個(gè)過程趟章,創(chuàng)建事務(wù)杏糙,執(zhí)行sql,提交尤揣,這三個(gè)過程搔啊,但是我們批量操作,就變成創(chuàng)建事務(wù)北戏,執(zhí)行n個(gè)sql负芋,提交,這樣效率會(huì)提高很多,
在sql語句數(shù)量比較多的情況下,用stringbuilder代替string拼接旧蛾,這樣會(huì)提高空間分配效率
查詢時(shí)根據(jù)需要返回盡量少的字段莽龟,可以減少內(nèi)存的消耗
查詢結(jié)束后及時(shí)關(guān)閉cursor
如果條件允許的話可以在建表的時(shí)候記住columnIndex,它是一個(gè)int類型下標(biāo)值锨天,不用每次查詢都去調(diào)用getColumnIndex毯盈,這個(gè)在數(shù)據(jù)量龐大的查詢條件下會(huì)比較節(jié)省時(shí)間
調(diào)用數(shù)據(jù)庫的時(shí)候要用子線程防止卡ui,但是由于sqllite是不支持多線程并發(fā)訪問的病袄,兩個(gè)線程同時(shí)插入會(huì)拋出異常搂赋,雖然是有事務(wù)控制,可以保證數(shù)據(jù)庫的完整性益缠,但是不能保證線程執(zhí)行的準(zhǔn)確性脑奠,也就是說有的線程可能會(huì)調(diào)用失敗或者請(qǐng)求出現(xiàn)線程繁忙錯(cuò)誤,所以sqlite最好保證單線程執(zhí)行
一般情況下幅慌,sqlite是多進(jìn)程可以操作的宋欺,不會(huì)報(bào)錯(cuò),但是不能保證插入順序胰伍,原則上需要在一個(gè)進(jìn)程里去操作齿诞,正確的做法是,啟用一個(gè)骂租, 單獨(dú)的進(jìn)程通過contentprovider或者其他ipc向其他進(jìn)程提供接口祷杈,通過這個(gè)單獨(dú)的進(jìn)程統(tǒng)一操作
ipc
為什么需要多進(jìn)程:
Android對(duì)進(jìn)程的內(nèi)存分配是有限的,用多進(jìn)程讓核心服務(wù)和UI分離菩咨,可以為用戶提供更好的程序穩(wěn)定性吠式,提升用戶體驗(yàn) 開啟多進(jìn)程,用多進(jìn)程分擔(dān)內(nèi)存壓力抽米,用前臺(tái)service保證adj的值最小,最不容易回收
內(nèi)存分配 管理內(nèi)存分配的是LMK LowMemoryKiller糙置,通過adb命令proc/pid/com_score_adj可以看到一個(gè)應(yīng)用的adj值云茸,值越大,越容易被回收谤饭,通常切換到后臺(tái)會(huì)變大
-
多進(jìn)程會(huì)出現(xiàn)的問題:
共享內(nèi)存失效标捺,單例,靜態(tài)變量成員失效揉抵,同步鎖失效亡容,application多個(gè),sharepreferce可靠性下降
-
應(yīng)用場(chǎng)景:
音樂播放器冤今,定位服務(wù)
開啟多進(jìn)程的方式:在四大組件注冊(cè)文件中指定 android:process
-
多進(jìn)程的通信方式:
Bundle 常用于四大組件通訊
文件共享闺兢,多進(jìn)程操作同一個(gè)文件交換數(shù)據(jù) 但是不支持并發(fā)
Messenger 輕量級(jí)的AIDL ,需要基于Handler
Socket
AIDL 寫aidl接口文件,在服務(wù)里通過Binder拿到接口對(duì)象傳遞數(shù)據(jù)戏罢,注冊(cè)服務(wù)屋谭,客戶端綁定服務(wù)轉(zhuǎn)換aidl接口獲取數(shù)據(jù)
ContentProvider 例如我們的應(yīng)用訪問系統(tǒng)的通訊錄數(shù)據(jù)
recycleview
嵌套scrollview卡頓脚囊,重新scrollview攔截一下事件
嵌套顯示不全item,外面再包一層relativelayout 增加一個(gè)descendantfcusability屬性
布局優(yōu)化
避免層級(jí)太多
開發(fā)者模式查看是否過度繪制
使用include標(biāo)簽重用layout
viewstub標(biāo)簽 (調(diào)用的時(shí)候才加載布局)
不要在onDraw中頻繁創(chuàng)建對(duì)象和做耗時(shí)操作
socket
創(chuàng)建服務(wù)端socket連接對(duì)象桐磁,指定ip和端口號(hào)悔耘,子線程進(jìn)行
監(jiān)聽socket流,獲取服務(wù)端返回?cái)?shù)據(jù)
發(fā)送數(shù)據(jù)也是利用InputStream的write字節(jié)
websocket
是基于類似于http的應(yīng)用層協(xié)義我擂,使用jar包WebSocketClient連接服務(wù)器
Android動(dòng)畫
view動(dòng)畫 移動(dòng)衬以,平移,縮放,旋轉(zhuǎn)
drawable動(dòng)畫 幀動(dòng)畫欣孤,一幀一幀的
property動(dòng)畫 view動(dòng)畫升級(jí)版叙甸,可以渲染還沒加載的view
Handler機(jī)制
Handler創(chuàng)建Looper,Looper創(chuàng)建MessageQueue Looper消息隊(duì)列處理者用死循環(huán)不斷去 MessageQueue 消息隊(duì)列拿到message然后又調(diào)用handler去處理备籽, 類似于生產(chǎn)者消費(fèi)者http://www.reibang.com/p/87ee9b5206df
性能優(yōu)化
1 anr主線程不能處理耗時(shí)操作
2 內(nèi)存溢出,bitmap優(yōu)化
3 內(nèi)存抖動(dòng),頻繁創(chuàng)建臨時(shí)對(duì)象
4 內(nèi)存泄漏
-
使用LeakCanary檢測(cè):
運(yùn)行后會(huì)在另外一個(gè)Leaks的app中顯示分井,該庫會(huì)監(jiān)聽onDistory方法车猬,把a(bǔ)ctivity實(shí)例放在弱引用里實(shí)時(shí)訪問,找出內(nèi)存泄露的變量和類
-
android studio app profiler工具:
可以查看當(dāng)前運(yùn)行app的CPU尺锚,內(nèi)存珠闰,網(wǎng)絡(luò)的占用和消耗,可以看當(dāng)前頁面所在類的實(shí)例瘫辩,可以調(diào)試內(nèi)存泄漏和占用比例
webview引起的內(nèi)存泄露伏嗜,手動(dòng)創(chuàng)建,手動(dòng)銷毀伐厌,不要在xml使用
線程銷毀
context單例引用
handler
弱引用
SQLite使用完記得關(guān)閉鏈接
5 ui布局復(fù)雜
6 view重復(fù)繪制
7 懶加載setUserVisibleHint
http://www.reibang.com/p/3e44250ca2de
activity啟動(dòng)模式
standard
默認(rèn)啟動(dòng)模式承绸,start多少就開啟多少
singletop
棧頂唯一,允許有多個(gè)實(shí)例挣轨,但是不允許疊加军熏,通知欄跳轉(zhuǎn)
singleTask
棧唯一,但是start的時(shí)候如果此activity之上有新的activity會(huì)被銷毀卷扮,會(huì)調(diào)用此activity的onNewIntent方法荡澎,主界面
singleInstance
棧唯一,一般用于系統(tǒng)應(yīng)用晤锹,launcher
Android 678910 的差異
6.0 運(yùn)行時(shí)權(quán)限摩幔,休眠模式,app進(jìn)入休眠模式會(huì)斷開網(wǎng)絡(luò)鞭铆,殺掉一些空置進(jìn)程
7.0 分屏多任務(wù)或衡,VR,通知欄快捷回復(fù),優(yōu)化編輯器減少安裝速度薇宠,文件加密
8.0 畫中畫偷办,Notifcation Dots,自適應(yīng)桌面圖標(biāo)澄港,后臺(tái)進(jìn)程限制椒涯,運(yùn)行時(shí)權(quán)限優(yōu)化,安裝位置來源apk權(quán)限
9.0 WIFI RTT室內(nèi)精準(zhǔn)定位回梧,凹凸屏支持废岂,消息通知優(yōu)化,多攝像頭api狱意,ImageDecoder湖苞,神經(jīng)網(wǎng)絡(luò)api,NFC api
10.0 暗黑模式详囤,桌面模式(投影)财骨,5Gapi,折疊屏支持藏姐,手勢(shì)導(dǎo)航隆箩,后臺(tái)程序位置獲取權(quán)限,神經(jīng)網(wǎng)絡(luò)1.2羔杨,文件沙盒
http://www.reibang.com/p/88409d6f5795
activity fragment互傳值
LiveData [http://www.reibang.com/p/3e8e1fee00fc](http://www.reibang.com/p/3e8e1fee00fc)
livedata 主要是用于activity的數(shù)據(jù)共享捌臊,比如activity和fragment,fragment和fragment之間的通訊兜材,優(yōu)點(diǎn)就是它自己會(huì)處理生命周期理澎,不用擔(dān)心內(nèi)存泄漏,比如網(wǎng)絡(luò)請(qǐng)求自動(dòng)刷新ui這種
實(shí)現(xiàn)方式
需要配合viewmodel使用曙寡,viewmodel 定義mutableLiveData, 用viewModelProviders.of創(chuàng)建實(shí)例糠爬,在fragment里用.observe綁定,最后調(diào)用mutableModel的setvalue刷新數(shù)據(jù),就可以自動(dòng)刷新
外部獲取自定義view的寬高
不能直接獲取举庶,view沒有進(jìn)行onmeasure方法獲取到是0秩铆,有兩種方法
——自己調(diào)用view的onmeasure測(cè)量
——需要設(shè)置一個(gè)監(jiān)聽,View.ViewTreeObserver.addGlobalLayoutLinstener在這個(gè)回調(diào)里獲取寬高
hashcode
hashcode是用對(duì)象的字段算出來的一個(gè)數(shù)字灯变,用來比較兩個(gè)對(duì)象是否相等,但是他需要和 equals一起使用捅膘,當(dāng)hashcode相等的時(shí)候比較equals添祸,這樣比較更高效 當(dāng)hashcode相等時(shí)兩個(gè)對(duì)象不一定相等
StringBuffer和StringBuilder
stringbuffer是線程安全,stringbuilder不能多線程訪問寻仗,但是stringbuilder速度更快刃泌,另外string因?yàn)槊看味际切陆▽?duì)象,所以string也是線程安全
接口的意義
接口主要為了彌補(bǔ)類不能實(shí)現(xiàn)多繼承的缺點(diǎn),有了接口一個(gè)類可以實(shí)現(xiàn)多個(gè)接口的操作
內(nèi)部類耙替,靜態(tài)內(nèi)部類亚侠,局部?jī)?nèi)部類
內(nèi)部類可以隱藏一些外部類的變量和方法,不讓調(diào)用者知道
靜態(tài)內(nèi)部類不依賴外部對(duì)象俗扇,但是可以指向表達(dá)一種從屬關(guān)系
局部類只是在方法里面使用
設(shè)計(jì)模式
- 單例模式
- 工廠模式(工廠方法硝烂,抽象工廠)
- 策略模式
- 代理模式 (動(dòng)態(tài)代理靜態(tài)代理)
- 觀察者模式
- 責(zé)任鏈模式
模塊化組件化與插件化和熱修復(fù)
模塊化是把基礎(chǔ)業(yè)務(wù)分成一個(gè)模塊,其他業(yè)務(wù)引用基礎(chǔ)業(yè)務(wù)铜幽,這些模塊都在同一個(gè)工程
組件化是指一個(gè)app有多個(gè)module滞谢,每個(gè)module負(fù)責(zé)一部分業(yè)務(wù),每個(gè)業(yè)務(wù)組件可以單獨(dú)打包也可以做依賴庫除抛,最后打包成為一個(gè)apk狮杨,
插件化是指一個(gè)項(xiàng)目分為一個(gè)宿主和多個(gè)插件,每個(gè)插件是一個(gè)apk到忽,最后這個(gè)宿主app加載多個(gè)apk橄教,可以實(shí)現(xiàn)動(dòng)態(tài)加載
熱修復(fù)是指為一個(gè)業(yè)務(wù)或者一個(gè)class單獨(dú)進(jìn)行加載,已達(dá)到修復(fù)bug的目的
排序算法
- 冒泡排序
int a = [2,1,5,9,5]
int temp = 0;
for (int i = 0; i < a.length-1; i++) {
for (int j = 0喘漏;j < a.length-1-i; j++) {
if (a[j] > a[j+1]) {
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
}
}
原理护蝶,像擠跑跑一樣,一個(gè)一個(gè)擠出來陷遮,第二層for循環(huán)每一次選出一個(gè)最大值滓走,外面一層for循環(huán)控制第二層循環(huán)的排序范圍
-
選擇排序
總結(jié),就是把里面的循環(huán)每次找到一個(gè)最小值帽馋,外面的循環(huán)控制輪詢范圍
glide 和 Picasso的選擇
特性 | glide | Picasso |
---|---|---|
gif加載 | 支持gif加載 | 不支持 |
生命周期 | 支持 | 不支持 |
內(nèi)存 | 根據(jù)image尺寸 | full 尺寸 |
加載時(shí)間 | 慢-先改變尺寸 | 快-直接加載到內(nèi)存 |
圖片加載時(shí)搅方,傳入Context對(duì)象或者fragment對(duì)象,glide會(huì)生成一個(gè)無UI的fragment绽族,因?yàn)間lide無法從傳入的context中獲取生命周期 通過這個(gè)fragment可以拿到傳入context相同的生命周期姨涡,從而實(shí)現(xiàn)了對(duì)生命周期變化做出相同的暫停和銷毀操作
總結(jié):小項(xiàng)目用Picasso,功能簡(jiǎn)單吧慢,加載速度快涛漂,大項(xiàng)目用glide,功能配置豐富检诗,對(duì)內(nèi)存優(yōu)化比較好匈仗,對(duì)于內(nèi)存方面,glide會(huì)對(duì)不同尺寸的圖片緩存多份緩存逢慌,
而Picasso都是同一份緩存悠轩,根據(jù)尺寸要求在內(nèi)存中進(jìn)行resize,所以下載速度Picasso>glide攻泼,內(nèi)存加載速度glide> Picasso
activity啟動(dòng)過程
首先從點(diǎn)擊桌面圖標(biāo)開始火架,launcher進(jìn)程通過binder ipc向system service發(fā)起通信startActivity鉴象,system service進(jìn)程的AMS(activity manager service)會(huì)判斷app進(jìn)程是否已經(jīng)創(chuàng)建,若沒有創(chuàng)建則通過binder ipc向zygote通信fork app進(jìn)程何鸡, app進(jìn)程會(huì)通過ipc向ams 發(fā)起通信 請(qǐng)求attachapplication 和得到schedulelancheractivity請(qǐng)求然后和主線程通信纺弊,主線程開始調(diào)用activity oncreate app正式啟動(dòng)
協(xié)成
什么是協(xié)成
協(xié)成是輕量級(jí)線程,建立在線程之上骡男,和線程的區(qū)別就是它不會(huì)阻塞任務(wù)淆游,而是掛起任務(wù),當(dāng)一個(gè)任務(wù)出現(xiàn)阻塞的時(shí)候這個(gè)線程會(huì)被掛起洞翩,掛起之后這個(gè)線程還可以去執(zhí)行其他任務(wù)稽犁,而這個(gè)任務(wù)阻塞結(jié)束后又會(huì)被線程執(zhí)行,相當(dāng)于是把線程進(jìn)行分段骚亿,相當(dāng)于用最少的線程做更多的事情已亥,節(jié)約資源,協(xié)成的另外一個(gè)好處就是它的調(diào)用是同步的来屠,不需要回調(diào)函數(shù)虑椎,只需要return回結(jié)果,看上去更簡(jiǎn)潔易懂
如何開啟協(xié)成
- launch
val job = launch {
repeat(1000) { i ->
println("job: I'm sleeping $i ...")
delay(500L)
}
}
delay(5000L) // 延遲一段時(shí)間
println("main: I'm tired of waiting!")
job.cancel() // 取消該作業(yè)
job.join() // 等待作業(yè)執(zhí)行結(jié)束
println("main: Now I can quit.")
launch 返回的是job對(duì)象 只能控制協(xié)成狀態(tài)俱笛,不能返回?cái)?shù)據(jù)結(jié)構(gòu)捆姜,異步方法需要用suspend修飾
- async
val time = measureTimeMillis {
val one = async { doSomethingUsefulOne() }
val two = async { doSomethingUsefulTwo() }
println("The answer is ${one.await() + two.await()}")
}
println("Completed in $time ms")
async 返回的是defferred對(duì)象,可以控制協(xié)成狀態(tài)可以返回?cái)?shù)據(jù)結(jié)構(gòu)迎膜,defferred是Job的子類
以上兩種方式都可以用Dispather 指定協(xié)成在那個(gè)線程運(yùn)行