介紹自己負(fù)責(zé)的部分,如何實現(xiàn)的。
自定義view viewGroup
activity的啟動流程
事件傳遞及滑動沖突的處理
插件化(activity如何加載及資源處理
內(nèi)存優(yōu)化 吼过,如何避免oom
內(nèi)存泄漏如何處理及如何排查
handler問題
圖片加載用的什么以及原理
從一堆數(shù)據(jù)里怎么查找最大的n個數(shù)
快速排序
字符串匹配
介紹自己負(fù)責(zé)的部分,如何實現(xiàn)的
這個把自己負(fù)責(zé)的模塊說清楚就好,一般有一下幾個方面可以說一下,前提是不要給自己挖坑
自己負(fù)責(zé)模塊在整個項目中的角色,也就是功能描述
開發(fā)前的自己的一些思考,比如對業(yè)務(wù)的抽象,接口的定義传于,協(xié)議的定義等等
開發(fā)編碼過程中遇到的難點以及坑
排查問題以及結(jié)解決方式
兼容性保證
性能優(yōu)化
上線之后模塊導(dǎo)致crash的比例
自定義view viewGroup
這個就是約定的幾個方法,onMeasure,onLayout,onDraw,measure,layout,draw
同時注意寫方法的調(diào)用時機(jī)以及區(qū)別,比如onMeasure是個模版方法是在measure下調(diào)用的,這個方法在viewGroup里面,
自定義的這些就已經(jīng)足夠了,如果還擴(kuò)展一些更新問題醉顽,子線程能不能更新沼溜,是可以的,在ViewRootImpl沒創(chuàng)建之前可以更新,不同sdk這個類可能名字不一樣游添。
activity的啟動流程
這個肯定不是說activity的生命周期系草,是啟動加載過程,大致說下流程,具體的要自己看代碼了,大致過程有:
這里可能分好幾種情況,其實都差不很多唆涝,這里就說一種情況,startActivity這個怎么啟動Activity的,
startActivity->ActivityManagerService->ActivityThread->Activity,大概參與就這幾個核心類,里面經(jīng)過了兩層binder通信,最后路由到IApplicationThread,然后到ActivityThread中的H消息隊列中啟動Activity找都,細(xì)節(jié)很多,可以在評論詢問廊酣。
事件傳遞及滑動沖突的處理
事件傳遞理解成責(zé)任鏈?zhǔn)秸{(diào)用就好能耻,也就是從最內(nèi)層到外層時間委派,如果事件consume了亡驰,那么就給這個view處理晓猛,不然從外向內(nèi)冒泡,
沖突處理舉個實例就好凡辱,比如SlideMenu與banner或者ListView與Scrollview的沖突等等戒职,說出基本思路就行,這些解決一般都是重寫那幾個事件方法煞茫,然后各種判斷就好
插件化(activity如何加載及資源處理)
Activity使用占坑hook加載,也可以使用靜態(tài)代理帕涌,靜態(tài)代理就需要自定義classloader,記住這個加載模式就行摄凡,再多細(xì)節(jié)在評論回復(fù)吧
,資源處理就是assetmanager的創(chuàng)建蚓曼,然后資源沖突處理亲澡,簡單的可以構(gòu)建多個assetmanager就沒有沖突問題,應(yīng)為隔離了纫版,如果使用一個那么
打包aapt定制一下就行,還有很多細(xì)節(jié)床绪,在評論回復(fù)吧,說不完了其弊。
內(nèi)存優(yōu)化 癞己,如何避免oom
內(nèi)存優(yōu)化太多要說的了,有套路的回答梭伐,基本就是避免跟gc配合好工作痹雅,比如:盡量復(fù)用對象,處理無用對象糊识,避免內(nèi)存泄漏绩社,壓縮對象等等
,盡量將大對象特殊處理赂苗,比如bitmap占用內(nèi)存較多愉耙,可以jni層與java層配合一起,大小壓縮拌滋,質(zhì)量壓縮朴沿,imsimplesize的大小定義,規(guī)范等等败砂,程序中有內(nèi)存管理模塊赌渣,避免內(nèi)存壓力大的時候
,能夠釋放內(nèi)存吠卷,避免oom發(fā)生的幾率锡垄,還有很多方面,在評論回復(fù)吧祭隔。
內(nèi)存泄漏如何處理及如何排查
內(nèi)存泄漏最大的問題就是無用對象常駐內(nèi)存货岭,導(dǎo)致內(nèi)存壓力很大,最后可能導(dǎo)致oom發(fā)生疾渴。盡量將對象生命周期可以在控制的能力之內(nèi)千贯,具體的在回復(fù)說吧,也很多場景,比如:context 除了特殊情況用activity搞坝,其他我們沒理由不用application搔谴。排查導(dǎo)出堆空間,然后mat分析桩撮,程序里面
用leackcanary定位敦第。
handler問題
這個需要回復(fù)兩個基本的峰弹,首先handler的創(chuàng)建需要loop,loop怎么創(chuàng)建的芜果,同時這個里面怎么保證loop線程安全的鞠呈,還有就是消息如何分發(fā)的,也就是消息發(fā)送到接受的流程右钾,
還有callback對消息處理的影響蚁吝,這些足夠了,還可以說可以跨進(jìn)程舀射,這樣就更棒了窘茁,具體的在回復(fù)說,太多了脆烟。
圖片加載用的什么以及原理
圖片加載的太多了山林,說個自己非常熟悉的就行,不要給自己挖坑浩淘,都懂的捌朴,比如你熟悉uil,那就說具體的加載過程张抄,
套路都差不多,都是創(chuàng)建圖片task洼怔,先從緩存取出來署惯,取不到就去網(wǎng)絡(luò)下載,下載完之后镣隶,同時緩存起來极谊,這里需要說下,線程池安岂,隊列轻猖,pause,resume的具體細(xì)節(jié)域那,比如跟view咙边,activity的綁定關(guān)系〈卧保回復(fù)具體說败许,也很多
從一堆數(shù)據(jù)里怎么查找最大的n個數(shù)
這個用歸并排序,或者直接快排淑蔚,沒啥還說的市殷。不會的自己google看算法,算法后面我會寫出來到文章里面刹衫。
快速排序
基本思想挖坑醋寝,分而治之搞挣,按照這個思路看代碼就行
字符串匹配
這個kmp算法,或者最基本的吧音羞,不考慮時間柿究,空間復(fù)雜度的條件下,但是不要說這個黄选,太low了點蝇摸。其實這些算法背下來就好,不是業(yè)務(wù)場景的办陷,意義不大貌夕,但是必須要會,不然吃虧了
架構(gòu)
其實架構(gòu)沒有固定模式,能夠說出自己對架構(gòu)的理解就很好民镜,比如mvp啡专,不同人對這個理解不一樣,最好的制圈,夠用的们童,最適合業(yè)務(wù)的才是好架構(gòu),這個也很多要說鲸鹦,評論說吧慧库。
熱點
如何保證Service不被殺死?
Android 進(jìn)程不死從3個層面入手:
A.提供進(jìn)程優(yōu)先級,降低進(jìn)程被殺死的概率方法一:監(jiān)控手機(jī)鎖屏解鎖事件馋嗜,在屏幕鎖屏?xí)r啟動1個像素的 Activity齐板,在用戶解鎖時將 Activity 銷毀掉。方法二:啟動前臺service葛菇。方法三:提升service優(yōu)先級:在AndroidManifest.xml文件中對于intent-filter可以通過android:priority = "1000"這個屬性設(shè)置最高優(yōu)先級甘磨,1000是最高值,如果數(shù)字越小則優(yōu)先級越低眯停,同時適用于廣播济舆。
B. 在進(jìn)程被殺死后,進(jìn)行拉活方法一:注冊高頻率廣播接收器莺债,喚起進(jìn)程滋觉。如網(wǎng)絡(luò)變化,解鎖屏幕九府,開機(jī)等方法二:雙進(jìn)程相互喚起椎瘟。方法三:依靠系統(tǒng)喚起。方法四:onDestroy方法里重啟service:service +broadcast? 方式侄旬,就是當(dāng)service走ondestory的時候肺蔚,發(fā)送一個自定義的廣播,當(dāng)收到廣播的時候儡羔,重新啟動service宣羊;
C. 依靠第三方根據(jù)終端不同璧诵,在小米手機(jī)(包括 MIUI)接入小米推送、華為手機(jī)接入華為推送仇冯;其他手機(jī)可以考慮接入騰訊信鴿或極光推送與小米推送做 A/B Test之宿。??
參考博客:Android 進(jìn)程保活招式大全
ButterKnife原理ButterKnife對性能的影響很小苛坚,因為沒有使用使用反射比被,而是使用的Annotation Processing Tool(APT),注解處理器,javac中用于編譯時掃描和解析Java注解的工具泼舱。在編譯階段執(zhí)行的等缀,它的原理就是讀入Java源代碼,解析注解娇昙,然后生成新的Java代碼尺迂。新生成的Java代碼最后被編譯成Java字節(jié)碼,注解解析器不能改變讀入的Java 類冒掌,比如不能加入或刪除Java方法噪裕。
參考資料:最新ButterKnife框架原理Java Annotation 及幾個常用開源項目注解原理簡析ButterKnife 簡單原理實現(xiàn)
基礎(chǔ)
Activity和Fragment生命周期有哪些??
屏幕快照 2016-09-19 下午8.10.27.png
橫豎屏切換時候Activity的生命周期
不設(shè)置Activity的android:configChanges時股毫,切屏?xí)匦禄氐舾鱾€生命周期膳音,切橫屏?xí)r會執(zhí)行一次,切豎屏?xí)r會執(zhí)行兩次設(shè)置Activity的android:configChanges=”orientation”時皇拣,切屏還是會調(diào)用各個生命周期严蓖,切換橫豎屏只會執(zhí)行一次設(shè)置Activity的android:configChanges=”orientation |keyboardHidden”時,切屏不會重新調(diào)用各個生命周期氧急,只會執(zhí)行onConfigurationChanged方法
AsyncTask源碼解析AsyncTask的缺陷和問題關(guān)于線程池:asynctask對應(yīng)的線程池ThreadPoolExecutor都是進(jìn)程范圍內(nèi)共享的,都是static的毫深,所以是asynctask控制著進(jìn)程范圍內(nèi)所有的子類實例吩坝。由于這個限制的存在,當(dāng)使用默認(rèn)線程池時哑蔫,如果線程數(shù)超過線程池的最大容量钉寝,線程池就會爆掉(3.0后默認(rèn)串行執(zhí)行,不會出現(xiàn)這個問題)闸迷。針對這種情況嵌纲,可以嘗試自定義線程池,配合asynctask使用腥沽。
關(guān)于默認(rèn)線程池:核心線程池中最多有CPU_COUNT+1個逮走,最多有CPU_COUNT*2+1個,線程等待隊列的最大等待數(shù)為128今阳,但是可以自定義線程池师溅。線程池是由AsyncTask來管理的茅信,線程池允許tasks并行運行,需要注意的是并發(fā)情況下數(shù)據(jù)的一致性問題墓臭,新數(shù)據(jù)可能會被老數(shù)據(jù)覆蓋掉蘸鲸,類似volatile變量。所以希望tasks能夠串行運行的話窿锉,使用SERIAL_EXECUTOR酌摇。
AsyncTask在不同的SDK版本中的區(qū)別:調(diào)用AsyncTask的excute方法不能立即執(zhí)行程序的原因分析及改善方案通過查閱官方文檔發(fā)現(xiàn),AsyncTask首次引入時嗡载,異步任務(wù)是在一個獨立的線程中順序的執(zhí)行窑多,也就是說一次只能執(zhí)行一個任務(wù)乡恕,不能并行的執(zhí)行腕窥,從1.6開始,AsyncTask引入了線程池态鳖,支持同時執(zhí)行5個異步任務(wù)判沟,也就是說同時只能有5個線程運行耿芹,超過的線程只能等待,等待前面的線程某個執(zhí)行完了才被調(diào)度和運行挪哄。換句話說吧秕,如果一個進(jìn)程中的AsyncTask實例個數(shù)超過5個,那么假如前5個都運行很長時間的話迹炼,那么第6個只能等待機(jī)會了砸彬。這是AsyncTask的一個限制,而且對于2.3以前的版本無法解決斯入。如果你的應(yīng)用需要大量的后臺線程去執(zhí)行任務(wù)砂碉,那么你只能放棄使用AsyncTask,自己創(chuàng)建線程池來管理Thread刻两。不得不說增蹭,雖然AsyncTask較Thread使用起來方便,但是它最多只能同時運行5個線程磅摹,這也大大局限了它的實力滋迈,你必須要小心設(shè)計你的應(yīng)用,錯開使用AsyncTask的時間户誓,盡力做到分時饼灿,或者保證數(shù)量不會大于5個,否則就會遇到上次提到的問題帝美“恚可能是Google意識到了AsyncTask的局限性了,從Android3.0開始對AsyncTask的API作出了一些調(diào)整:每次只啟動一個線程執(zhí)行一個任務(wù),完成之后再執(zhí)行第二個任務(wù)硕旗,也就是相當(dāng)于只有一個后臺線程在執(zhí)行所提交的任務(wù)窗骑。
1.生命周期很多開發(fā)者會認(rèn)為一個在Activity中創(chuàng)建的AsyncTask會隨著Activity的銷毀而銷毀。然而事實并非如此漆枚。AsyncTask會一直執(zhí)行创译,直到doInBackground()方法執(zhí)行完畢。然后墙基,如果cancel(boolean)被調(diào)用,那么onCancelled(Result result)方法會被執(zhí)行软族;否則,執(zhí)行onPostExecute(Result result)方法残制。如果我們的Activity銷毀之前立砸,沒有取消AsyncTask,這有可能讓我們的AsyncTask崩潰(crash)初茶。因為它想要處理的view已經(jīng)不在了颗祝。所以,我們總是必須確保在銷毀活動之前取消任務(wù)恼布÷荽粒總之,我們使用AsyncTask需要確保AsyncTask正確的取消折汞。
2.內(nèi)存泄漏如果AsyncTask被聲明為Activity的非靜態(tài)的內(nèi)部類倔幼,那么AsyncTask會保留一個對Activity的引用。如果Activity已經(jīng)被銷毀爽待,AsyncTask的后臺線程還在執(zhí)行损同,它將繼續(xù)在內(nèi)存里保留這個引用,導(dǎo)致Activity無法被回收鸟款,引起內(nèi)存泄漏膏燃。
3.結(jié)果丟失屏幕旋轉(zhuǎn)或Activity在后臺被系統(tǒng)殺掉等情況會導(dǎo)致Activity的重新創(chuàng)建,之前運行的AsyncTask會持有一個之前Activity的引用何什,這個引用已經(jīng)無效蹄梢,這時調(diào)用onPostExecute()再去更新界面將不再生效。
4.并行還是串行在Android1.6之前的版本富俄,AsyncTask是串行的,在1.6至2.3的版本而咆,改成了并行的霍比。在2.3之后的版本又做了 修改,可以支持并行和串行暴备,當(dāng)想要串行執(zhí)行時悠瞬,直接執(zhí)行execute()方法,如果需要執(zhí)行executeOnExecutor(Executor)。
Acitivty的任務(wù)棧
使用android:launchMode="standard|singleInstance|single Task|singleTop"來控制Acivity任務(wù)棧浅妆。
任務(wù)棧是一種后進(jìn)先出的結(jié)構(gòu)望迎。位于棧頂?shù)腁ctivity處于焦點狀態(tài),當(dāng)按下back按鈕的時候,棧內(nèi)的Activity會一個一個的出棧,并且調(diào)用其onDestory()方法。如果棧內(nèi)沒有Activity,那么系統(tǒng)就會回收這個棧,每個APP默認(rèn)只有一個棧,以APP的包名來命名.
standard : 標(biāo)準(zhǔn)模式,每次啟動Activity都會創(chuàng)建一個新的Activity實例,并且將其壓入任務(wù)棧棧頂,而不管這個Activity是否已經(jīng)存在凌外。Activity的啟動三回調(diào)(onCreate()->onStart()->onResume())都會執(zhí)行辩尊。
singleTop : 棧頂復(fù)用模式.這種模式下,如果新Activity已經(jīng)位于任務(wù)棧的棧頂,那么此Activity不會被重新創(chuàng)建,所以它的啟動三回調(diào)就不會執(zhí)行,同時Activity的onNewIntent()方法會被回調(diào).如果Activity已經(jīng)存在但是不在棧頂,那么作用于standard模式一樣.
singleTask: 棧內(nèi)復(fù)用模式.創(chuàng)建這樣的Activity的時候,系統(tǒng)會先確認(rèn)它所需任務(wù)棧已經(jīng)創(chuàng)建,否則先創(chuàng)建任務(wù)棧.然后放入Activity,如果棧中已經(jīng)有一個Activity實例,那么這個Activity就會被調(diào)到棧頂,onNewIntent(),并且singleTask會清理在當(dāng)前Activity上面的所有Activity.(clear top)
singleInstance : 加強(qiáng)版的singleTask模式,這種模式的Activity只能單獨位于一個任務(wù)棧內(nèi),由于棧內(nèi)復(fù)用的特性,后續(xù)請求均不會創(chuàng)建新的Activity,除非這個獨特的任務(wù)棧被系統(tǒng)銷毀了Activity的堆棧管理以ActivityRecord為單位,所有的ActivityRecord都放在一個List里面.可以認(rèn)為一個ActivityRecord就是一個Activity棧
onSaveInstanceState() 與onRestoreIntanceState()用戶或者程序員主動去銷毀一個Activity的時候不會掉用,其他情況都會調(diào)動康辑,來保存界面信息摄欲。如代碼中finish()或用戶按下back,不會掉用疮薇。
android中進(jìn)程的優(yōu)先級胸墙??
前臺進(jìn)程:即與用戶正在交互的Activity或者Activity用到的Service等,如果系統(tǒng)內(nèi)存不足時前臺進(jìn)程是最后被殺死的
可見進(jìn)程:可以是處于暫停狀態(tài)(onPause)的Activity或者綁定在其上的Service按咒,即被用戶可見迟隅,但由于失去了焦點而不能與用戶交互
服務(wù)進(jìn)程:其中運行著使用startService方法啟動的Service,雖然不被用戶可見励七,但是卻是用戶關(guān)心的智袭,例如用戶正在非音樂界面聽的音樂或者正在非下載頁面自己下載的文件等;當(dāng)系統(tǒng)要空間運行前兩者進(jìn)程時才會被終止
后臺進(jìn)程:其中運行著執(zhí)行onStop方法而停止的程序呀伙,但是卻不是用戶當(dāng)前關(guān)心的补履,例如后臺掛著的QQ,這樣的進(jìn)程系統(tǒng)一旦沒了有內(nèi)存就首先被殺死
空進(jìn)程:不包含任何應(yīng)用程序的程序組件的進(jìn)程剿另,這樣的進(jìn)程系統(tǒng)是一般不會讓他存在的
Serializable和Parcelable序列化箫锤,表示將一個對象轉(zhuǎn)換成可存儲或可傳輸?shù)臓顟B(tài)。序列化后的對象可以在網(wǎng)絡(luò)上進(jìn)行傳輸雨女,也可以存儲到本地谚攒。
Serializable(Java自帶):Serializable是序列化的意思,表示將一個對象轉(zhuǎn)換成可存儲或可傳輸?shù)臓顟B(tài)氛堕。序列化后的對象可以在網(wǎng)絡(luò)上進(jìn)行傳輸馏臭,也可以存儲到本地。
Parcelable(android 專用):除了Serializable之外讼稚,使用Parcelable也可以實現(xiàn)相同的效果括儒,不過不同于將對象進(jìn)行序列化,Parcelable方式的實現(xiàn)原理是將一個完整的對象進(jìn)行分解锐想,而分解后的每一部分都是Intent所支持的數(shù)據(jù)類型帮寻,這樣也就實現(xiàn)傳遞對象的功能了。
動畫
tween 補(bǔ)間動畫赠摇。通過指定View的初末狀態(tài)和變化時間固逗、方式浅蚪,對View的內(nèi)容完成一系列的圖形變換來實現(xiàn)動畫效果。 Alpha, Scale ,Translate, Rotate烫罩。
frame 幀動畫 AnimationDrawable 控制 animation-list xml布局
PropertyAnimation 屬性動畫 3.0引入惜傲,屬性動畫核心思想是對值的變化。?
?屬性動畫詳解Property Animation 動畫有兩個步聚:1.計算屬性值2.為目標(biāo)對象的屬性設(shè)置屬性值贝攒,即應(yīng)用和刷新動畫
valuecaculate.png
計算屬性分為3個過程:?
過程一:計算已完成動畫分?jǐn)?shù) elapsed fraction 為了執(zhí)行一個動畫盗誊,你需要創(chuàng)建一個 ValueAnimator,并且指定目標(biāo)對象屬性的開始饿这、結(jié)束值和持續(xù)時間浊伙。在調(diào)用 start 后的整個動畫過程中, ValueAnimator 會根據(jù)已經(jīng)完成的動畫時間計算得到一個 0 到 1 之間的分?jǐn)?shù)长捧,代表該動畫的已完成動畫百分比嚣鄙。0 表示 0%,1 表示 100%串结。?
過程二:計算插值(動畫變化率)interpolated fraction 當(dāng) ValueAnimator 計算完已完成動畫分?jǐn)?shù)后哑子,它會調(diào)用當(dāng)前設(shè)置的 TimeInterpolator,去計算得到一個 interpolated(插值)分?jǐn)?shù)肌割,在計算過程中卧蜓,已完成動畫百分比會被加入到新的插值計算中。?
過程三:計算屬性值 當(dāng)插值分?jǐn)?shù)計算完成后把敞,ValueAnimator 會根據(jù)插值分?jǐn)?shù)調(diào)用合適的 TypeEvaluator 去計算運動中的屬性值弥奸。以上分析引入了兩個概念:已完成動畫分?jǐn)?shù)(elapsed fraction)、插值分?jǐn)?shù)( interpolated fraction )奋早。
Android的數(shù)據(jù)存儲形式
SQLite:SQLite是一個輕量級的數(shù)據(jù)庫盛霎,支持基本的SQL語法,是常被采用的一種數(shù)據(jù)存儲方式耽装。 Android為此數(shù)據(jù)庫提供了一個名為SQLiteDatabase的類愤炸,封裝了一些操作數(shù)據(jù)庫的api
SharedPreference: 以鍵值對的形勢儲存。其本質(zhì)就是一個xml文件掉奄,常用于存儲較簡單的參數(shù)設(shè)置规个。
File: 即常說的文件(I/O)存儲方法,常用語存儲大數(shù)量的數(shù)據(jù)姓建,但是缺點是更新數(shù)據(jù)將是一件困難的事情诞仓。
ContentProvider: Android系統(tǒng)中能實現(xiàn)所有應(yīng)用程序共享的一種數(shù)據(jù)存儲方式,由于數(shù)據(jù)通常在各應(yīng)用間的是互相私密的速兔,所以此存儲方式較少使用狂芋,但是其又是必不可少的一種存儲方式。例如音頻憨栽,視頻,圖片和通訊錄,一般都可以采用此種方式進(jìn)行存儲屑柔。每個Content Provider都會對外提供一個公共的URI(包裝成Uri對象)屡萤,如果應(yīng)用程序有數(shù)據(jù)需要共享時,就需要使用Content Provider為這些數(shù)據(jù)定義一個URI掸宛,然后其他的應(yīng)用程序就通過Content Provider傳入這個URI來對數(shù)據(jù)進(jìn)行操作死陆。
Context相關(guān)
Activity和Service以及Application的Context是不一樣的,Activity繼承自ContextThemeWraper.其他的繼承自ContextWrapper.每一個Activity和Service以及Application的Context都是一個新的ContextImpl對象getApplication()用來獲取Application實例的,但是這個方法只有在Activity和Service中才能調(diào)用的到唧瘾。那么也許在絕大多數(shù)情況下我們都是在Activity或者Service中使用Application的措译,但是如果在一些其它的場景,比如BroadcastReceiver中也想獲得Application的實例饰序,這時就可以借助getApplicationContext()方法领虹,getApplicationContext()比getApplication()方法的作用域會更廣一些,任何一個Context的實例求豫,只要調(diào)用getApplicationContext()方法都可以拿到我們的Application對象塌衰。創(chuàng)建Toast和對話框不可以用Application 的context,只能用Activity的context蝠嘉。Context的數(shù)量等于Activity的個數(shù) + Service的個數(shù) + 1最疆,這個1為Application
Android各版本新特性Android5.0新特性
MaterialDesign設(shè)計風(fēng)格
支持多種設(shè)備
支持64位ART虛擬機(jī)
Android6.0新特性
大量漂亮流暢的動畫
支持快速充電的切換
支持文件夾拖拽應(yīng)用
相機(jī)新增專業(yè)模式?
Android7.0新特性
分屏多任務(wù)
增強(qiáng)的Java8語言模式
夜間模式
Json
JSON的全程是JavaScript Object Notation,也就是JavaScript 對象表示法
JSON是存儲和交換文本信息的語法蚤告,類似XML努酸,但是比XML更小、更快杜恰,更易解析
JSON是輕量級的文本數(shù)據(jù)交換格式获诈,獨立于語言,具有自我描述性箫章,更易理解
對象可以包含多個名稱/值對烙荷,比如:?
{"name":"zhangsan" , "age":25}
使用谷歌的GSON包進(jìn)行解析在 Android Studio 里引入依賴:
compile 'com.google.code.gson:gson:2.7'
值得注意的是實體類中變量名稱必須和json中的值名相同。json1的解析我們這里的實體類是Student.class
Gson gson = new Gson();
Student student = gson.fromJson(json1, Student.class);
json2的解析我們可以解析成int數(shù)組檬寂,也可以解析成Integer的List终抽。解析成數(shù)組:?
Gson gson = new Gson();
int[] ages = gson.fromJson(json2, int[].class);
解析成List:
Gson gson = new Gson();
List<Integer> ages = gson.fromJson(json2, new TypeToken<List<Integer>>(){}.getType);
json3的解析同樣可以解析成List或者數(shù)組,我們就直接解析成List.
Gson gson = new Gson();
List<Student> students = gson.fromJson(json3, new TypeToke<List<Student>>(){}.getType);
android中有哪幾種解析xml的類,官方推薦哪種桶至?以及它們的原理和區(qū)別?
DOM解析???? 優(yōu)點:1.XML樹在內(nèi)存中完整存儲,因此可以直接修改其數(shù)據(jù)和結(jié)構(gòu).2.可以通過該解析器隨時訪問XML樹中的任何一個節(jié)點.3.DOM解析器的API在使用上也相對比較簡單.缺點:如果XML文檔體積比較大時,將文檔讀入內(nèi)存是非常消耗系統(tǒng)資源的.使用場景:DOM 是用與平臺和語言無關(guān)的方式表示 XML 文檔的官方 W3C 標(biāo)準(zhǔn).DOM 是以層次結(jié)構(gòu)組織的節(jié)點的集合.這個層次結(jié)構(gòu)允許開發(fā)人員在樹中尋找特定信息.分析該結(jié)構(gòu)通常需要加載整個文檔和構(gòu)造層次結(jié)構(gòu),然后才能進(jìn)行任何工作.DOM是基于對象層次結(jié)構(gòu)的.
SAX解析? 優(yōu)點:SAX 對內(nèi)存的要求比較低,因為它讓開發(fā)人員自己來決定所要處理的標(biāo)簽.特別是當(dāng)開發(fā)人員只需要處理文檔中所包含的部分?jǐn)?shù)據(jù)時,SAX 這種擴(kuò)展能力得到了更好的體現(xiàn).缺點:用SAX方式進(jìn)行XML解析時,需要順序執(zhí)行,所以很難訪問到同一文檔中的不同數(shù)據(jù).此外,在基于該方式的解析編碼過程也相對復(fù)雜.使用場景:對于含有數(shù)據(jù)量十分巨大,而又不用對文檔的所有數(shù)據(jù)進(jìn)行遍歷或者分析的時候,使用該方法十分有效.該方法不用將整個文檔讀入內(nèi)存,而只需讀取到程序所需的文檔標(biāo)簽處即可.
Xmlpull解析? android SDK提供了xmlpull api,xmlpull和sax類似,是基于流(stream)操作文件,然后根據(jù)節(jié)點事件回調(diào)開發(fā)者編寫的處理程序.因為是基于流的處理,因此xmlpull和sax都比較節(jié)約內(nèi)存資源,不會象dom那樣要把所有節(jié)點以對橡樹的形式展現(xiàn)在內(nèi)存中.xmlpull比sax更簡明,而且不需要掃描完整個流.
Jar和Aar的區(qū)別
Jar包里面只有代碼昼伴,aar里面不光有代碼還包括代碼還包括資源文件,比如 drawable 文件镣屹,xml 資源文件圃郊。對于一些不常變動的 Android Library,我們可以直接引用 aar女蜈,加快編譯速度
什么是三級緩存(研究中)
三級緩存原理(研究中)
Android為每個應(yīng)用程序分配的內(nèi)存大小是多少android程序內(nèi)存一般限制在16M持舆,也有的是24M?
更新UI方式Activity.runOnUiThread(Runnable)View.post(Runnable),View.postDelay(Runnable,long)HandlerAsyncTask?
進(jìn)階
引起內(nèi)存泄漏的情況?
對于使用了BraodcastReceiver色瘩,ContentObserver,F(xiàn)ile逸寓,游標(biāo) Cursor居兆,Stream,Bitmap等資源的使用竹伸,應(yīng)該在Activity銷毀時及時關(guān)閉或者注銷泥栖。
靜態(tài)內(nèi)部類持有外部成員變量(或context):可以使用弱引用或使用ApplicationContext。?
內(nèi)部類持有外部類引用,異步任務(wù)中勋篓,持有外部成員變量吧享。
集合中沒用的對象沒有及時remove。
不用的對象及時釋放譬嚣,如使用完Bitmap后掉用recycle()钢颂,再賦null。?
handler引起的內(nèi)存泄漏孤荣,MessageQueue里的消息如果在activity銷毀時沒有處理完甸陌,就會引起內(nèi)存的泄漏,可以使用弱引用解決盐股。
設(shè)置過的監(jiān)聽不用時钱豁,及時移除。如在Destroy時及時remove疯汁。尤其以addListener開頭的牲尺,在Destroy中都需要remove。
activity泄漏可以使用LeakCanary幌蚊。
Android 內(nèi)存溢出解決方案(OOM) 整理總結(jié)?
在內(nèi)存引用上做些處理谤碳,常用的有軟引用、弱引用??
在內(nèi)存中加載圖片時直接在內(nèi)存中作處理溢豆,如:邊界壓縮?
動態(tài)回收內(nèi)存?
優(yōu)化Dalvik虛擬機(jī)的堆內(nèi)存分配?
自定義堆內(nèi)存大小
Activity/Window/View三者的差別,fragment的特點
Activity像一個工匠(控制單元)蜒简,Window像窗戶(承載模型),View像窗花(顯示視圖) LayoutInflater像剪刀漩仙,Xml配置像窗花圖紙搓茬。?
在Activity中調(diào)用attach,創(chuàng)建了一個Window創(chuàng)建的window是其子類PhoneWindow队他,在attach中創(chuàng)建PhoneWindow在Activity中調(diào)用setContentView(R.layout.xxx)其中實際上是調(diào)用的getWindow().setContentView()調(diào)用PhoneWindow中的setContentView方法創(chuàng)建ParentView:? 作為ViewGroup的子類卷仑,實際是創(chuàng)建的DecorView(作為FramLayout的子類)將指定的R.layout.xxx進(jìn)行填充通過布局填充器進(jìn)行填充【其中的parent指的就是DecorView】調(diào)用到ViewGroup調(diào)用ViewGroup的removeAllView(),先將所有的view移除掉添加新的view:addView()?
Fragment 特點Fragment可以作為Activity界面的一部分組成出現(xiàn)麸折;可以在一個Activity中同時出現(xiàn)多個Fragment锡凝,并且一個Fragment也可以在多個Activity中使用;在Activity運行過程中垢啼,可以添加窜锯、移除或者替換Fragment张肾;Fragment可以響應(yīng)自己的輸入事件,并且有自己的生命周期衬浑,它們的生命周期會受宿主Activity的生命周期影響捌浩。
JVM 和Dalvik虛擬機(jī)的區(qū)別?
JVM:.java -> javac -> .class -> jar -> .jar架構(gòu): 堆和棧的架構(gòu).?
DVM:.java -> javac -> .class -> dx.bat -> .dex架構(gòu): 寄存器(cpu上的一塊高速緩存)
怎么考慮數(shù)據(jù)傳輸?shù)陌踩匀绻麘?yīng)用對傳輸?shù)臄?shù)據(jù)沒有任何安全措施,攻擊者設(shè)置的釣魚網(wǎng)絡(luò)中更改DNS服務(wù)器工秩。這臺服務(wù)器可以獲取用戶信息,或充當(dāng)中間人與原服務(wù)器交換數(shù)據(jù)进统。在SSL/TLS通信中助币,客戶端通過數(shù)字證書判斷服務(wù)器是否可信,并采用證書的公鑰與服務(wù)器進(jìn)行加密通信螟碎。
自定義View的相關(guān)方法 1.自定義屬性2.onLayout(Viewgroup)3.onMesure4.onDraw5.交互:onIntercepterTouchEvent()onTouchEvent()
事件傳遞機(jī)制 詳解當(dāng)手指觸摸到屏幕時眉菱,系統(tǒng)就會調(diào)用相應(yīng)View的onTouchEvent,并傳入一系列的action掉分。?
dispatchTouchEvent的執(zhí)行順序為:?
首先觸發(fā)ACTIVITY的dispatchTouchEvent,然后觸發(fā)ACTIVITY的onInterceptTouchEvent.然后觸發(fā)LAYOUT的dispatchTouchEvent俭缓,然后觸發(fā)LAYOUT的onInterceptTouchEvent這就解釋了重寫ViewGroup時必須調(diào)用super.dispatchTouchEvent();?
(1)dispatchTouchEvent:
此方法一般用于初步處理事件,因為動作是由此分發(fā)酥郭,所以通常會調(diào)用super.dispatchTouchEvent华坦。這樣就會繼續(xù)調(diào)用onInterceptTouchEvent,再由onInterceptTouchEvent決定事件流向不从。
(2)onInterceptTouchEvent:
若返回值為true事件會傳遞到自己的onTouchEvent();若返回值為false傳遞到下一個View的dispatchTouchEvent();
(3)onTouchEvent():
若返回值為true惜姐,事件由自己消耗,后續(xù)動作讓其處理椿息;若返回值為false歹袁,自己不消耗事件了,向上返回讓其他的父View的onTouchEvent接受處理
三大方法關(guān)系的偽代碼:如果當(dāng)前View攔截事件寝优,就交給自己的onTouchEvent去處理条舔,否則就丟給子View繼續(xù)走相同的流程。
public boolean dispatchTouchEvent(MotionEvent ev)
{
??? boolean consume = false;
??? if(onInterceptTouchEvent(ev))
??? {
??????? consume = onTouchEvent(ev);
??? }
??? else
??? {
??????? consume = child.dispatchTouchEvent(ev);
??? }
??? return consume;
}
onTouchEvent的傳遞:
當(dāng)有多個層級的View時乏矾,在父層級允許的情況下孟抗,這個action會一直傳遞直到遇到最深層的View。所以touch事件最先調(diào)用的是最底層View的onTouchEvent妻熊,如果View的onTouchEvent接收到某個touch action并做了相應(yīng)處理夸浅,最后有兩種返回方式return true和return false;return true會告訴系統(tǒng)當(dāng)前的View需要處理這次的touch事件扔役,以后的系統(tǒng)發(fā)出的ACTION_MOVE,ACTION_UP還是需要繼續(xù)監(jiān)聽并接收的帆喇,并且這次的action已經(jīng)被處理掉了,父層的View是不可能觸發(fā)onTouchEvent的了亿胸。所以每一個action最多只能有一個onTouchEvent接口返回true坯钦。如果返回false预皇,便會通知系統(tǒng),當(dāng)前View不關(guān)心這一次的touch事件婉刀,此時這個action會傳向父級吟温,調(diào)用父級View的onTouchEvent。但是這一次的touch事件之后發(fā)出任何action突颊,該View都不在接受鲁豪,onTouchEvent在這一次的touch事件中再也不會觸發(fā),也就是說一旦View返回false律秃,那么之后的ACTION_MOVE,ACTION_UP等ACTION就不會在傳入這個View,但是下一次touch事件的action還是會傳進(jìn)來的爬橡。
父層的onInterceptTouchEvent
前面說了底層的View能夠接收到這次的事件有一個前提條件:在父層允許的情況下。假設(shè)不改變父層級的dispatch方法棒动,在系統(tǒng)調(diào)用底層onTouchEvent之前會調(diào)用父View的onInterceptTouchEvent方法判斷糙申,父層View是否要截獲本次touch事件之后的action。如果onInterceptTouchEvent返回了true船惨,那么本次touch事件之后的所有action都不會向深層的View傳遞柜裸,統(tǒng)統(tǒng)都會傳給父層View的onTouchEvent,就是說父層已經(jīng)截獲了這次touch事件粱锐,之后的action也不必詢問onInterceptTouchEvent疙挺,在這次的touch事件之后發(fā)出的action時onInterceptTouchEvent不會再被調(diào)用,直到下一次touch事件的來臨卜范。如果onInterceptTouchEvent返回false衔统,那么本次action將發(fā)送給更深層的View,并且之后的每一次action都會詢問父層的onInterceptTouchEvent需不需要截獲本次touch事件海雪。只有ViewGroup才有onInterceptTouchEvent方法锦爵,因為一個普通的View肯定是位于最深層的View,touch能夠傳到這里已經(jīng)是最后一站了奥裸,肯定會調(diào)用View的onTouchEvent()险掀。
底層View的getParent().requestDisallowInterceptTouchEvent(true)
對于底層的View來說,有一種方法可以阻止父層的View獲取touch事件湾宙,就是調(diào)用getParent().requestDisallowInterceptTouchEvent(true)方法樟氢。一旦底層View收到touch的action后調(diào)用這個方法那么父層View就不會再調(diào)用onInterceptTouchEvent了,也無法截獲以后的action(如果父層ViewGroup和最底層View需要截獲不同焦點侠鳄,或不同手勢的touch埠啃,不能使用這個寫死)。
ART和Dalvik區(qū)別
art上應(yīng)用啟動快伟恶,運行快碴开,但是耗費更多存儲空間,安裝時間長,總的來說ART的功效就是”空間換時間”潦牛。
ART: Ahead of TimeDalvik: Just in Time
什么是Dalvik:Dalvik是Google公司自己設(shè)計用于Android平臺的Java虛擬機(jī)眶掌。Dalvik虛擬機(jī)是Google等廠商合作開發(fā)的Android移動設(shè)備平臺的核心組成部分之一,它可以支持已轉(zhuǎn)換為.dex(即Dalvik Executable)格式的Java應(yīng)用程序的運行巴碗,.dex格式是專為Dalvik應(yīng)用設(shè)計的一種壓縮格式朴爬,適合內(nèi)存和處理器速度有限的系統(tǒng)。Dalvik經(jīng)過優(yōu)化橡淆,允許在有限的內(nèi)存中同時運行多個虛擬機(jī)的實例召噩,并且每一個Dalvik應(yīng)用作為獨立的Linux進(jìn)程執(zhí)行。獨立的進(jìn)程可以防止在虛擬機(jī)崩潰的時候所有程序都被關(guān)閉逸爵。
什么是ART:Android操作系統(tǒng)已經(jīng)成熟蚣常,Google的Android團(tuán)隊開始將注意力轉(zhuǎn)向一些底層組件,其中之一是負(fù)責(zé)應(yīng)用程序運行的Dalvik運行時痊银。Google開發(fā)者已經(jīng)花了兩年時間開發(fā)更快執(zhí)行效率更高更省電的替代ART運行時。ART代表Android Runtime,其處理應(yīng)用程序執(zhí)行的方式完全不同于Dalvik施绎,Dalvik是依靠一個Just-In-Time(JIT)編譯器去解釋字節(jié)碼溯革。開發(fā)者編譯后的應(yīng)用代碼需要通過一個解釋器在用戶的設(shè)備上運行,這一機(jī)制并不高效谷醉,但讓應(yīng)用能更容易在不同硬件和架構(gòu)上運行致稀。ART則完全改變了這套做法,在應(yīng)用安裝的時候就預(yù)編譯字節(jié)碼到機(jī)器語言俱尼,這一機(jī)制叫Ahead-Of-Time(AOT)編譯抖单。在移除解釋代碼這一過程后,應(yīng)用程序執(zhí)行將更有效率遇八,啟動更快矛绘。
ART優(yōu)點:
系統(tǒng)性能的顯著提升應(yīng)用啟動更快、運行更快刃永、體驗更流暢货矮、觸感反饋更及時。更長的電池續(xù)航能力支持更低的硬件?
ART缺點:更大的存儲空間占用斯够,可能會增加10%-20%更長的應(yīng)用安裝時間
Scroller原理
Scroller執(zhí)行流程里面的三個核心方法
mScroller.startScroll()mScroller.computeScrollOffset()view.computeScroll()1囚玫、在mScroller.startScroll()中為滑動做了一些初始化準(zhǔn)備,比如:起始坐標(biāo)读规,滑動的距離和方向以及持續(xù)時間(有默認(rèn)值)抓督,動畫開始時間等。
2束亏、mScroller.computeScrollOffset()方法主要是根據(jù)當(dāng)前已經(jīng)消逝的時間來計算當(dāng)前的坐標(biāo)點铃在。因為在mScroller.startScroll()中設(shè)置了動畫時間,那么在computeScrollOffset()方法中依據(jù)已經(jīng)消逝的時間就很容易得到當(dāng)前時刻應(yīng)該所處的位置并將其保存在變量mCurrX和mCurrY中枪汪。除此之外該方法還可判斷動畫是否已經(jīng)結(jié)束涌穆。
Android中Java和JavaScript交互
webView.addJavaScriptInterface(new Object(){xxx}, "xxx");
1
答案:可以使用WebView控件執(zhí)行JavaScript腳本怔昨,并且可以在JavaScript中執(zhí)行Java代碼。要想讓W(xué)ebView控件執(zhí)行JavaScript宿稀,需要調(diào)用WebSettings.setJavaScriptEnabled方法趁舀,代碼如下:
WebView webView = (WebView)findViewById(R.id.webview);
WebSettings webSettings = webView.getSettings();
//設(shè)置WebView支持JavaScript
webSettings.setJavaScriptEnabled(true);
webView.setWebChromeClient(new WebChromeClient());
JavaScript調(diào)用Java方法需要使用WebView.addJavascriptInterface方法設(shè)置JavaScript調(diào)用的Java方法,代碼如下:
webView.addJavascriptInterface(new Object()
{
??? //JavaScript調(diào)用的方法
??? public String process(String value)
??? {
??????? //處理代碼
??????? return result;
??? }
}, "demo");?????? //demo是Java對象映射到JavaScript中的對象名
可以使用下面的JavaScript代碼調(diào)用process方法祝沸,代碼如下:
<script language="javascript">
??? function search()
??? {
??????? //調(diào)用searchWord方法
??????? result.innerHTML = "<font color='red'>" + window.demo.process('data') + "</font>";
??? }
SurfaceView和View的最本質(zhì)的區(qū)別
SurfaceView是在一個新起的單獨線程中可以重新繪制畫面矮烹,而view必須在UI的主線程中更新畫面。
在UI的主線程中更新畫面可能會引發(fā)問題罩锐,比如你更新的時間過長奉狈,那么你的主UI線程就會被你正在畫的函數(shù)阻塞。那么將無法響應(yīng)按鍵涩惑、觸屏等消息仁期。當(dāng)使用SurfaceView由于是在新的線程中更新畫面所以不會阻塞你的UI主線程。但這也帶來了另外一個問題竭恬,就是事件同步跛蛋。比如你觸屏了一下,你需要SurfaceView中thread處理痊硕,一般就需要有一個event queue的設(shè)計來保存touchevent赊级,這會稍稍復(fù)雜一點,因為涉及到線程安全岔绸。常用的設(shè)計模式單例理逊,適配器,策略模式等常用的設(shè)計模式需要掌握?
單例
public class Singleton{?
private volatile static Singleton mSingleton;
private Singleton(){
}
public static Singleton getInstance(){
? if(mSingleton == null){\\A
??? synchronized(Singleton.class){\\C
???? if(mSingleton == null)
????? mSingleton = new Singleton();\\B
????? }
??? }
??? return mSingleton;
? }
}
ANR排錯
1盒揉、ANR排錯一般有三種情況
KeyDispatchTimeout(5 seconds) –主要類型按鍵或觸摸事件在特定時間內(nèi)無響應(yīng)
BroadcastTimeout(10 secends) –BroadcastReceiver在特定時間內(nèi)無法處理完成??
ServiceTimeout(20 secends) –小概率事件 Service在特定的時間內(nèi)無法處理完成發(fā)生原因主線程被IO操作(從4.0之后網(wǎng)絡(luò)IO不允許在主線程中)阻塞晋被。主線程中存在耗時的計算主線程中錯誤的操作,比如Thread.wait或者Thread.sleep等 Android系統(tǒng)會監(jiān)控程序的響應(yīng)狀況使用AsyncTask處理耗時IO操作预烙。
2墨微、如何避免
UI線程盡量只做跟UI相關(guān)的工作耗時的操作(比如數(shù)據(jù)庫操作,I/O,連接網(wǎng)絡(luò)或者別的有可能阻塞UI線程的操作)把它放在單獨的線程處理盡量用Handler來處理UIthread和別的thread之間的交互.使用Thread或者HandlerThread時扁掸,調(diào)用Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND)設(shè)置優(yōu)先級翘县,否則仍然會降低程序響應(yīng),因為默認(rèn)Thread的優(yōu)先級和主線程相同谴分。使用Handler處理工作線程結(jié)果锈麸,而不是使用Thread.wait()或者Thread.sleep()來阻塞主線程。Activity的onCreate和onResume回調(diào)中盡量避免耗時的代碼BroadcastReceiver中onReceive代碼也要盡量減少耗時牺蹄,建議使用IntentService處理忘伞。
3、ANR定位和修正如果開發(fā)機(jī)器上出現(xiàn)問題,我們可以通過查看/data/anr/traces.txt即可氓奈,最新的ANR信息在最開始部分翘魄。?
Android程序運行時權(quán)限與文件系統(tǒng)權(quán)限1,Linux 文件系統(tǒng)權(quán)限暑竟。不同的用戶對文件有不同的讀寫執(zhí)行權(quán)限育勺。在android系統(tǒng)中,system和應(yīng)用程序是分開的腹躁,system里的數(shù)據(jù)是不可更改的南蓬。2,Android中有3種權(quán)限铐炫,進(jìn)程權(quán)限UserID,簽名蒜焊,應(yīng)用申明權(quán)限。每次安裝時科贬,系統(tǒng)根據(jù)包名為應(yīng)用分配唯一的userID泳梆,不同的userID運行在不同的進(jìn)程里,進(jìn)程間的內(nèi)存是獨立的榜掌,不可以相互訪問优妙,除非通過特定的Binder機(jī)制。Android提供了如下的一種機(jī)制,可以使兩個apk打破前面講的這種壁壘。在AndroidManifest.xml中利用sharedUserId屬性給不同的package分配相同的userID凡资,通過這樣做迫皱,兩個package可以被當(dāng)做同一個程序,系統(tǒng)會分配給兩個程序相同的UserID骨望。當(dāng)然,基于安全考慮,兩個package需要有相同的簽名雾鬼,否則沒有驗證也就沒有意義了。
如何讓程序自動啟動定義一個Braodcastreceiver宴树,action為BOOT——COMPLETE策菜,接受到廣播后啟動程序。
View繪制流程
斷電續(xù)傳詳解?
Handler機(jī)制andriod提供了Handler 和 Looper 來滿足線程間的通信。Handler先進(jìn)先出原則又憨。Looper類用來管理特定線程內(nèi)對象之間的消息交換(MessageExchange)翠霍。Looper: 一個線程可以產(chǎn)生一個Looper對象,由它來管理此線程里的MessageQueue(消息隊列)蠢莺。Handler: 你可以構(gòu)造Handler對象來與Looper溝通浪秘,以便push新消息到MessageQueue里;或者接收Looper從Message Queue取出)所送來的消息耸携。Message Queue(消息隊列):用來存放線程放入的消息狈谊。線程:UIthread 通常就是main thread河劝,而Android啟動程序時會替它建立一個MessageQueue。
ListView卡頓原因Adapter的getView方法里面convertView沒有使用setTag和getTag方式务甥;在getView方法里面ViewHolder初始化后的賦值或者是多個控件的顯示狀態(tài)和背景的顯示沒有優(yōu)化好敞临,抑或是里面含有復(fù)雜的計算和耗時操作;在getView方法里面 inflate的row 嵌套太深(布局過于復(fù)雜)或者是布局里面有大圖片或者背景所致编矾;Adapter多余或者不合理的notifySetDataChanged洽沟;listview 被多層嵌套怒详,多次的onMessure導(dǎo)致卡頓昆烁,如果多層嵌套無法避免,建議把listview的高和寬設(shè)置為fill_parent. 如果是代碼繼承的listview鼠渺,那么也請你別忘記為你的繼承類添加上LayoutPrams拦盹,注意高和寬都是fill_parent的;
啟動一個程序沼侣,可以主界面點擊圖標(biāo)進(jìn)入蛾洛,也可以從一個程序中跳轉(zhuǎn)過去,二者有什么區(qū)別?是因為啟動程序(主界面也是一個app)裂明,發(fā)現(xiàn)了在這個程序中存在一個設(shè)置為?
<category android:name="android.intent.category.LAUNCHER" />
的activity,所以這個launcher會把icon提出來闽晦,放在主界面上。當(dāng)用戶點擊icon的時候荠瘪,發(fā)出一個Intent:
Intent intent = mActivity.getPackageManager().getLaunchIntentForPackage(packageName);
mActivity.startActivity(intent);
跳過去可以跳到任意允許的頁面哀墓,如一個程序可以下載后雷,那么真正下載的頁面可能不是首頁(也有可能是首頁)臀突,這時還是構(gòu)造一個Intent,startActivity.這個intent中的action可能有多種view,download都有可能盒齿。系統(tǒng)會根據(jù)第三方程序向系統(tǒng)注冊的功能边翁,為你的Intent選擇可以打開的程序或者頁面。所以唯一的一點不同的是從icon的點擊啟動的intent的action是相對單一的啊胶,從程序中跳轉(zhuǎn)或者啟動可能樣式更多一些焰坪。本質(zhì)是相同的。
AIDL的全稱是什么?如何工作?能處理哪些類型的數(shù)據(jù)?AIDL全稱Android Interface Definition Language(Android接口描述語言)是一種接口描述語言; 編譯器可以通過aidl文件生成一段代碼黔漂,通過預(yù)先定義的接口達(dá)到兩個進(jìn)程內(nèi)部通信進(jìn)程跨界訪問對象的目的.AIDL的IPC的機(jī)制和COM或CORBA類似, 是基于接口的炬守,但它是輕量級的酣藻。它使用代理類在客戶端和實現(xiàn)層間傳遞值. 如果要使用AIDL, 需要完成2件事情: 1. 引入AIDL的相關(guān)類.; 2. 調(diào)用aidl產(chǎn)生的class.理論上, 參數(shù)可以傳遞基本數(shù)據(jù)類型和String, 還有就是Bundle的派生類, 不過在Eclipse中,目前的ADT不支持Bundle做為參數(shù),具體實現(xiàn)步驟如下:1、創(chuàng)建AIDL文件, 在這個文件里面定義接口, 該接口定義了可供客戶端訪問的方法和屬性抖仅。2撤卢、編譯AIDL文件, 用Ant的話, 可能需要手動, 使用Eclipse plugin的話,可以根據(jù)adil文件自動生產(chǎn)java文件并編譯, 不需要人為介入.3、在Java文件中, 實現(xiàn)AIDL中定義的接口. 編譯器會根據(jù)AIDL接口, 產(chǎn)生一個JAVA接口渡紫。這個接口有一個名為Stub的內(nèi)部抽象類惕澎,它繼承擴(kuò)展了接口并實現(xiàn)了遠(yuǎn)程調(diào)用需要的幾個方法。接下來就需要自己去實現(xiàn)自定義的幾個接口了.4八孝、向客戶端提供接口ITaskBinder, 如果寫的是service干跛,擴(kuò)展該Service并重載onBind ()方法來返回一個實現(xiàn)上述接口的類的實例。5、在服務(wù)器端回調(diào)客戶端的函數(shù). 前提是當(dāng)客戶端獲取的IBinder接口的時候,要去注冊回調(diào)函數(shù), 只有這樣, 服務(wù)器端才知道該調(diào)用那些函數(shù)AIDL語法很簡單,可以用來聲明一個帶一個或多個方法的接口阎姥,也可以傳遞參數(shù)和返回值呼巴。 由于遠(yuǎn)程調(diào)用的需要, 這些參數(shù)和返回值并不是任何類型.下面是些AIDL支持的數(shù)據(jù)類型:
不需要import聲明的簡單Java編程語言類型(int,boolean等)
String, CharSequence不需要特殊聲明
List, Map和Parcelables類型, 這些類型內(nèi)所包含的數(shù)據(jù)成員也只能是簡單數(shù)據(jù)類型, String等其他比支持的類型.(另外: 我沒嘗試Parcelables, 在Eclipse+ADT下編譯不過, 或許以后會有所支持).實現(xiàn)接口時有幾個原則:1.拋出的異常不要返回給調(diào)用者. 跨進(jìn)程拋異常處理是不可取的.2.IPC調(diào)用是同步的诊赊。如果你知道一個IPC服務(wù)需要超過幾毫秒的時間才能完成地話碧磅,你應(yīng)該避免在Activity的主線程中調(diào)用。也就是IPC調(diào)用會掛起應(yīng)用程序?qū)е陆缑媸ロ憫?yīng). 這種情況應(yīng)該考慮單起一個線程來處理.3.不能在AIDL接口中聲明靜態(tài)屬性秆撮。IPC的調(diào)用步驟:?
聲明一個接口類型的變量,該接口類型在.aidl文件中定義舒裤。?
實現(xiàn)ServiceConnection惭每。?
調(diào)用ApplicationContext.bindService(),并在ServiceConnection實現(xiàn)中進(jìn)行傳遞.?
在ServiceConnection.onServiceConnected()實現(xiàn)中,你會接收一個IBinder實例(被調(diào)用的Service). 調(diào)用YourInterfaceName.Stub.asInterface((IBinder)service)將參數(shù)轉(zhuǎn)換為YourInterface類型黎侈。?
調(diào)用接口中定義的方法峻汉。你總要檢測到DeadObjectException異常,該異常在連接斷開時被拋出瘤礁。它只會被遠(yuǎn)程方法拋出柜思。???
斷開連接号枕,調(diào)用接口實例中的ApplicationContext.unbindService()參考:http://buaadallas.blog.51cto.com/399160/372090
aidl主要就是幫助我們完成了包裝數(shù)據(jù)和解包的過程葱淳,并調(diào)用了transact過程,而用來傳遞的數(shù)據(jù)包我們就稱為parcel
AIDL: xxx.aidl->xxx.java,注冊service
用aidl定義需要被調(diào)用方法接口實現(xiàn)這些方法調(diào)用這些方法?
FC(Force Close)
什么時候會出現(xiàn)???
Error
OOM坑傅,內(nèi)存溢出
StackOverFlowError
Runtime,比如說空指針異常?
解決的辦法
注意內(nèi)存的使用和管理
使用Thread.UncaughtExceptionHandler接口
性能優(yōu)化
界面優(yōu)化太多重疊的背景(overdraw)
這個問題其實最容易解決唁毒,建議就是檢查你在布局和代碼中設(shè)置的背景,有些背景是隱藏在底下的近零,它永遠(yuǎn)不可能顯示出來久信,這種沒必要的背景一定要移除,因為它很可能會嚴(yán)重影響到app的性能腿椎。如果采用的是selector的背景啃炸,將normal狀態(tài)的color設(shè)置為”@android:color/transparent”,也同樣可以解決問題。
太多重疊的View
第一個建議是 :使用ViewStub來加載一些不常用的布局训枢,它是一個輕量級且默認(rèn)是不可見的視圖,可以動態(tài)的加載一個布局十酣,只要你用到這個重疊著的View的時候才加載耸采,推遲加載的時間。
第二個建議是:如果使用了類似Viewpager+Fragment這樣的組合或者有多個Fragment在一個界面上嘱朽,需要控制Fragment的顯示和隱藏搪泳,盡量使用動態(tài)的Inflation view,它的性能要比SetVisibility好艰赞。
復(fù)雜的Layout層級
這里的建議比較多一些猖毫,首先推薦使用Android提供的布局工具Hierarchy Viewer來檢查和優(yōu)化布局吁断。第一個建議是:如果嵌套的線性布局加深了布局層次,可以使用相對布局來取代是己。第二個建議是:用標(biāo)簽來合并布局沛厨。第三個建議是:用標(biāo)簽來重用布局逆皮,抽取通用的布局可以讓布局的邏輯更清晰明了秽梅。記住企垦,這些建議的最終目的都是使得你的Layout在Hierarchy Viewer里變得寬而淺钞诡,而不是窄而深。
總結(jié):可以考慮多使用merge和include誊抛,ViewStub拗窃。盡量使布局淺平,根布局盡量少使用RelactivityLayout,因為RelactivityLayout每次需要測量2次震放。
內(nèi)存優(yōu)化核心思想:減少內(nèi)存使用诈铛,能不new的不new幢竹,能少分配的少分配蹲坷。因為分配更多的內(nèi)存就意味著發(fā)生更多的GC循签,每次觸發(fā)GC都會占用CPU時間,影響性能。
集合優(yōu)化:Android提供了一系列優(yōu)化過后的數(shù)據(jù)集合工具類腔召,如SparseArray臀蛛、SparseBooleanArray、LongSparseArray豫领,使用這些API可以讓我們的程序更加高效洲劣。HashMap工具類會相對比較低效囱稽,因為它需要為每一個鍵值對都提供一個對象入口,而SparseArray就避免掉了基本數(shù)據(jù)類型轉(zhuǎn)換成對象數(shù)據(jù)類型的時間吞获。?
Bitmap優(yōu)化:讀取一個Bitmap圖片的時候衫哥,千萬不要去加載不需要的分辨率∥萌伲可以壓縮圖片等操作奢入。???
盡量避免使用依賴注入框架腥光。
避免創(chuàng)作不必要的對象:字符串拼接使用StringBuffer,StringBuilder捉片。
onDraw方法里面不要執(zhí)行對象的創(chuàng)建.
重寫onTrimMemory,根據(jù)傳入的參數(shù)莹规,進(jìn)行內(nèi)存釋放。
使用static final 優(yōu)化成員變量债热。?
移動端獲取網(wǎng)絡(luò)數(shù)據(jù)優(yōu)化的幾個點
連接復(fù)用:節(jié)省連接建立時間窒篱,如開啟 keep-alive。對于Android來說默認(rèn)情況下HttpURLConnection和HttpClient都開啟了keep-alive高镐。只是2.2之前HttpURLConnection存在影響連接池的Bug观腊,具體可見:Android HttpURLConnection及HttpClient選擇
請求合并:即將多個請求合并為一個進(jìn)行請求梧油,比較常見的就是網(wǎng)頁中的CSS Image Sprites。如果某個頁面內(nèi)請求過多量淌,也可以考慮做一定的請求合并骗村。
減少請求數(shù)據(jù)的大小:對于post請求呀枢,body可以做gzip壓縮的胚股,header也可以做數(shù)據(jù)壓縮(不過只支持http 2.0)。返回數(shù)據(jù)的body也可以做gzip壓縮硫狞,body數(shù)據(jù)體積可以縮小到原來的30%左右。(也可以考慮壓縮返回的json數(shù)據(jù)的key數(shù)據(jù)的體積晃痴,尤其是針對返回數(shù)據(jù)格式變化不大的情況倘核,支付寶聊天返回的數(shù)據(jù)用到了)根據(jù)用戶的當(dāng)前的網(wǎng)絡(luò)質(zhì)量來判斷下載什么質(zhì)量的圖片(電商用的比較多)
高級
Android系統(tǒng)啟動過程蛹锰,App啟動過程]從桌面點擊到activity啟動的過程
1.Launcher線程捕獲onclick的點擊事件,調(diào)用Launcher.startActivitySafely,進(jìn)一步調(diào)用Launcher.startActivity,最后調(diào)用父類Activity的startActivity。
2.Activity和ActivityManagerService交互痘儡,引入Instrumentation砖茸,將啟動請求交給Instrumentation,調(diào)用Instrumentation.execStartActivity人柿。
3.調(diào)用ActivityManagerService的startActivity方法,這里做了進(jìn)程切換(具體過程請查看源碼)。
4.開啟Activity宰掉,調(diào)用onCreate方法
熱布丁原因:因為一個dvm中存儲方法id用的是short類型挨务,導(dǎo)致dex中方法不能超過65536個原理:將編譯好的class文件拆分打包成兩個dex,繞過dex方法數(shù)量的限制以及安裝時的檢查筷黔,在運行時再動態(tài)加載第二個dex文件中粟矿。使用Dexclassloader。
動態(tài)加載(也叫插件化技術(shù))動態(tài)加載主要解決3個技術(shù)問題:1诈豌,使用ClassLoader加載類。2员魏,資源訪問。3晰韵,生命周期管理休涤。?
參考1、Android熱補(bǔ)丁動態(tài)修復(fù)技術(shù)系列 2、Android 利用 APT 技術(shù)在編譯期生成代碼3、Android中的動態(tài)加載機(jī)制 4、掌閱 Android App 插件補(bǔ)丁實踐 (ZeusPlugin)5魏身、插件化開發(fā)從入門到深入6涵但、Android Hotfix 新方案——Amigo 源碼解讀(from diycode) 【更新于2016年9月2號】7棘催、插件化由理論到實踐【更新于2016年9月3日】8Android插件化原理解析9 Android動態(tài)加載技術(shù)三個關(guān)鍵問題詳解10 Android apk動態(tài)加載機(jī)制的研究
Binder機(jī)制
跨進(jìn)程間通信(IPC):四大組件之間通過Intent互相跳轉(zhuǎn)淫僻,Android實現(xiàn)IPC的方式是binder機(jī)制坚踩。
android中的跨進(jìn)程通信的實現(xiàn)(一)——遠(yuǎn)程調(diào)用過程和aidlAndroid中的Binder機(jī)制的簡要理解Android中的Binder機(jī)制的簡要理解二
Android系統(tǒng)的架構(gòu)?
屏幕快照 2016-09-07 上午9.26.57.png
android的系統(tǒng)架構(gòu)和其操作系統(tǒng)一樣豆瘫,采用了分層的架構(gòu)蒋譬。從架構(gòu)圖看附井,android分為四個層,從高層到低層分別是應(yīng)用程序?qū)酉敢啤?yīng)用程序框架層、系統(tǒng)運行庫層和linux核心層〖衿 1.應(yīng)用程序 Android會同一系列核心應(yīng)用程序包一起發(fā)布彤避,該應(yīng)用程序包包括email客戶端昙楚,SMS短消息程序挂捅,日歷,地圖无蜂,瀏覽器伺糠,聯(lián)系人管理程序等。所有的應(yīng)用程序都是使用JAVA語言編寫的斥季⊙低埃 2.應(yīng)用程序框架 開發(fā)人員也可以完全訪問核心應(yīng)用程序所使用的API框架。該應(yīng)用程序的架構(gòu)設(shè)計簡化了組件的重用;任何一個應(yīng)用程序都可以發(fā)布它的功能塊并且任何其它的應(yīng)用程序都可以使用其所發(fā)布的功能塊(不過得遵循框架的安全性限制)酣倾。同樣舵揭,該應(yīng)用程序重用機(jī)制也使用戶可以方便的替換程序組件≡晡 隱藏在每個應(yīng)用后面的是一系列的服務(wù)和系統(tǒng), 其中包括; 豐富而又可擴(kuò)展的視圖(Views)午绳,可以用來構(gòu)建應(yīng)用程序, 它包括列表(lists)映之,網(wǎng)格(grids)拦焚,文本框(text boxes),按鈕(buttons)杠输, 甚至可嵌入的web瀏覽器赎败。
內(nèi)容提供器(Content Providers)使得應(yīng)用程序可以訪問另一個應(yīng)用程序的數(shù)據(jù)(如聯(lián)系人數(shù)據(jù)庫), 或者共享它們自己的數(shù)據(jù) 資源管理器(Resource Manager)提供 非代碼資源的訪問蠢甲,如本地字符串螟够,圖形,和布局文件( layout files )峡钓。
通知管理器 (Notification Manager) 使得應(yīng)用程序可以在狀態(tài)欄中顯示自定義的提示信息妓笙。 * 活動管理器( Activity Manager) 用來管理應(yīng)用程序生命周期并提供常用的導(dǎo)航回退功能能岩∧ 有關(guān)更多的細(xì)節(jié)和怎樣從頭寫一個應(yīng)用程序,請參考 如何編寫一個 Android 應(yīng)用程序.?
3.系統(tǒng)運行庫 1)程序庫 Android 包含一些C/C++庫拉鹃,這些庫能被Android系統(tǒng)中不同的組件使用辈赋。它們通過 Android 應(yīng)用程序框架為開發(fā)者提供服務(wù)鲫忍。以下是一些核心庫: 系統(tǒng) C 庫 - 一個從 BSD 繼承來的標(biāo)準(zhǔn) C 系統(tǒng)函數(shù)庫( libc ), 它是專門為基于 embedded linux 的設(shè)備定制的钥屈∥蛎瘢 媒體庫 - 基于 PacketVideo OpenCORE;該庫支持多種常用的音頻、視頻格式回放和錄制篷就,同時支持靜態(tài)圖像文件射亏。編碼格式包括MPEG4, H.264, MP3, AAC, AMR, JPG, PNG 〗咭担 Surface Manager - 對顯示子系統(tǒng)的管理智润,并且為多個應(yīng)用程序提 供了2D和3D圖層的無縫融合∥戳荆 ? LibWebCore - 一個最新的web瀏覽器引擎用窟绷,支持Android瀏覽器和一個可嵌入的web視圖「拦瘢 SGL- 底層的2D圖形引擎 3D libraries - 基于OpenGL ES 1.0 APIs實現(xiàn);該庫可以使用硬件 3D加速(如果可用)或者使用高度優(yōu)化的3D軟加速兼蜈。 FreeType -位圖(bitmap)和矢量(vector)字體顯示拙友∥辏 SQLite - 一個對于所有應(yīng)用程序可用,功能強(qiáng)勁的輕型關(guān)系型數(shù)據(jù)庫引擎献宫≡科剑 2)Android 運行庫 Android 包括了一個核心庫,該核心庫提供了JAVA編程語言核心庫的大多數(shù)功能姊途∩骜 每一個Android應(yīng)用程序都在它自己的進(jìn)程中運行,都擁有一個獨立的Dalvik虛擬機(jī)實例捷兰。Dalvik被設(shè)計成一個設(shè)備可以同時高效地運行多個虛擬系統(tǒng)立叛。 Dalvik虛擬機(jī)執(zhí)行(.dex)的Dalvik可執(zhí)行文件,該格式文件針對小內(nèi)存使用做了優(yōu)化贡茅。同時虛擬機(jī)是基于寄存器的秘蛇,所有的類都經(jīng)由JAVA編譯器編譯,然后通過SDK中 的 “dx” 工具轉(zhuǎn)化成.dex格式由虛擬機(jī)執(zhí)行顶考×藁梗 Dalvik虛擬機(jī)依賴于linux內(nèi)核的一些功能,比如線程機(jī)制和底層內(nèi)存管理機(jī)制驹沿∷也撸 *4.Linux 內(nèi)核**Android 的核心系統(tǒng)服務(wù)依賴于 Linux 2.6 內(nèi)核,如安全性渊季,內(nèi)存管理朋蔫,進(jìn)程管理罚渐, 網(wǎng)絡(luò)協(xié)議棧和驅(qū)動模型。 Linux 內(nèi)核也同時作為硬件和軟件棧之間的抽象層驯妄。