ContentProvider:學(xué)習(xí)筆記| AS入門(八) 組件篇之ContentProvider - 簡書
ContentProvider有存儲數(shù)據(jù)的功能冰沙,ContentProvider有兩種形式:可以使用現(xiàn)有的內(nèi)容提供者來讀取和操作相應(yīng)程序中的數(shù)據(jù)眯勾,也可以創(chuàng)建自己的內(nèi)容提供者給這個(gè)程序的數(shù)據(jù)提供外部訪問接口铐姚。
從系統(tǒng)提供的Provider訪問數(shù)據(jù)
既然ContentProvider有對外共享數(shù)據(jù)的功能旦袋,換句話說喷市,其他應(yīng)用程序可以通過ContentProvider對應(yīng)用中的數(shù)據(jù)進(jìn)行增刪改查(例如訪問通訊錄),訪問ContentProvider中共享的數(shù)據(jù)的方法是:
第一步:通過Context 中的getContentResolver()方法實(shí)例化一個(gè)ContentResolve對象塑猖。
第二步:調(diào)用該對象的增刪改查方法去操作ContentProvider中的數(shù)據(jù)。
具體內(nèi)容查看上述鏈接谈跛。
Android跨進(jìn)程通信:
1.Bundle/Intent傳遞數(shù)據(jù)
2.文件共享
3.Messenger
4.AIDL
5.ContentProvider
Bundle 機(jī)制:Bundle實(shí)現(xiàn)了Parcelable接口萌庆,所以他可以方便的在不同進(jìn)程間傳輸。
場景:
Activity狀態(tài)數(shù)據(jù)的保存與恢復(fù)涉及到的兩個(gè)回調(diào):void onSaveInstanceState (Bundle outState)币旧、void onCreate (Bundle savedInstanceState)
Fragment的setArguments方法:void setArguments (Bundle args)
消息機(jī)制中的Message的setData方法:void setData (Bundle data)
Bundle其實(shí)就是一個(gè)容器,內(nèi)部使用了Arraymap去存儲數(shù)據(jù)猿妈,那么就必然會(huì)提供get吹菱,put方法
AIDL :Android 進(jìn)階7:進(jìn)程通信之 AIDL 的使用 - 張拭心的博客 shixinzhang - CSDN博客
AIDL(Android 接口定義語言) 是 Android 提供的一種進(jìn)程間通信 (IPC) 機(jī)制。
我們可以利用它定義客戶端與服務(wù)使用進(jìn)程間通信 (IPC) 進(jìn)行相互通信時(shí)都認(rèn)可的編程接口彭则。
在 Android 上鳍刷,一個(gè)進(jìn)程通常無法訪問另一個(gè)進(jìn)程的內(nèi)存, Android 會(huì)使用 AIDL 來處理俯抖。
通過這種機(jī)制输瓜,我們只需要寫好 aidl 接口文件,編譯時(shí)系統(tǒng)會(huì)幫我們生成 Binder 接口。
AIDL 支持的數(shù)據(jù)類型共 4 種:
1.Java 的基本數(shù)據(jù)類型
2.List 和 Map?
????元素必須是 AIDL 支持的數(shù)據(jù)類型
????Server 端具體的類里則必須是 ArrayList 或者 HashMap
3.其他 AIDL 生成的接口
4.實(shí)現(xiàn) Parcelable 的實(shí)體
AIDL 的編寫主要為以下三部分:
1.創(chuàng)建 AIDL
????創(chuàng)建要操作的實(shí)體類尤揣,實(shí)現(xiàn)Parcelable接口搔啊,以便序列化/反序列化
????新建 aidl 文件夾,在其中創(chuàng)建接口 aidl 文件以及實(shí)體類的映射 aidl 文件
????Make project 北戏,生成 Binder 的 Java 文件
2.服務(wù)端
????創(chuàng)建 Service负芋,在其中創(chuàng)建上面生成的 Binder 對象實(shí)例,實(shí)現(xiàn)接口定義的方法
????在onBind()中返回
3.客戶端
????實(shí)現(xiàn)ServiceConnection接口嗜愈,在其中拿到 AIDL 類
????bindService()
我們從Android對aidl文件自動(dòng)生成的java類中可以看到asInterface()這個(gè)接口的實(shí)現(xiàn)旧蛾,大概的意思就是:?
如果客戶端和服務(wù)端在同一個(gè)進(jìn)程下,那么asInterface()將返回Stub對象本身蠕嫁,否則返回Stub.Proxy對象锨天。
Binder機(jī)制:Android系統(tǒng)中,涉及到多進(jìn)程間的通信底層都是依賴于Binder IPC機(jī)制剃毒。
性能方面
在移動(dòng)設(shè)備上(性能受限制的設(shè)備病袄,比如要省電),廣泛地使用跨進(jìn)程通信對通信機(jī)制的性能有嚴(yán)格的要求迟赃,Binder相對出傳統(tǒng)的Socket方式陪拘,更加高效。Binder數(shù)據(jù)拷貝只需要一次纤壁,而管道左刽、消息隊(duì)列、Socket都需要2次酌媒,共享內(nèi)存方式一次內(nèi)存拷貝都不需要欠痴,但實(shí)現(xiàn)方式又比較復(fù)雜。
Binder原理
Binder通信采用C/S架構(gòu)秒咨,從組件視角來說喇辽,包含Client、Server雨席、ServiceManager以及binder驅(qū)動(dòng)菩咨,其中ServiceManager用于管理系統(tǒng)中的各種服務(wù)。
Binder運(yùn)行機(jī)制:
注冊服務(wù)(addService):Server進(jìn)程要先注冊Service到ServiceManager陡厘。該過程:Server是客戶端抽米,ServiceManager是服務(wù)端。
獲取服務(wù)(getService):Client進(jìn)程使用某個(gè)Service前糙置,須先向ServiceManager中獲取相應(yīng)的Service云茸。該過程:Client是客戶端,ServiceManager是服務(wù)端谤饭。
使用服務(wù):Client根據(jù)得到的Service信息建立與Service所在的Server進(jìn)程通信的通路标捺,然后就可以直接與Service交互懊纳。該過程:client是客戶端,server是服務(wù)端亡容。
序列化:Serializable接口和Parcelable接口
含義:序列化表示將一個(gè)對象轉(zhuǎn)換成可存儲或可傳輸的狀態(tài)嗤疯。序列化后的對象可以在網(wǎng)絡(luò)上進(jìn)行傳輸,也可以存儲到本地萍倡。
場景:需要通過Intent和Binder等傳輸類對象就必須完成對象的序列化過程身弊。
Serializable:java提供的接口,將java對象轉(zhuǎn)為字節(jié)序列列敲,需要繼承接口阱佛,為基于磁盤或者網(wǎng)絡(luò)的對象序列化,調(diào)用WriteObject(obj)方法實(shí)現(xiàn)戴而。
Parcelable:android提供的接口凑术,基于內(nèi)存的對象序列化,將對象拆分為可傳遞的數(shù)據(jù)類型所意,基于內(nèi)存的速度要快于基于磁盤的接口淮逊。
serialVersionUID
含義:是Serializable接口中用來輔助序列化和反序列化過程。
注意:原則上序列化后的數(shù)據(jù)中的serialVersionUID要和當(dāng)前類的serialVersionUID?相同才能正常的序列化
簡單描述Handler:
andriod提供了Handler 和 Looper 來滿足線程間的通信扶踊。Handler先進(jìn)先出原則泄鹏。Looper類用來管理特定線程內(nèi)對象之間的消息交換
Message(消息):需要被傳遞的消息,其中包含了消息ID秧耗,消息處理對象以及處理的數(shù)據(jù)等备籽,由MessageQueue統(tǒng)一列隊(duì),最終由Handler處理分井。
MessageQueue(消息隊(duì)列):用來存放Handler發(fā)送過來的消息车猬,內(nèi)部通過單鏈表的數(shù)據(jù)結(jié)構(gòu)來維護(hù)消息列表,等待Looper的抽取尺锚。
Handler(處理者):負(fù)責(zé)Message的發(fā)送及處理珠闰。
Handler.sendMessage():向消息池發(fā)送各種消息事件。
Handler.handleMessage() :處理相應(yīng)的消息事件瘫辩。
Looper(消息泵):通過Looper.loop()不斷地從MessageQueue中抽取Message伏嗜,按分發(fā)機(jī)制將消息分發(fā)給目標(biāo)處理者。
存在關(guān)系:
一個(gè)Thread只能有一個(gè)Looper伐厌,可以有多個(gè)Handler阅仔;
Looper有一個(gè)MessageQueue,可以處理來自多個(gè)Handler的Message弧械;
MessageQueue有一組待處理的Message,這些Message可來自不同的Handler空民;
Message中記錄了負(fù)責(zé)發(fā)送和處理消息的Handler刃唐;
Handler中有Looper和MessageQueue羞迷;
UI的線程looper不會(huì)卡死(ANR)的原因:
ActivityThread的main方法主要就是做消息循環(huán),一旦退出消息循環(huán)画饥,那么你的應(yīng)用也就退出了衔瓮。looper采用,epoll+pipe抖甘,有消息就依次執(zhí)行热鞍,沒消息就block住,讓出CPU衔彻,等有消息了薇宠,epoll會(huì)往pipe中寫一個(gè)字符,把主線程從block狀態(tài)喚起艰额,主線程就繼續(xù)依次執(zhí)行消息澄港。
Android的線程和線程池:
AsyncTask
HandlerThread
IntentService(見前文)
按用途可分為兩類:
主線程:一般一個(gè)進(jìn)程只有一個(gè)主線程,主要處理界面交互相關(guān)的邏輯柄沮。
子線程:除主線程之外都是子線程回梧,主要用于執(zhí)行耗時(shí)操作。
按形態(tài)可分為三類:
AsyncTask:底層封裝了線程池和Handler祖搓,便于執(zhí)行后臺任務(wù)以及在子線程中進(jìn)行UI操作狱意。
HandlerThread:一種具有消息循環(huán)的線程,其內(nèi)部可使用Handler拯欧。
IntentService:是一種異步详囤、會(huì)自動(dòng)停止的服務(wù),內(nèi)部采用HandlerThread哈扮。
1.AsyncTask? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Android AsyncTask完全解析纬纪,帶你從源碼的角度徹底理解 - 郭霖的專欄 - CSDN博客
AsyncTask:一種輕量級的異步任務(wù)類。AsyncTask的好處:創(chuàng)建異步任務(wù)更簡單滑肉,直接繼承它可方便實(shí)現(xiàn)后臺異步任務(wù)的執(zhí)行和進(jìn)度的回調(diào)更新UI包各,而無需編寫任務(wù)線程和Handler實(shí)例就能完成相同的任務(wù)。
1.execute(Params... params)靶庙,執(zhí)行一個(gè)異步任務(wù)问畅,需要我們在代碼中調(diào)用此方法,觸發(fā)異步任務(wù)的執(zhí)行六荒。
2.onPreExecute()护姆,在execute(Params... params)被調(diào)用后立即執(zhí)行,一般用來在執(zhí)行后臺任務(wù)前對UI做一些標(biāo)記掏击。
3.doInBackground(Params... params)卵皂,在onPreExecute()完成后立即執(zhí)行,用于執(zhí)行較為費(fèi)時(shí)的操作砚亭,此方法將接收輸入?yún)?shù)和返回計(jì)算結(jié)果灯变。在執(zhí)行過程中可以調(diào)用publishProgress(Progress... values)來更新進(jìn)度信息殴玛。
4.onProgressUpdate(Progress... values),在調(diào)用publishProgress(Progress... values)時(shí)添祸,此方法被執(zhí)行滚粟,直接將進(jìn)度信息更新到UI組件上。
5.onPostExecute(Result result)刃泌,當(dāng)后臺操作結(jié)束時(shí)凡壤,此方法將會(huì)被調(diào)用,計(jì)算結(jié)果將做為參數(shù)傳遞到此方法中耙替,直接將結(jié)果顯示到UI組件上亚侠。
工作原理:
內(nèi)部有一個(gè)靜態(tài)的Handler對象即InternalHandler:
作用:將執(zhí)行環(huán)境從線程池切換到主線程;通過它來發(fā)送任務(wù)執(zhí)行的進(jìn)度以及執(zhí)行結(jié)束等消息林艘。
注意:必須在主線程中創(chuàng)建
內(nèi)部有兩個(gè)線程池:
SerialExecutor:用于任務(wù)的排隊(duì)盖奈,默認(rèn)是串行的線程池
THREAD_POOL_EXECUTOR:用于真正執(zhí)行任務(wù)。
排隊(duì)執(zhí)行過程:把參數(shù)Params封裝為FutureTask對象狐援,相當(dāng)于Runnable钢坦;調(diào)用SerialExecutor.execute()將FutureTask插入到任務(wù)隊(duì)列tasks;若沒有正在活動(dòng)的AsyncTask任務(wù)啥酱,則就會(huì)執(zhí)行下一個(gè)AsyncTask任務(wù)爹凹。執(zhí)行完畢后會(huì)繼續(xù)執(zhí)行其他任務(wù)直到所有任務(wù)都完成。即默認(rèn)使用串行方式執(zhí)行任務(wù)镶殷。
2.HandlerThread
HandlerThread是一個(gè)線程類禾酱,它繼承自Thread,與普通Thread的區(qū)別:具有消息循環(huán)的效果绘趋。內(nèi)部HandlerThread.run()方法中有Looper颤陶,通過Looper.prepare()來創(chuàng)建消息隊(duì)列,并通過Looper.loop()來開啟消息循環(huán)陷遮。
實(shí)現(xiàn)方法步驟:實(shí)例化一個(gè)HandlerThread對象滓走,參數(shù)是該線程的名稱;通過HandlerThread.start()開啟線程帽馋;實(shí)例化一個(gè)Handler并傳入HandlerThread中的looper對象搅方,使得與HandlerThread綁定;利用Handler即可執(zhí)行異步任務(wù)绽族;當(dāng)不需要HandlerThread時(shí)姨涡,通過HandlerThread.quit()/quitSafely()方法來終止線程的執(zhí)行。
Animation(android動(dòng)畫):要點(diǎn)提煉|開發(fā)藝術(shù)之Animation - 簡書
1.View動(dòng)畫(View Animation)/補(bǔ)間動(dòng)畫(Tween animation)
2.逐幀動(dòng)畫(Drawable Animation)
3.屬性動(dòng)畫(Property Animation)
View動(dòng)畫:平移動(dòng)畫吧慢、縮放動(dòng)畫涛漂、旋轉(zhuǎn)動(dòng)畫和透明度動(dòng)畫
通過xml定義:該xml文件創(chuàng)建在res/anim/?下。
根節(jié)點(diǎn)<set>检诗,子節(jié)點(diǎn)<translate>怖喻、<scale>底哗、<rotate>、<alpha >锚沸,分別對應(yīng)四種View動(dòng)畫:
通過Java代碼動(dòng)態(tài)創(chuàng)建具體步驟:
step1:創(chuàng)建TranslateAnimation、RotateAnimation涕癣、ScaleAnimation或AlphaAnimation對象哗蜈。
step2:設(shè)置創(chuàng)建的動(dòng)畫對象的屬性,如動(dòng)畫執(zhí)行時(shí)間坠韩、延遲時(shí)間距潘、起始位置、結(jié)束位置等只搁。
step3:通過View.startAnimation()方法開啟動(dòng)畫音比。
step4:可通過Animation.setAnimationListener()設(shè)置動(dòng)畫的監(jiān)聽器。
Activity的切換效果:
該xml文件創(chuàng)建在res/anim/?下氢惋,Activity默認(rèn)是有切換效果的洞翩,若需要自定義切換效果,需要用到overridePendingTransition(int inAnim, int outAnim)方法焰望。
startActivity(intent);?
overridePendingTransition(R.anim.enter_anim,R.anim.exit_anim);
逐幀動(dòng)畫對應(yīng)類AnimationDrawable:
a.通過xml定義:
該xml文件創(chuàng)建在res/drawable/?下骚亿。根節(jié)點(diǎn)<animation-list>,屬性android:oneshot表示是否執(zhí)行一次熊赖;子節(jié)點(diǎn)<item>?下可設(shè)置輪播的圖片資源id和持續(xù)時(shí)間来屠。在xml聲明好之后,將它作為View的背景并通過AnimationDrawable來播放即可震鹉。
b.通過Java代碼動(dòng)態(tài)創(chuàng)建:
AnimationDrawable ad =newAnimationDrawable();
for(inti =0; i <4; i++) {
Drawable drawable = getResources().getDrawable(getResources().getIdentifier("xxx"+ i,"drawable", getPackageName()));?
?ad.addFrame(drawable,500);? }?
?ad.setOneShot(false)俱笛;
mView.setBackgroundResource(ad);
ad.start();
屬性動(dòng)畫:通過改變對象屬性來實(shí)現(xiàn)動(dòng)畫,真正改變了view传趾,Android 屬性動(dòng)畫:這是一篇很詳細(xì)的 屬性動(dòng)畫 總結(jié)&攻略 - 簡書
插值器迎膜、估值器:Android 動(dòng)畫:你真的會(huì)使用插值器與估值器嗎?(含詳細(xì)實(shí)例教學(xué)) - 簡書
實(shí)現(xiàn)方式:在res/animator/下可創(chuàng)建屬性動(dòng)畫的xml文件墨缘。其中星虹,根節(jié)點(diǎn)<set>對應(yīng)AnimatorSet類,子節(jié)點(diǎn)<objectAnimator>對應(yīng)ObjectAnimator類镊讼、<animator>對應(yīng)ValueAnimator類宽涌。
ObjectAnimator與 ValueAnimator類的區(qū)別:
ValueAnimator 類是先改變值,然后手動(dòng)賦值給對象的屬性從而實(shí)現(xiàn)動(dòng)畫蝶棋;是間接對對象屬性進(jìn)行操作卸亮;
ObjectAnimator 類是先改變值,然后自動(dòng)賦值給對象的屬性從而實(shí)現(xiàn)動(dòng)畫玩裙;是直接對對象屬性進(jìn)行操作兼贸;
Android系統(tǒng)的有哪些安全機(jī)制:
應(yīng)用程序簽名機(jī)制段直,權(quán)限申明機(jī)制,訪問控制機(jī)制溶诞,進(jìn)程通訊機(jī)制鸯檬,內(nèi)存管理機(jī)制。
未完待續(xù)..............