Activity生命周期(7個(gè)方法)
Fragment (生命周期11個(gè)方法)
Fragment 執(zhí)行hide陈醒、show生命周期執(zhí)行:
? ? ? ? 當(dāng)使用hide宾娜、show方法來控制Fragment使用時(shí),F(xiàn)ragment生命周期將不執(zhí)行仙粱,在onResume以及onPause方法處理的事情將由onHiddenChange進(jìn)行管理蚪黑,當(dāng)Fragment調(diào)用hide隱藏時(shí),
? ?該方法會(huì)被調(diào)用徐绑,傳入?yún)?shù)為true邪驮,表示該Fragment被隱藏了,當(dāng)Fragment調(diào)用了show方法后傲茄,該方法傳入的參數(shù)為false毅访,表示該Fragment正在顯示。
? ? ? ? onHiddenChange 回調(diào)時(shí)機(jī):
? ? ? ? ?當(dāng)使用add()+show()盘榨、hide()跳轉(zhuǎn)到新的Fragment時(shí)喻粹,舊的Fragment回調(diào) onHiddenChanged(),不會(huì)回調(diào)onStop()等生命周期方法草巡,而新的Fragment在創(chuàng)建時(shí)是不會(huì)回調(diào)onHiddenChanged()守呜。
https://www.cnblogs.com/zty-Love/p/8656151.html
Activity啟動(dòng)模式(4種)
Service (2)和BroadCast
Service 兩種啟動(dòng)模式
Android APP 啟動(dòng)流程
Activity啟動(dòng)流程
Q:Activity的啟動(dòng)過程?
技術(shù)點(diǎn):Activity啟動(dòng)山憨、ActivityManagerServie查乒、ApplicationThread
思路:可大致介紹Activity啟動(dòng)過程涉及到的類,尤其是ActivityManagerServie郁竟、ApplicationThread從中發(fā)揮的作用玛迄。
調(diào)用startActivity()后經(jīng)過重重方法會(huì)轉(zhuǎn)移到ActivityManagerService的startActivity(),并通過一個(gè)IPC回到ActivityThread的內(nèi)部類ApplicationThread中棚亩,并調(diào)用其scheduleLaunchActivity()將啟動(dòng)Activity的消息發(fā)送并交由Handler H處理憔晒。Handler H對(duì)消息的處理會(huì)調(diào)用handleLaunchActivity()->performLaunchActivity()得以完成Activity對(duì)象的創(chuàng)建和啟動(dòng)。
Android事件分發(fā)機(jī)制 詳解攻略蔑舞,您值得擁有
首先你需要知道一點(diǎn)拒担,只要你觸摸到了任何一個(gè)控件,就一定會(huì)調(diào)用該控件的dispatchTouchEvent方法攻询。那當(dāng)我們?nèi)c(diǎn)擊按鈕的時(shí)候从撼,就會(huì)去調(diào)用Button類里的dispatchTouchEvent方法,可是你會(huì)發(fā)現(xiàn)Button類里并沒有這個(gè)方法,那么就到它的父類TextView里去找一找低零,你會(huì)發(fā)現(xiàn)TextView里也沒有這個(gè)方法婆翔,那沒辦法了,只好繼續(xù)在TextView的父類View里找一找掏婶,這個(gè)時(shí)候你終于在View里找到了這個(gè)方法啃奴。
[https://blog.csdn.net/carson_ho/article/details/54136311](https://blog.csdn.net/carson_ho/article/details/54136311)
事件傳遞機(jī)制 (同時(shí)執(zhí)行幾個(gè)方法 on touch
on touch event
? ? up (on click )
on long click
ACTION_DOWN:主要包括了setPressed和checkForLongClick兩個(gè)操作:
setPressed用于設(shè)置按下狀態(tài),此時(shí)PFLAG_PRESSED標(biāo)志位被設(shè)置雄妥。
checkForLongClick用于檢查L(zhǎng)ongClick是否可以觸發(fā)最蕾,以及發(fā)送延遲消息來響應(yīng)長(zhǎng)按事件。
)
view繪制流程
Handler Loop 機(jī)制
IPC
Bindle 機(jī)制
多線程
jvm
? ? jmm
okhttp
retrofit
glide
rxjava
volley 請(qǐng)問volley為什么不適合傳輸大數(shù)據(jù)
volley中為了提高請(qǐng)求處理的速度老厌,采用了ByteArrayPool進(jìn)行內(nèi)存中的數(shù)據(jù)存儲(chǔ)的瘟则,如果下載大量的數(shù)據(jù),這個(gè)存儲(chǔ)空間就會(huì)溢出枝秤,所以不適合大量的數(shù)據(jù)醋拧,但是由于他的這個(gè)存儲(chǔ)空間是內(nèi)存中分配的,當(dāng)存儲(chǔ)的時(shí)候優(yōu)是從ByteArrayPool中取出一塊已經(jīng)分配的內(nèi)存區(qū)域, 不必每次存數(shù)據(jù)都要進(jìn)行內(nèi)存分配淀弹,而是先查找緩沖池中有無適合的內(nèi)存區(qū)域丹壕,如果有,直接拿來用薇溃,從而減少內(nèi)存分配的次數(shù) 菌赖,所以他比較適合大量的數(shù)據(jù)量少的網(wǎng)絡(luò)數(shù)據(jù)交互情況。
HttpClient和HttpURLConnection區(qū)別
1痊焊、HttpURLConnection是java的標(biāo)準(zhǔn)類,沒有做封裝忿峻,用起來比較原始
2薄啥、HttpClient是開源框架,封裝了訪問HTTP的請(qǐng)求頭逛尚、參數(shù)垄惧、內(nèi)容體、響應(yīng)等绰寞;HttpURLConnection中的輸入輸出流操作到逊,在這個(gè)接口中被統(tǒng)一封裝成了HttpPost(HttpGet)和HttpResponse。這樣滤钱,減少了操作的繁瑣性觉壶。
性能方面:
HttpURLConnection的訪問速度比HttpClient要快。
哪一種方式是最好的件缸?
HttpClient 在 Android 2.2 之前擁有比較少的 bug铜靶,因此選擇它是最好的選擇。
在 Android 2.3 及以后他炊,HttpURLConnection 是最好的選擇争剿。它那簡(jiǎn)單的 API 以及小尺寸使其非常適合 Android已艰。透明的壓縮和響應(yīng)緩存減少了網(wǎng)絡(luò)的使用,提高速度以及節(jié)省電量蚕苇。新的應(yīng)用程序中應(yīng)使用 HttpURLConnection哩掺。我們未來也會(huì)將更多的精力花在優(yōu)化 HttpURLConnection 上面。
sqlite插入數(shù)據(jù)的時(shí)候默認(rèn)一條語句就是一個(gè)事務(wù)涩笤,有多少條數(shù)據(jù)就有多少次磁盤操作嚼吞。初始5000條記錄也就是要5000次讀寫磁盤操作, 將會(huì)重復(fù)的打開關(guān)閉數(shù)據(jù)庫(kù)文件5000次,所以速度當(dāng)然會(huì)很慢辆它。而且不能保證所有數(shù)據(jù)都能同時(shí)插入誊薄。
解決方法:
添加事務(wù)處理,把5000條插入作為一個(gè)事務(wù)
我們使用SQLite的事務(wù)進(jìn)行控制:
db.beginTransaction();? //手動(dòng)設(shè)置開始事務(wù)
try{
//批量處理操作
for(Collection c:colls){
insert(db, c);
}
db.setTransactionSuccessful(); //設(shè)置事務(wù)處理成功锰茉,不設(shè)置會(huì)自動(dòng)回滾不提交呢蔫。
//在setTransactionSuccessful和endTransaction之間不進(jìn)行任何數(shù)據(jù)庫(kù)操作
}catch(Exception e){
MyLog.printStackTraceString(e);
}finally{
db.endTransaction(); //處理完成
}
Android廣播機(jī)制
廣播(Broadcast)機(jī)制用于進(jìn)程/線程間通信,廣播分為廣播發(fā)送和廣播接收兩個(gè)過程飒筑,其中廣播接收者BroadcastReceiver便是Android四大組件之一片吊。
BroadcastReceiver分為兩類:
靜態(tài)廣播接收者:通過AndroidManifest.xml的標(biāo)簽來申明的BroadcastReceiver。
動(dòng)態(tài)廣播接收者:通過AMS.registerReceiver()方式注冊(cè)的BroadcastReceiver协屡,動(dòng)態(tài)注冊(cè)更為靈活俏脊,可在不需要時(shí)通過unregisterReceiver()取消注冊(cè)。
從廣播發(fā)送方式可分為三類:
普通廣播:通過Context.sendBroadcast()發(fā)送肤晓,可并行處理
有序廣播:通過Context.sendOrderedBroadcast()發(fā)送爷贫,串行處理
Sticky廣播:通過Context.sendStickyBroadcast()發(fā)送,發(fā)出的廣播會(huì)一直滯留(等待)补憾,以便有人注冊(cè)這則廣播消息后能盡快的收到這條廣播漫萄。
Android 中的 Broadcast 實(shí)際底層使用Binder機(jī)制。
Q:獲取Bitmap對(duì)象并計(jì)算它所占用的內(nèi)存大小:
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.size);
int size = bitmap.getByteCount();
getByteCount()源碼:
public final int getByteCount() {
? ? return getRowBytes() * getHeight();
}
getHeight():圖片的高度(單位為px), getRowBytes方法返回的是圖片的像素寬度與色彩深度的乘積盈匾。
所以getByteCount()是這樣計(jì)算的:像素寬 * 像素高 * 色彩深度腾务,其中色彩深度與Bitmap的色彩格式有關(guān),默認(rèn)為ARGB_8888.
### 這里補(bǔ)充一個(gè)小知識(shí)點(diǎn)吧削饵!
ARGB_4444: 2bytes 每個(gè)像素占據(jù)2 個(gè)字節(jié):A(Alpha)占4位的精度岩瘦,R(Red)占4位的精度,G(Green)占4位的精度窿撬,B(Blue)占4位的精度启昧,加起來一共是16位的精度,折合是2個(gè)字節(jié)劈伴,也就是一個(gè)像素占兩個(gè)字節(jié)的內(nèi)存箫津,同時(shí)存儲(chǔ)位圖的透明度和顏色信息。
ARGB_8888 : 4bytes 每個(gè)像素占據(jù)4 個(gè)字節(jié):這個(gè)類型的跟ARGB_4444的原理是一樣的,只是A,R,G,B各占8個(gè)位的精度苏遥,所以一個(gè)像素占4個(gè)字節(jié)的內(nèi)存饼拍。由于該類型的位圖質(zhì)量較好,官方特別推薦使用田炭。但是师抄,如果一個(gè)480*800的位圖設(shè)置了此類型,那個(gè)它占用的內(nèi)存空間是:480*800*4/(1024*1024)=1.5M
RGB_565 : 2bytes 每個(gè)像素占據(jù)2 個(gè)字節(jié):R占5位精度教硫,G占6位精度叨吮,B占5位精度,一共是16位精度瞬矩,折合兩個(gè)字節(jié)茶鉴。這里注意的時(shí),這個(gè)類型存儲(chǔ)的只是顏色信息景用,沒有透明度信息
Q:為什么不能在子線程中更新UI ?
一般我們?cè)陧?xiàng)目中涵叮,進(jìn)行聯(lián)網(wǎng)請(qǐng)求后,這里我們就用子線程來表示聯(lián)網(wǎng)請(qǐng)求伞插,開了線程后獲取到我們服務(wù)器返回的數(shù)據(jù)后割粮,需要去更新UI,在這里我們就需要去調(diào)用setText()媚污、setImageView()舀瓢、setVisibility()等等等等,不管你調(diào)用的什么方法耗美,它都會(huì)去調(diào)用 ViewRootImpl 中的 checkThread()京髓,所以關(guān)鍵在于checkThread()這個(gè)方法
checkThread()方法分析:
1>:checkThread()方法作用是用來檢測(cè)線程,源碼如下:
void checkThread() {? ? ? ? if (mThread != Thread.currentThread()) {? ? ? ? ? ? throw new CalledFromWrongThreadException(? ? ? ? ? ? ? ? ? ? "Only the original thread that created a view hierarchy can touch its views.");? ? ? ? }? ? }
2>:if (mThread != Thread.currentThread()) 中的 Thread.currentThread()是子線程商架,而mThread是在構(gòu)造方法中初始化的 是主線程 [ MainThread ]
如果兩個(gè)不相等堰怨,那么那么左邊就是主線程、右邊就是子線程甸私;
如果兩個(gè)相等诚些,那么就是主線程
由上邊源碼可知:
如果兩個(gè)相等飞傀,就說明兩個(gè)都是在主線程中皇型,那么就不會(huì)調(diào)用下邊的異常;
如果兩個(gè)不相等砸烦,就說明是在子線程中更新UI弃鸦,那么就會(huì)調(diào)用checkThread()方法,就會(huì)拋出下邊的異常Only the original thread that created a view hierarchy can touch its views.
這個(gè)只解釋了如果在子線程更新UI為什么會(huì)拋異常幢痘;真正不能再自在子線程更新UI的原因是:UI控件非線程安全唬格,在多線程中并發(fā)訪問可能會(huì)導(dǎo)致UI控件處于不可預(yù)期的狀態(tài)。而不對(duì)UI控件的訪問加上鎖機(jī)制的原因有:
上鎖會(huì)讓UI控件變得復(fù)雜和低效
上鎖后會(huì)阻塞某些進(jìn)程的執(zhí)行
Android 高清加載長(zhǎng)圖或大圖方案
首先不壓縮,按照原圖尺寸加載购岗,那么屏幕肯定是不夠大的汰聋,并且考慮到內(nèi)存的情況,不可能一次性整圖加載到內(nèi)存中喊积,所以肯定是局部加載烹困,那么就需要用到一個(gè)類:
BitmapRegionDecoder
https://blog.csdn.net/lin20044140410/article/details/79485920