Activity的生命周期
正常的流程:
onCreate():被創(chuàng)建的時候被回調(diào),
onStart():Activity正在啟動狀態(tài),處于可見但無法交互,但處在后臺
onResume():已經(jīng)在前臺可見,可以和用戶交互,Activity已經(jīng)在運行
onPause():Activity正在停止,和onResume()成對出現(xiàn)
onStop():即將停止,或被新的Activity覆蓋,Activity不可見,在后臺運行
onDestory():Activity正在被銷毀,回收和資源的釋放,和onCreate()成對
onRestart():Activity正在重新啟動不會執(zhí)行此方法
異常的流程(1、系統(tǒng)發(fā)生改變 2、內(nèi)存不足造成的改變):
只有在Activity異常的情況下才會調(diào)用
onSaveInstanceState()是出現(xiàn)異常情況下,會自動調(diào)用,來保存當前Activity的信息,(當異常啟動的時候,這個方法中的bunlder可能為空,所以要進行非空判斷)
onRestoreInstanceState()當Activity重新創(chuàng)建后,自動調(diào)用,會通過onSaveInstanceState()的Bundle來保存狀態(tài)
一旦被異常啟動,Bundle()方法不會為空
總結(jié): 1、Activity正常啟動:onCreate--onStart--onResume
2、點擊Back回退:onPause--onStop--onDestroy
3、打開新的Activity:onPause--onStop
4、Activity異常:onSaveInstanceState來保存數(shù)據(jù)
5、Activity重新創(chuàng)建:調(diào)用onRestoreInstanceState
1.任務棧????
四種形態(tài):
Active:Activity處于棧頂
Paused:可見但不可交互? 只是失去了和用戶的交互,只有在系統(tǒng)內(nèi)存不足時才會被回收
Stopped:不可見? 被完全覆蓋時,只有在系統(tǒng)內(nèi)存不足時才會被回收
Killed:系統(tǒng)回收掉
(在內(nèi)存不足的時候,會回收棧底部的Activity)
總結(jié):1、Activity是與用戶交互的接口 2、Android系統(tǒng)是通過Activity棧的形式來管理Activity 3、四種形態(tài):Active/Paused/Stopped/Killed
2.四種啟動模式
Activity啟動模式(當多次啟動Activity的時候,系統(tǒng)會創(chuàng)建多個實例,按照先后進出的順序放入任務棧中,當按下Back鍵的時候,整個任務棧就會為空,系統(tǒng)就會回收)
1、standard(標準模式)(默認啟動模式)
一、在不指定啟動模式的前提下,系統(tǒng)默認使用該模式啟動每個Activity
二、每次啟動一個Activity都會重寫創(chuàng)建一個新的實例(消耗資源)
三、Activity在啟動的時候,onCreate(),onStart(),onResume()都會依次調(diào)用
2、singleTop(棧頂復用) ps:只有在棧頂才可以
一、當前棧中已有該Activity實例并且該實例位于棧頂時
二、當前棧中已有該Activity實例單實該實例不再棧頂時
三、當前棧中不存在該Activity的實例
SingleTop應用場景:
IM對話框
新聞客戶端推送
3、singleTask(棧內(nèi)復用模式),檢測的是整個棧中是否存在要啟動的Activity
(適合于應用中主界面模式)
一、首先根據(jù)taskAffinity去尋找當前是否存在一個對應名字(就是包名)的任務棧
(任務相關(guān)性)
二、如果不存在,就重新創(chuàng)建一個Task任務棧
然后創(chuàng)建新的Activity的實例假如棧中
三、如果存在,先得到該任務棧,查找該任務棧中是否存在該Activity實例
存在的話,就會將所有這個實例的Activity都出棧
SingleTask應用場景
應用的主界面
4、singleInstance(單一實例模式)
singleInstance模式下,所有的Activity中只有一個實例,所有Activity會獨享一個任務棧
如果有別的Activity使用的話,這兩個Activity會使用一個任務棧
應用場景:呼叫來電、
特性:
1、以SingleInstance模式啟動的Activity具有全局唯一性
2、如果在啟動這樣的Activity時,已經(jīng)存在了一個實例
3、以SingleInstance模式啟動的Activity具有獨占性
Activity和Activity之間的通信
1、Intent/Bundle
Intent:首先創(chuàng)建Bundle對象,通過Key,Value傳遞數(shù)據(jù)
例:
第一個Activity發(fā)送
Bundle bundle = new Bundle();
bundle.putString("Key","value");
bundle.putInt("Key2",1);
Intent intent = new Intent(GoActivity.this,ToActivity.class);
intent.putExtras(bundle);
startActivity(intent);
將Bundle對象和Intent建立聯(lián)系
第二個Activity接收
Intent intent = getIntent();
String key = intent.getStringExtra("Key");
int value = intent.getIntExtra("Key2",1);
第二個Activity中獲取第一個Activity傳過來的值
2、類靜態(tài)變量
3、全局變量
Activity和Service之間的通信
1、綁定服務,利用ServiceConnection類
在Activity中實現(xiàn)接口(ServiceConnection)
重寫onServiceConnected(綁定成功執(zhí)行) onServiceDisconnected(進程崩潰執(zhí)行)這兩個方法,這兩個方法是在綁定成功和進程崩潰的時候調(diào)用
首先在onServiceConnected()中創(chuàng)建Binder對象,利用binder的setData()方法,向Service中傳遞數(shù)據(jù)
2、簡單通信,利用Intent進行傳值
用Intent進行傳值,從Activity中傳值(putExtras.("key","value"))
在Service中直接用(getIntent)獲取
3、定義一個CallBack接口來監(jiān)聽服務中的進程的變化
在Service中定義一個接口
在Activity中,在onServiceConnected()方法中,用binder對象來實現(xiàn)Callback中重寫的方法
如果是在子線程中,需要通過Handler來發(fā)送到主線程中,
Activity和Fragment之間的通信
Activity將數(shù)據(jù)傳遞給Fragment
Bundle:
當用Bundle來傳遞數(shù)據(jù)時,用fragment.setArguments(bundle對象名);
在Fragment的時候,用(isAdded()方法)判斷是否已經(jīng)依附在Activity上。
直接在Activity中定義方法:
在第一個Activity中定義構(gòu)造方法
然后在需要接收數(shù)據(jù)的Fragment中用onAttach()方法中強轉(zhuǎn)為Activity的類型
Fragment將數(shù)據(jù)傳遞給Activity
1、接口回調(diào):
一、在fragment中定義一個內(nèi)部回調(diào)接口//Acticity實現(xiàn)這個接口就行
二、fragment的方法onAttch()//檢查fragment中是否實現(xiàn)了內(nèi)部接口
三、調(diào)用onDetach方法,銷毀,把Activity傳過來的資源釋放
Fragment與Service數(shù)據(jù)通信
Activity調(diào)用bindService (Intent service, ServiceConnection conn, int flags)方法,得到Service對象的一個引用,這樣Activity可以直接調(diào)用到Service中的方法,如果要主動通知Activity,我們可以利用回調(diào)方法
?Service向Activity發(fā)送消息,可以使用廣播,當然Activity要注冊相應的接收器。比如Service要向多個Activity發(fā)送同樣的消息的話,用這種方法就更好
Fragment復用
?為什么要復用Fragment?
Activity 在重建的時候會恢復其包含的 FragmentManager ,F(xiàn)ragmentManager 又會恢復其管理的 Fragment ,同理 Fragment 也會恢復其包含的 FragmentManager,層層遞進,直到全部恢復
復用的好處:
避免顯示錯亂
避免重復添加
避免多余的內(nèi)存占用
優(yōu)化界面啟動速度
兩種適配器的區(qū)別?
(1).FragmentPagerAdapter
適合于?Fragment數(shù)量不多的情況。當某個頁面不可見時,該頁面對應的View可能會被銷毀,
但是所有的Fragment都會一直存在于內(nèi)存中。
如果Fragment需要保存的狀態(tài)較多時,會導致占用內(nèi)存較大,
(2).FragmentStatePagerAdapter
適合于Fragment數(shù)量較多的情況。當頁面不可見時,?對應的Fragment實例可能會被銷毀,
但是Fragment的狀態(tài)會被保存。
因此每個Fragment占用的內(nèi)存會更少,但是頁面切換會引起較大開銷。
1、service和線程(Thread)的區(qū)別和場景
Thread:程序執(zhí)行的最小單元,它是分配CPU的基本單位
Thread:生命周期
1.新建new
2.就緒runnable
3.運行running
4.死亡death
5.阻塞block
缺點:無法控制,當Activity被關(guān)閉之后,無法控制線程
場景:Thread需要連續(xù)不斷地每隔一段時間就要連接服務器一次做某種操作
2、如何管理service生命周期
不管如何啟動service,oncreate()和ondestory()都會運行
Service運行在后臺
Service時Android的一種機制,服務是運行在主線程上的
Service生命周期:
onCreate()通過onCreate開始
onStart()
onDestroy()到onDestory結(jié)束
onBind()
onUnbind()
四種情況:
1:StartService:
2:stopService:
3:bindService:
4:unBindService:
3、Service和IntentService的區(qū)別
Service:不建議在service中執(zhí)行耗時操作,否則會報ANR
IntentService:內(nèi)部有一個工作線程HandlerThread來處理耗時操作
工作機制:繼承與Service,
和Service不同點:在onCreate()方法中會創(chuàng)建并啟動HandlerThread,還創(chuàng)建了ServiceHandler異步處理類,執(zhí)行異步任務
當持有IntentService會實現(xiàn)onHandlerIntent方法,
如果后臺只有一個任務,執(zhí)行完onHandlerIntent會進行銷毀
如果后臺有很多任務,onHandlerIntent會依次執(zhí)行,直到執(zhí)行完畢之后,才會銷毀(調(diào)用StopSelf()結(jié)束操作)
總結(jié):
1、IntentService是繼承并處理異步請求的一個類
2、內(nèi)有一個工作線程(也就是HandlerThread)來處理耗時操作
3、IntentService內(nèi)部則是通過消息的方式發(fā)送給HandlerThread的,然后由Handler中的Looper來處理消息
4、啟動服務和綁定服務先后次序問題
Android中只會又一個服務
啟動服務:service會無限期的運行
先綁定service后啟動
綁定服務會轉(zhuǎn)為啟動服務狀態(tài),不會影響服務運行,之到onStop為止
先啟動service后綁定
不會轉(zhuǎn)為綁定的狀態(tài),當Activity解除綁定服務的時候,還會按照啟動的生命周期在后臺運行,之到onStop為止
總結(jié): 1、啟動服務的優(yōu)先級比綁定服務高
2、服務在其托管進程的主線程中執(zhí)行,主線程
ALDL:
AIDL:是一種android內(nèi)部進程通信接口描述語言,用過它我們可以定義進程間的通信接口但是記住僅僅只是 android ,換個平臺就不是AIDL 了。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? AIDL進程間通訊的原理:
? 1.通過編寫aidl文件夾來定義進程間通信接口
? 2.編譯后會自動生成相應的java文件? 在各未見中我們可以看到是繼承啦一個Binder對象,實現(xiàn)剛剛定義的接口
? 3.服務器我們通過一個服務實現(xiàn)里面的Binder方法,將接口的具體實現(xiàn)寫在stub中,用ibinder對象傳遞給客戶端
? 4.客戶端bindservice的時候,服務是實現(xiàn)serviceConnection重寫里面的方法,用asinterface的形式將ibinder還原成接口,在調(diào)用其接口中的方法來實現(xiàn)通信
Binder機制:
???????? Android使用Linux內(nèi)核擁有這非常多的跨進程通信機制,比如Socket,管道。為什么還要binder呢?
性能:Binder相比較于傳統(tǒng)的socket/管道通信而言,更加高效,它在IPC時,只需要數(shù)據(jù)拷貝1次,而傳統(tǒng)的socket之類的需要2次;
出于安全上的考慮:傳統(tǒng)的進程間通信對于通信雙方的身份沒有進行嚴格的驗證,只有上層協(xié)議才會進行架構(gòu),比如說,socket通信時,IP地址是手動填寫的,可以進行人為的偽造,而Binder支持通信雙方進行身份校驗,極大的保障了安全性;
Binder的通信模型:
我們其實可以進程通信的雙方一方稱為服務端進程,另一方稱為客戶端進程,我們知道,由于進程隔離的存在,在不進行進程間通信的方式的情況下,客戶端進程是無法訪問服務端進程的;
對于A和B相當于兩個進程,他們要打電話就相當于要進行通信,其中電話基站就想到與Binder驅(qū)動,而通信錄則相當于其中的一個ServerManager
ServerManager其實就是一個進程,它里面維護了一張表,表里面存儲的是向他注冊過的進程信息,在通信之初,首先需要有一個進程向驅(qū)動申請成為ServerManager,當內(nèi)核驅(qū)動同意之后,這個成為ServerManager的進程就負責管理所有需要通信的進程信息,當客戶端進程要訪問服務端進程時,服務端進程首先會向ServerManager注冊,讓ServerManager保存自己的有關(guān)信息,當ServerManger保存完畢后,客戶端進程就會通過Binder驅(qū)動向ServerManger查詢服務端進程的信息,ServerManage就會將服務端進程的信息返回給客戶端進程,客戶端與服務端進程之間就可以通過這些信息,利用Binder驅(qū)動來進行通信了;
總結(jié)來說,Binder通信機制分三步:
第一步:ServerManager在其內(nèi)部維護一張表;
第二步:服務端進程向ServerManager注冊信息;
第三步:客戶端進程向ServerManager取得信息,通過Binder驅(qū)動與服務端進程通信;
手寫網(wǎng)絡框架:理解http網(wǎng)絡請求的過程,會存在的問題記錄下來,對比okhttp, 為啥要手寫?
問題?
擴展性:不能只處理Json/Xml,image,file,video
易用性:解決問題只需要調(diào)用一兩個API
穩(wěn)定性,封裝性,模塊化
和其他框架能不能集成(數(shù)據(jù)庫,網(wǎng)絡,MVC,MVVM,資源加載)
對比?
okhttp:
1.占用儲存空間
okhttp占用內(nèi)存空間過大。
2.功能介紹
Square 公司開源的 OkHttp 是一個專注于連接效率的 HTTP 客戶端。OkHttp 提供了對 HTTP/2 和 SPDY 的支持,并提供了連接池,GZIP 壓縮和 HTTP 響應緩存功能。
3.優(yōu)點
支持http請求,https請求。
支持文件下載。
使用的是HttpURLConnection,不要擔心android版本的變換。(至少目前是都支持的)。
支持get,post請求。
基于Http的文件上傳。
加載圖片。
4.缺點
比如callback回來是在線程里面, 不能刷新UI,需要我們手動處理。
封裝比較麻煩。
Volley
1.占用儲存空間
占用內(nèi)存空間小。
2.功能介紹
Volley是Goole在2013年Google I/O大會上推出了一個新的網(wǎng)絡通信框架,它是開源的。
Volley 的特點:特別適合數(shù)據(jù)量小,通信頻繁的網(wǎng)絡操作。
3.優(yōu)點
非常適合進行數(shù)據(jù)量不大,但通信頻繁的網(wǎng)絡操作。
內(nèi)部分裝了異步線程。
支持get,post網(wǎng)絡請求。
圖片下載。
可直接在主線程調(diào)用服務端并處理返回結(jié)果。
可以取消請求,容易擴展,面向接口編程。
4.缺點
對大文件下載 Volley的表現(xiàn)非常糟糕。
只支持http請求。
為啥手寫?
因為在項目中,可以使代碼簡介明了,做到代碼職責劃分明顯,實現(xiàn)某一塊功能不會有多余的代碼,而使用別人的開源框架會使我們的代碼混亂,代碼過多,不簡潔,從而導致App的內(nèi)存占用太大,而且某些開源框架,不能滿足我們功能上的需求,而且自己寫的更方便自己理解和修改。