wordpress 音樂下載主題seo搜索引擎優(yōu)化實訓(xùn)總結(jié)
熟悉Android系統(tǒng)的童鞋都知道,系統(tǒng)出于體驗和性能上的考慮,app在退到后臺時系統(tǒng)并不會真正的kill掉這個進程,而是將其緩存起來。打開的應(yīng)用越多,后臺緩存的進程也越多。在系統(tǒng)內(nèi)存不足的情況下,系統(tǒng)開始依據(jù)自身的一套進程回收機制來判斷要kill掉哪些進程,以騰出內(nèi)存來供給需要的app。這套殺進程回收內(nèi)存的機制就叫 Low Memory Killer ,它是基于Linux內(nèi)核的 OOM Killer(Out-Of-Memory killer)機制誕生。
- 進程的重要性,劃分5級:-
- 前臺進程 (Foreground process)
- 可見進程 (Visible process)
- 服務(wù)進程 (Service process)
- 后臺進程 (Background process)
- 空進程 (Empty process)
了解完 Low Memory Killer,再科普一下oom_adj。什么是oom_adj?它是linux內(nèi)核分配給每個系統(tǒng)進程的一個值,代表進程的優(yōu)先級,進程回收機制就是根據(jù)這個優(yōu)先級來決定是否進行回收。對于oom_adj的作用,你只需要記住以下幾點即可:
進程的oom_adj越大,表示此進程優(yōu)先級越低,越容易被殺回收;越小,表示進程優(yōu)先級越高,越不容易被殺回收
普通app進程的oom_adj>=0,系統(tǒng)進程的oom_adj才可能<0
有些手機廠商把這些知名的app放入了自己的白名單中,保證了進程不死來提高用戶體驗(如微信、QQ、陌陌都在小米的白名單中)。如果從白名單中移除,他們終究還是和普通app一樣躲避不了被殺的命運,為了盡量避免被殺,還是老老實實去做好優(yōu)化工作吧。
所以,進程保活的根本方案終究還是回到了性能優(yōu)化上,進程永生不死終究是個徹頭徹尾的偽命題!
8、講解一下Context
Context是一個抽象基類。在翻譯為上下文,也可以理解為環(huán)境,是提供一些程序的運行環(huán)境基礎(chǔ)信息。Context下有兩個子類,ContextWrapper是上下文功能的封裝類,而ContextImpl則是上下文功能的實現(xiàn)類。而ContextWrapper又有三個直接的子類, ContextThemeWrapper、Service和Application。其中,ContextThemeWrapper是一個帶主題的封裝類,而它有一個直接子類就是Activity,所以Activity和Service以及Application的Context是不一樣的,只有Activity需要主題,Service不需要主題。Context一共有三種類型,分別是Application、Activity和Service。這三個類雖然分別各種承擔(dān)著不同的作用,但它們都屬于Context的一種,而它們具體Context的功能則是由ContextImpl類去實現(xiàn)的,因此在絕大多數(shù)場景下,Activity、Service和Application這三種類型的Context都是可以通用的。不過有幾種場景比較特殊,比如啟動Activity,還有彈出Dialog。出于安全原因的考慮,Android是不允許Activity或Dialog憑空出現(xiàn)的,一個Activity的啟動必須要建立在另一個Activity的基礎(chǔ)之上,也就是以此形成的返回棧。而Dialog則必須在一個Activity上面彈出(除非是System Alert類型的Dialog),因此在這種場景下,我們只能使用Activity類型的Context,否則將會出錯。
getApplicationContext()和getApplication()方法得到的對象都是同一個application對象,只是對象的類型不一樣。
Context數(shù)量 = Activity數(shù)量 + Service數(shù)量 + 1 (1為Application)
9、理解Activity,View,Window三者關(guān)系
這個問題真的很不好回答。所以這里先來個算是比較恰當(dāng)?shù)谋扔鱽硇稳菹滤鼈兊年P(guān)系吧。Activity像一個工匠(控制單元),Window像窗戶(承載模型),View像窗花(顯示視圖)LayoutInflater像剪刀,Xml配置像窗花圖紙。
- 1:Activity構(gòu)造的時候會初始化一個Window,準確的說是PhoneWindow。
- 2:這個PhoneWindow有一個“ViewRoot”,這個“ViewRoot”是一個View或者說ViewGroup,是最初始的根視圖。
- 3:“ViewRoot”通過addView方法來一個個的添加View。比如TextView,Button等
- 4:這些View的事件監(jiān)聽,是由WindowManagerService來接受消息,并且回調(diào)Activity函數(shù)。比如onClickListener,onKeyDown等。
10、四種LaunchMode及其使用場景
此處延伸:棧(First In Last Out)與隊列(First In First Out)的區(qū)別
棧與隊列的區(qū)別:
- 隊列先進先出,棧先進后出
\2. 對插入和刪除操作的”限定”。 棧是限定只能在表的一端進行插入和刪除操作的線性表。 隊列是限定只能在表的一端進行插入和在另一端進行刪除操作的線性表。
\3. 遍歷數(shù)據(jù)速度不同
standard 模式
這是默認模式,每次激活A(yù)ctivity時都會創(chuàng)建Activity實例,并放入任務(wù)棧中。使用場景:大多數(shù)Activity。
- singleTop 模式
如果在任務(wù)的棧頂正好存在該Activity的實例,就重用該實例( 會調(diào)用實例的 onNewIntent() ),否則就會創(chuàng)建新的實例并放入棧頂,即使棧中已經(jīng)存在該Activity的實例,只要不在棧頂,都會創(chuàng)建新的實例。使用場景如新聞類或者閱讀類App的內(nèi)容頁面。
- singleTask 模式
如果在棧中已經(jīng)有該Activity的實例,就重用該實例(會調(diào)用實例的 onNewIntent() )。重用時,會讓該實例回到棧頂,因此在它上面的實例將會被移出棧。如果棧中不存在該實例,將會創(chuàng)建新的實例放入棧中。使用場景如瀏覽器的主界面。不管從多少個應(yīng)用啟動瀏覽器,只會啟動主界面一次,其余情況都會走onNewIntent,并且會清空主界面上面的其他頁面。
- singleInstance 模式
在一個新棧中創(chuàng)建該Activity的實例,并讓多個應(yīng)用共享該棧中的該Activity實例。一旦該模式的Activity實例已經(jīng)存在于某個棧中,任何應(yīng)用再激活該Activity時都會重用該棧中的實例( 會調(diào)用實例的 onNewIntent() )。其效果相當(dāng)于多個應(yīng)用共享一個應(yīng)用,不管誰激活該 Activity 都會進入同一個應(yīng)用中。使用場景如鬧鈴提醒,將鬧鈴提醒與鬧鈴設(shè)置分離。singleInstance不要用于中間頁面,如果用于中間頁面,跳轉(zhuǎn)會有問題,比如:A -> B (singleInstance) -> C,完全退出后,在此啟動,首先打開的是B。
11、View的繪制流程
自定義控件:
1、組合控件。這種自定義控件不需要我們自己繪制,而是使用原生控件組合成的新控件。如標題欄。
2、繼承原有的控件。這種自定義控件在原生控件提供的方法外,可以自己添加一些方法。如制作圓角,圓形圖片。
3、完全自定義控件:這個View上所展現(xiàn)的內(nèi)容全部都是我們自己繪制出來的。比如說制作水波紋進度條。
View的繪制流程:OnMeasure()——>OnLayout()——>OnDraw()
第一步:OnMeasure():測量視圖大小。從頂層父View到子View遞歸調(diào)用measure方法,measure方法又回調(diào)OnMeasure。
第二步:OnLayout():確定View位置,進行頁面布局。從頂層父View向子View的遞歸調(diào)用view.layout方法的過程,即父View根據(jù)上一步measure子View所得到的布局大小和布局參數(shù),將子View放在合適的位置上。
第三步:OnDraw():繪制視圖。ViewRoot創(chuàng)建一個Canvas對象,然后調(diào)用OnDraw()。六個步驟:①、繪制視圖的背景;②、保存畫布的圖層(Layer);③、繪制View的內(nèi)容;④、繪制View子視圖,如果沒有就不用;
⑤、還原圖層(Layer);⑥、繪制滾動條。
12、View,ViewGroup事件分發(fā)
\1. Touch事件分發(fā)中只有兩個主角:ViewGroup和View。ViewGroup包含onInterceptTouchEvent、dispatchTouchEvent、onTouchEvent三個相關(guān)事件。View包含dispatchTouchEvent、onTouchEvent兩個相關(guān)事件。其中ViewGroup又繼承于View。
2.ViewGroup和View組成了一個樹狀結(jié)構(gòu),根節(jié)點為Activity內(nèi)部包含的一個ViwGroup。
3.觸摸事件由Action_Down、Action_Move、Aciton_UP組成,其中一次完整的觸摸事件中,Down和Up都只有一個,Move有若干個,可以為0個。
4.當(dāng)Acitivty接收到Touch事件時,將遍歷子View進行Down事件的分發(fā)。ViewGroup的遍歷可以看成是遞歸的。分發(fā)的目的是為了找到真正要處理本次完整觸摸事件的View,這個View會在onTouchuEvent結(jié)果返回true。
5.當(dāng)某個子View返回true時,會中止Down事件的分發(fā),同時在ViewGroup中記錄該子View。接下去的Move和Up事件將由該子View直接進行處理。由于子View是保存在ViewGroup中的,多層ViewGroup的節(jié)點結(jié)構(gòu)時,上級ViewGroup保存的會是真實處理事件的View所在的ViewGroup對象:如ViewGroup0-ViewGroup1-TextView的結(jié)構(gòu)中,TextView返回了true,它將被保存在ViewGroup1中,而ViewGroup1也會返回true,被保存在ViewGroup0中。當(dāng)Move和UP事件來時,會先從ViewGroup0傳遞至ViewGroup1,再由ViewGroup1傳遞至TextView。
6.當(dāng)ViewGroup中所有子View都不捕獲Down事件時,將觸發(fā)ViewGroup自身的onTouch事件。觸發(fā)的方式是調(diào)用super.dispatchTouchEvent函數(shù),即父類View的dispatchTouchEvent方法。在所有子View都不處理的情況下,觸發(fā)Acitivity的onTouchEvent方法。
7.onInterceptTouchEvent有兩個作用:1.攔截Down事件的分發(fā)。2.中止Up和Move事件向目標View傳遞,使得目標View所在的ViewGroup捕獲Up和Move事件。
13、保存Activity狀態(tài)
onSaveInstanceState(Bundle)會在activity轉(zhuǎn)入后臺狀態(tài)之前被調(diào)用,也就是onStop()方法之前,onPause方法之后被調(diào)用;
14、Android中的幾種動畫
幀動畫:指通過指定每一幀的圖片和播放時間,有序的進行播放而形成動畫效果,比如想聽的律動條。
補間動畫:指通過指定View的初始狀態(tài)、變化時間、方式,通過一系列的算法去進行圖形變換,從而形成動畫效果,主要有Alpha、Scale、Translate、Rotate四種效果。注意:只是在視圖層實現(xiàn)了動畫效果,并沒有真正改變View的屬性,比如滑動列表,改變標題欄的透明度。
屬性動畫:在Android3.0的時候才支持,通過不斷的改變View的屬性,不斷的重繪而形成動畫效果。相比于視圖動畫,View的屬性是真正改變了。比如view的旋轉(zhuǎn),放大,縮小。
15、Android中跨進程通訊的幾種方式
Android 跨進程通信,像intent,contentProvider,廣播,service都可以跨進程通信。
intent:這種跨進程方式并不是訪問內(nèi)存的形式,它需要傳遞一個uri,比如說打電話。
contentProvider:這種形式,是使用數(shù)據(jù)共享的形式進行數(shù)據(jù)共享。
service:遠程服務(wù),aidl
廣播
16、AIDL理解
此處延伸:簡述Binder
AIDL: 每一個進程都有自己的Dalvik VM實例,都有自己的一塊獨立的內(nèi)存,都在自己的內(nèi)存上存儲自己的數(shù)據(jù),執(zhí)行著自己的操作,都在自己的那片狹小的空間里過完自己的一生。而aidl就類似與兩個進程之間的橋梁,使得兩個進程之間可以進行數(shù)據(jù)的傳輸,跨進程通信有多種選擇,比如 BroadcastReceiver , Messenger 等,但是 BroadcastReceiver 占用的系統(tǒng)資源比較多,如果是頻繁的跨進程通信的話顯然是不可取的;Messenger 進行跨進程通信時請求隊列是同步進行的,無法并發(fā)執(zhí)行。
Binde機制簡單理解:
在Android系統(tǒng)的Binder機制中,是有Client,Service,ServiceManager,Binder驅(qū)動程序組成的,其中Client,service,Service Manager運行在用戶空間,Binder驅(qū)動程序是運行在內(nèi)核空間的。而Binder就是把這4種組件粘合在一塊的粘合劑,其中核心的組件就是Binder驅(qū)動程序,Service Manager提供輔助管理的功能,而Client和Service正是在Binder驅(qū)動程序和Service Manager提供的基礎(chǔ)設(shè)施上實現(xiàn)C/S 之間的通信。其中Binder驅(qū)動程序提供設(shè)備文件/dev/binder與用戶控件進行交互,
Client、Service,Service Manager通過open和ioctl文件操作相應(yīng)的方法與Binder驅(qū)動程序進行通信。而Client和Service之間的進程間通信是通過Binder驅(qū)動程序間接實現(xiàn)的。而Binder Manager是一個守護進程,用來管理Service,并向Client提供查詢Service接口的能力。
17、Handler的原理
Android中主線程是不能進行耗時操作的,子線程是不能進行更新UI的。所以就有了handler,它的作用就是實現(xiàn)線程之間的通信。
handler整個流程中,主要有四個對象,handler,Message,MessageQueue,Looper。當(dāng)應(yīng)用創(chuàng)建的時候,就會在主線程中創(chuàng)建handler對象,
我們通過要傳送的消息保存到Message中,handler通過調(diào)用sendMessage方法將Message發(fā)送到MessageQueue中,Looper對象就會不斷的調(diào)用loop()方法
不斷的從MessageQueue中取出Message交給handler進行處理。從而實現(xiàn)線程之間的通信。
18、Binder機制原理
在Android系統(tǒng)的Binder機制中,是有Client,Service,ServiceManager,Binder驅(qū)動程序組成的,其中Client,service,Service Manager運行在用戶空間,Binder驅(qū)動程序是運行在內(nèi)核空間的。而Binder就是把這4種組件粘合在一塊的粘合劑,其中核心的組件就是Binder驅(qū)動程序,Service Manager提供輔助管理的功能,而Client和Service正是在Binder驅(qū)動程序和Service Manager提供的基礎(chǔ)設(shè)施上實現(xiàn)C/S 之間的通信。其中Binder驅(qū)動程序提供設(shè)備文件/dev/binder與用戶控件進行交互,Client、Service,Service Manager通過open和ioctl文件操作相應(yīng)的方法與Binder驅(qū)動程序進行通信。而Client和Service之間的進程間通信是通過Binder驅(qū)動程序間接實現(xiàn)的。而Binder Manager是一個守護進程,用來管理Service,并向Client提供查詢Service接口的能力。
19、熱修復(fù)的原理
我們知道Java虛擬機 —— JVM 是加載類的class文件的,而Android虛擬機——Dalvik/ART VM 是加載類的dex文件,
而他們加載類的時候都需要ClassLoader,ClassLoader有一個子類BaseDexClassLoader,而BaseDexClassLoader下有一個
數(shù)組——DexPathList,是用來存放dex文件,當(dāng)BaseDexClassLoader通過調(diào)用findClass方法時,實際上就是遍歷數(shù)組,
找到相應(yīng)的dex文件,找到,則直接將它return。而熱修復(fù)的解決方法就是將新的dex添加到該集合中,并且是在舊的dex的前面,
所以就會優(yōu)先被取出來并且return返回。
20、Android內(nèi)存泄露及管理
- (1)內(nèi)存溢出(OOM)和內(nèi)存泄露(對象無法被回收)的區(qū)別。
- (2)引起內(nèi)存泄露的原因
(3) 內(nèi)存泄露檢測工具 ——→LeakCanary
內(nèi)存溢出 out of memory:是指程序在申請內(nèi)存時,沒有足夠的內(nèi)存空間供其使用,出現(xiàn)out of memory;比如申請了一個integer,但給它存了long才能存下的數(shù),那就是內(nèi)存溢出。內(nèi)存溢出通俗的講就是內(nèi)存不夠用。
內(nèi)存泄露 memory leak:是指程序在申請內(nèi)存后,無法釋放已申請的內(nèi)存空間,一次內(nèi)存泄露危害可以忽略,但內(nèi)存泄露堆積后果很嚴重,無論多少內(nèi)存,遲早會被占光
內(nèi)存泄露原因:
一、Handler 引起的內(nèi)存泄漏。
解決:將Handler聲明為靜態(tài)內(nèi)部類,就不會持有外部類SecondActivity的引用,其生命周期就和外部類無關(guān),
如果Handler里面需要context的話,可以通過弱引用方式引用外部類
二、單例模式引起的內(nèi)存泄漏。
解決:Context是ApplicationContext,由于ApplicationContext的生命周期是和app一致的,不會導(dǎo)致內(nèi)存泄漏
三、非靜態(tài)內(nèi)部類創(chuàng)建靜態(tài)實例引起的內(nèi)存泄漏。
解決:把內(nèi)部類修改為靜態(tài)的就可以避免內(nèi)存泄漏了
四、非靜態(tài)匿名內(nèi)部類引起的內(nèi)存泄漏。
解決:將匿名內(nèi)部類設(shè)置為靜態(tài)的。
五、注冊/反注冊未成對使用引起的內(nèi)存泄漏。
注冊廣播接受器、EventBus等,記得解綁。
六、資源對象沒有關(guān)閉引起的內(nèi)存泄漏。
在這些資源不使用的時候,記得調(diào)用相應(yīng)的類似close()、destroy()、recycler()、release()等方法釋放。
七、集合對象沒有及時清理引起的內(nèi)存泄漏。
通常會把一些對象裝入到集合中,當(dāng)不使用的時候一定要記得及時清理集合,讓相關(guān)對象不再被引用。
21、Fragment與Fragment、Activity通信的方式
- 1.直接在一個Fragment中調(diào)用另外一個Fragment中的方法
- 2.使用接口回調(diào)
- 3.使用廣播
- 4.Fragment直接調(diào)用Activity中的public方法
22、Android UI適配
字體使用sp,使用dp,多使用match_parent,wrap_content,weight
圖片資源,不同圖片的的分辨率,放在相應(yīng)的文件夾下可使用百分比代替。
23、app優(yōu)化
app優(yōu)化:(工具:Hierarchy Viewer 分析布局 工具:TraceView 測試分析耗時的)
- App啟動優(yōu)化
- 布局優(yōu)化
- 響應(yīng)優(yōu)化
- 內(nèi)存優(yōu)化
- 電池使用優(yōu)化
- 網(wǎng)絡(luò)優(yōu)化
App啟動優(yōu)化(針對冷啟動)
App啟動的方式有三種:
冷啟動:App沒有啟動過或App進程被killed, 系統(tǒng)中不存在該App進程, 此時啟動App即為冷啟動。
熱啟動:熱啟動意味著你的App進程只是處于后臺, 系統(tǒng)只是將其從后臺帶到前臺, 展示給用戶。
介于冷啟動和熱啟動之間, 一般來說在以下兩種情況下發(fā)生:
- (1)用戶back退出了App, 然后又啟動. App進程可能還在運行, 但是activity需要重建。
- (2)用戶退出App后, 系統(tǒng)可能由于內(nèi)存原因?qū)pp殺死, 進程和activity都需要重啟, 但是可以在onCreate中將被動殺死鎖保存的狀態(tài)(saved instance state)恢復(fù)。
優(yōu)化:
Application的onCreate(特別是第三方SDK初始化),首屏Activity的渲染都不要進行耗時操作,如果有,就可以放到子線程或者IntentService中
布局優(yōu)化
盡量不要過于復(fù)雜的嵌套??梢允褂?#xff0c;,
響應(yīng)優(yōu)化
Android系統(tǒng)每隔16ms會發(fā)出VSYNC信號重繪我們的界面(Activity)。
頁面卡頓的原因:
- (1)過于復(fù)雜的布局.
- (2)UI線程的復(fù)雜運算
- (3)頻繁的GC,導(dǎo)致頻繁GC有兩個原因:1、內(nèi)存抖動, 即大量的對象被創(chuàng)建又在短時間內(nèi)馬上被釋放.2、瞬間產(chǎn)生大量的對象會嚴重占用內(nèi)存區(qū)域。
內(nèi)存優(yōu)化:參考內(nèi)存泄露和內(nèi)存溢出部分
電池使用優(yōu)化(使用工具:Batterystats & bugreport)
- (1)優(yōu)化網(wǎng)絡(luò)請求
- (2)定位中使用GPS, 請記得及時關(guān)閉
網(wǎng)絡(luò)優(yōu)化(網(wǎng)絡(luò)連接對用戶的影響:流量,電量,用戶等待)可在Android studio下方logcat旁邊那個工具Network Monitor檢測
- API設(shè)計:App與Server之間的API設(shè)計要考慮網(wǎng)絡(luò)請求的頻次, 資源的狀態(tài)等. 以便App可以以較少的請求來完成業(yè)務(wù)需求和界面的展示.
- Gzip壓縮:使用Gzip來壓縮request和response, 減少傳輸數(shù)據(jù)量, 從而減少流量消耗.
- 圖片的Size:可以在獲取圖片時告知服務(wù)器需要的圖片的寬高, 以便服務(wù)器給出合適的圖片, 避免浪費.
- 網(wǎng)絡(luò)緩存:適當(dāng)?shù)木彺? 既可以讓我們的應(yīng)用看起來更快, 也能避免一些不必要的流量消耗.
24、圖片優(yōu)化
- (1)對圖片本身進行操作。盡量不要使用setImageBitmap、setImageResource、BitmapFactory.decodeResource來設(shè)置一張大圖,因為這些方法在完成decode后,
最終都是通過java層的createBitmap來完成的,需要消耗更多內(nèi)存.
- (2)圖片進行縮放的比例,SDK中建議其值是2的指數(shù)值,值越大會導(dǎo)致圖片不清晰。
- (3)不用的圖片記得調(diào)用圖片的recycle()方法
25、HybridApp WebView和JS交互
Android與JS通過WebView互相調(diào)用方法,實際上是:
Android去調(diào)用JS的代碼
- \1. 通過WebView的loadUrl(),使用該方法比較簡潔,方便。但是效率比較低,獲取返回值比較困難。
- \2. 通過WebView的evaluateJavascript(),該方法效率高,但是4.4以上的版本才支持,4.4以下版本不支持。所以建議兩者混合使用。
JS去調(diào)用Android的代碼
\1. 通過WebView的addJavascriptInterface()進行對象映射 ,該方法使用簡單,僅將Android對象和JS對象映射即可,但是存在比較大的漏洞。
漏洞產(chǎn)生原因是:當(dāng)JS拿到Android這個對象后,就可以調(diào)用這個Android對象中所有的方法,包括系統(tǒng)類(java.lang.Runtime 類),從而進行任意代碼執(zhí)行。
解決方式:
- (1)Google 在Android 4.2 版本中規(guī)定對被調(diào)用的函數(shù)以 @JavascriptInterface進行注解從而避免漏洞攻擊。
- (2)在Android 4.2版本之前采用攔截prompt()進行漏洞修復(fù)。
\2. 通過 WebViewClient 的shouldOverrideUrlLoading ()方法回調(diào)攔截 url 。這種方式的優(yōu)點:不存在方式1的漏洞;缺點:JS獲取Android方法的返回值復(fù)雜。(ios主要用的是這個方式)
- (1)Android通過 WebViewClient 的回調(diào)方法shouldOverrideUrlLoading ()攔截 url
- (2)解析該 url 的協(xié)議
- (3)如果檢測到是預(yù)先約定好的協(xié)議,就調(diào)用相應(yīng)方法
\3. 通過 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回調(diào)攔截JS對話框alert()、confirm()、prompt() 消息
這種方式的優(yōu)點:不存在方式1的漏洞;缺點:JS獲取Android方法的返回值復(fù)雜。
26、JAVA GC原理
垃圾收集算法的核心思想是:對虛擬機可用內(nèi)存空間,即堆空間中的對象進行識別,如果對象正在被引用,那么稱其為存活對象
,反之,如果對象不再被引用,則為垃圾對象,可以回收其占據(jù)的空間,用于再分配。垃圾收集算法的選擇和垃圾收集系統(tǒng)參數(shù)的合理調(diào)節(jié)直接影響著系統(tǒng)性能。
27、ANR
ANR全名Application Not Responding, 也就是”應(yīng)用無響應(yīng)”. 當(dāng)操作在一段時間內(nèi)系統(tǒng)無法處理時, 系統(tǒng)層面會彈出上圖那樣的ANR對話框.
產(chǎn)生原因:
- (1)5s內(nèi)無法響應(yīng)用戶輸入事件(例如鍵盤輸入, 觸摸屏幕等).
- (2)BroadcastReceiver在10s內(nèi)無法結(jié)束
- (3)Service 20s內(nèi)無法結(jié)束(低概率)
解決方式:
- (1)不要在主線程中做耗時的操作,而應(yīng)放在子線程中來實現(xiàn)。如onCreate()和onResume()里盡可能少的去做創(chuàng)建操作。
- (2)應(yīng)用程序應(yīng)該避免在BroadcastReceiver里做耗時的操作或計算。
- (3)避免在Intent Receiver里啟動一個Activity,因為它會創(chuàng)建一個新的畫面,并從當(dāng)前用戶正在運行的程序上搶奪焦點。
- (4)service是運行在主線程的,所以在service中做耗時操作,必須要放在子線程中。
28、設(shè)計模式
此處延伸:Double Check的寫法被要求寫出來。
單例模式:分為惡漢式和懶漢式
餓漢式:
public class Singleton
{
private static Singleton instance = new Singleton();
public static Singleton getInstance()
{
return instance ;
}
}
懶漢式:
public class Singleton02
{
private static Singleton02 instance;
public static Singleton02 getInstance()
{
if (instance == null)
{
synchronized (Singleton02.class)
{
if (instance == null)
{
instance = new Singleton02();
}
}
}
return instance;
}
}
29、RxJava
30、MVP,MVC,MVVM
此處延伸:手寫mvp例子,與mvc之間的區(qū)別,mvp的優(yōu)勢
MVP模式,對應(yīng)著Model—業(yè)務(wù)邏輯和實體模型,view—對應(yīng)著activity,負責(zé)View的繪制以及與用戶交互,Presenter—負責(zé)View和Model之間的交互,MVP模式是在MVC模式的基礎(chǔ)上,將Model與View徹底分離使得項目的耦合性更低,在Mvc中項目中的activity對應(yīng)著mvc中的C—Controllor,而項目中的邏輯處理都是在這個C中處理,同時View與Model之間的交互,也是也就是說,mvc中所有的邏輯交互和用戶交互,都是放在Controllor中,也就是activity中。View和model是可以直接通信的。而MVP模式則是分離的更加徹底,分工更加明確Model—業(yè)務(wù)邏輯和實體模型,view—負責(zé)與用戶交互,Presenter 負責(zé)完成View于Model間的交互,MVP和MVC最大的區(qū)別是MVC中是允許Model和View進行交互的,而MVP中很明顯,Model與View之間的交互由Presenter完成。還有一點就是Presenter與View之間的交互是通過接口的
31、手寫算法(選擇冒泡必須要會)
32、JNI
- (1)安裝和下載Cygwin,下載 Android NDK
- (2)在ndk項目中JNI接口的設(shè)計
- (3)使用C/C++實現(xiàn)本地方法
- (4)JNI生成動態(tài)鏈接庫.so文件
- (5)將動態(tài)鏈接庫復(fù)制到j(luò)ava工程,在java工程中調(diào)用,運行java工程即可
33、RecyclerView和ListView的區(qū)別
RecyclerView可以完成ListView,GridView的效果,還可以完成瀑布流的效果。同時還可以設(shè)置列表的滾動方向(垂直或者水平);
RecyclerView中view的復(fù)用不需要開發(fā)者自己寫代碼,系統(tǒng)已經(jīng)幫封裝完成了。
RecyclerView可以進行局部刷新。
RecyclerView提供了API來實現(xiàn)item的動畫效果。
在性能上:
如果需要頻繁的刷新數(shù)據(jù),需要添加動畫,則RecyclerView有較大的優(yōu)勢。
如果只是作為列表展示,則兩者區(qū)別并不是很大。
34、Universal-ImageLoader,Picasso,Fresco,Glide對比
Fresco 是 Facebook 推出的開源圖片緩存工具,主要特點包括:兩個內(nèi)存緩存加上 Native 緩存構(gòu)成了三級緩存,
優(yōu)點:
- \1. 圖片存儲在安卓系統(tǒng)的匿名共享內(nèi)存, 而不是虛擬機的堆內(nèi)存中, 圖片的中間緩沖數(shù)據(jù)也存放在本地堆內(nèi)存, 所以, 應(yīng)用程序有更多的內(nèi)存使用, 不會因為圖片加載而導(dǎo)致oom, 同時也減少垃圾回收器頻繁調(diào)用回收 Bitmap 導(dǎo)致的界面卡頓, 性能更高。
- \2. 漸進式加載 JPEG 圖片, 支持圖片從模糊到清晰加載。
- \3. 圖片可以以任意的中心點顯示在 ImageView, 而不僅僅是圖片的中心。
- \4. JPEG 圖片改變大小也是在 native 進行的, 不是在虛擬機的堆內(nèi)存, 同樣減少 OOM。
- \5. 很好的支持 GIF 圖片的顯示。
缺點:
- \1. 框架較大, 影響 Apk 體積
- \2. 使用較繁瑣
Universal-ImageLoader:(估計由于HttpClient被Google放棄,作者就放棄維護這個框架)
優(yōu)點:
- 1.支持下載進度監(jiān)聽
- 2.可以在 View 滾動中暫停圖片加載,通過 PauseOnScrollListener 接口可以在 View 滾動中暫停圖片加載。
- 3.默認實現(xiàn)多種內(nèi)存緩存算法 這幾個圖片緩存都可以配置緩存算法,不過 ImageLoader 默認實現(xiàn)了較多緩存算法,如 Size 最大先刪除、使用最少先刪除、最近最少使用、先進先刪除、時間最長先刪除等。
- 4.支持本地緩存文件名規(guī)則定義
Picasso 優(yōu)點
- \1. 自帶統(tǒng)計監(jiān)控功能。支持圖片緩存使用的監(jiān)控,包括緩存命中率、已使用內(nèi)存大小、節(jié)省的流量等。
- 2.支持優(yōu)先級處理。每次任務(wù)調(diào)度前會選擇優(yōu)先級高的任務(wù),比如 App 頁面中 Banner 的優(yōu)先級高于 Icon 時就很適用。
- 3.支持延遲到圖片尺寸計算完成加載
- 4.支持飛行模式、并發(fā)線程數(shù)根據(jù)網(wǎng)絡(luò)類型而變。 手機切換到飛行模式或網(wǎng)絡(luò)類型變換時會自動調(diào)整線程池最大并發(fā)數(shù),比如 wifi 最大并發(fā)為 4,4g 為 3,3g 為 2。 這里 Picasso 根據(jù)網(wǎng)絡(luò)類型來決定最大并發(fā)數(shù),而不是 CPU 核數(shù)。
- 5.“無”本地緩存。無”本地緩存,不是說沒有本地緩存,而是 Picasso 自己沒有實現(xiàn),交給了 Square 的另外一個網(wǎng)絡(luò)庫 okhttp 去實現(xiàn),這樣的好處是可以通過請求 Response Header 中的 Cache-Control 及 Expired 控制圖片的過期時間。
Glide 優(yōu)點
- \1. 不僅僅可以進行圖片緩存還可以緩存媒體文件。Glide 不僅是一個圖片緩存,它支持 Gif、WebP、縮略圖。甚至是 Video,所以更該當(dāng)做一個媒體緩存。
- \2. 支持優(yōu)先級處理。
- \3. 與 Activity/Fragment 生命周期一致,支持 trimMemory。Glide 對每個 context 都保持一個 RequestManager,通過 FragmentTransaction 保持與 Activity/Fragment 生命周期一致,并且有對應(yīng)的 trimMemory 接口實現(xiàn)可供調(diào)用。
- \4. 支持 okhttp、Volley。Glide 默認通過 UrlConnection 獲取數(shù)據(jù),可以配合 okhttp 或是 Volley 使用。實際 ImageLoader、Picasso 也都支持 okhttp、Volley。
- \5. 內(nèi)存友好。Glide 的內(nèi)存緩存有個 active 的設(shè)計,從內(nèi)存緩存中取數(shù)據(jù)時,不像一般的實現(xiàn)用 get,而是用 remove,再將這個緩存數(shù)據(jù)放到一個 value 為軟引用的 activeResources map 中,并計數(shù)引用數(shù),在圖片加載完成后進行判斷,如果引用計數(shù)為空則回收掉。內(nèi)存緩存更小圖片,Glide 以 url、view_width、view_height、屏幕的分辨率等做為聯(lián)合 key,將處理后的圖片緩存在內(nèi)存緩存中,而不是原始圖片以節(jié)省大小與 Activity/Fragment 生命周期一致,支持 trimMemory。圖片默認使用默認 RGB_565 而不是 ARGB_888,雖然清晰度差些,但圖片更小,也可配置到 ARGB_888。
- 6.Glide 可以通過 signature 或不使用本地緩存支持 url 過期
42、Xutils, OKhttp, Volley, Retrofit對比
Xutils這個框架非常全面,可以進行網(wǎng)絡(luò)請求,可以進行圖片加載處理,可以數(shù)據(jù)儲存,還可以對view進行注解,使用這個框架非常方便,但是缺點也是非常明顯的,使用這個項目,會導(dǎo)致項目對這個框架依賴非常的嚴重,一旦這個框架出現(xiàn)問題,那么對項目來說影響非常大的。、
OKhttp:Android開發(fā)中是可以直接使用現(xiàn)成的api進行網(wǎng)絡(luò)請求的。就是使用HttpClient,HttpUrlConnection進行操作。okhttp針對Java和Android程序,封裝的一個高性能的http請求庫,支持同步,異步,而且okhttp又封裝了線程池,封裝了數(shù)據(jù)轉(zhuǎn)換,封裝了參數(shù)的使用,錯誤處理等。API使用起來更加的方便。但是我們在項目中使用的時候仍然需要自己在做一層封裝,這樣才能使用的更加的順手。
**Volley:**Volley是Google官方出的一套小而巧的異步請求庫,該框架封裝的擴展性很強,支持HttpClient、HttpUrlConnection, 甚至支持OkHttp,而且Volley里面也封裝了ImageLoader,所以如果你愿意你甚至不需要使用圖片加載框架,不過這塊功能沒有一些專門的圖片加載框架強大,對于簡單的需求可以使用,稍復(fù)雜點的需求還是需要用到專門的圖片加載框架。Volley也有缺陷,比如不支持post大數(shù)據(jù),所以不適合上傳文件。不過Volley設(shè)計的初衷本身也就是為頻繁的、數(shù)據(jù)量小的網(wǎng)絡(luò)請求而生。
**Retrofit:**Retrofit是Square公司出品的默認基于OkHttp封裝的一套RESTful網(wǎng)絡(luò)請求框架,RESTful是目前流行的一套api設(shè)計的風(fēng)格, 并不是標準。Retrofit的封裝可以說是很強大,里面涉及到一堆的設(shè)計模式,可以通過注解直接配置請求,可以使用不同的http客戶端,雖然默認是用http ,可以使用不同Json Converter 來序列化數(shù)據(jù),同時提供對RxJava的支持,使用Retrofit + OkHttp + RxJava + Dagger2 可以說是目前比較潮的一套框架,但是需要有比較高的門檻。
Volley VS OkHttp
Volley的優(yōu)勢在于封裝的更好,而使用OkHttp你需要有足夠的能力再進行一次封裝。而OkHttp的優(yōu)勢在于性能更高,因為 OkHttp基于NIO和Okio ,所以性能上要比 Volley更快。IO 和 NIO這兩個都是Java中的概念,如果我從硬盤讀取數(shù)據(jù),第一種方式就是程序一直等,數(shù)據(jù)讀完后才能繼續(xù)操作這種是最簡單的也叫阻塞式IO,還有一種是你讀你的,程序接著往下執(zhí)行,等數(shù)據(jù)處理完你再來通知我,然后再處理回調(diào)。而第二種就是 NIO 的方式,非阻塞式, 所以NIO當(dāng)然要比IO的性能要好了,而 Okio是 Square 公司基于IO和NIO基礎(chǔ)上做的一個更簡單、高效處理數(shù)據(jù)流的一個庫。理論上如果Volley和OkHttp對比的話,更傾向于使用 Volley,因為Volley內(nèi)部同樣支持使用OkHttp,這點OkHttp的性能優(yōu)勢就沒了, 而且 Volley 本身封裝的也更易用,擴展性更好些。
OkHttp VS Retrofit
毫無疑問,Retrofit 默認是基于 OkHttp 而做的封裝,這點來說沒有可比性,肯定首選 Retrofit。
Volley VS Retrofit
這兩個庫都做了不錯的封裝,但Retrofit解耦的更徹底,尤其Retrofit2.0出來,Jake對之前1.0設(shè)計不合理的地方做了大量重構(gòu), 職責(zé)更細分,而且Retrofit默認使用OkHttp,性能上也要比Volley占優(yōu)勢,再有如果你的項目如果采用了RxJava ,那更該使用 Retrofit 。所以這兩個庫相比,Retrofit更有優(yōu)勢,在能掌握兩個框架的前提下該優(yōu)先使用 Retrofit。但是Retrofit門檻要比Volley稍高些,要理解他的原理,各種用法,想徹底搞明白還是需要花些功夫的,如果你對它一知半解,那還是建議在商業(yè)項目使用Volley吧。
Java
1、線程中sleep和wait的區(qū)別
- (1)這兩個方法來自不同的類,sleep是來自Thread,wait是來自O(shè)bject;
- (2)sleep方法沒有釋放鎖,而wait方法釋放了鎖。
- (3)wait,notify,notifyAll只能在同步控制方法或者同步控制塊里面使用,而sleep可以在任何地方使用。
2、Thread中的start()和run()方法有什么區(qū)別
start()方法是用來啟動新創(chuàng)建的線程,而start()內(nèi)部調(diào)用了run()方法,這和直接調(diào)用run()方法是不一樣的,如果直接調(diào)用run()方法,
則和普通的方法沒有什么區(qū)別。
3、關(guān)鍵字final和static是怎么使用的。
final:
- 1、final變量即為常量,只能賦值一次。
- 2、final方法不能被子類重寫。
- 3、final類不能被繼承。
static:
- 1、static變量:對于靜態(tài)變量在內(nèi)存中只有一個拷貝(節(jié)省內(nèi)存),JVM只為靜態(tài)分配一次內(nèi)存,
在加載類的過程中完成靜態(tài)變量的內(nèi)存分配,可用類名直接訪問(方便),當(dāng)然也可以通過對象來訪問(但是這是不推薦的)。
- 2、static代碼塊
static代碼塊是類加載時,初始化自動執(zhí)行的。
- 3、static方法
static方法可以直接通過類名調(diào)用,任何的實例也都可以調(diào)用,因此static方法中不能用this和super關(guān)鍵字,
不能直接訪問所屬類的實例變量和實例方法(就是不帶static的成員變量和成員成員方法),只能訪問所屬類的靜態(tài)成員變量和成員方法。
- 4、String,StringBuffer,StringBuilder區(qū)別
- 1、三者在執(zhí)行速度上:StringBuilder > StringBuffer > String (由于String是常量,不可改變,拼接時會重新創(chuàng)建新的對象)。
- 2、StringBuffer是線程安全的,StringBuilder是線程不安全的。(由于StringBuffer有緩沖區(qū))
5、Java中重載和重寫的區(qū)別:
1、重載:一個類中可以有多個相同方法名的,但是參數(shù)類型和個數(shù)都不一樣。這是重載。
2、重寫:子類繼承父類,則子類可以通過實現(xiàn)父類中的方法,從而新的方法把父類舊的方法覆蓋。
6、Http https區(qū)別
此處延伸:https的實現(xiàn)原理
- 1、https協(xié)議需要到ca申請證書,一般免費證書較少,因而需要一定費用。
- 2、http是超文本傳輸協(xié)議,信息是明文傳輸,https則是具有安全性的ssl加密傳輸協(xié)議。
- 3、http和https使用的是完全不同的連接方式,用的端口也不一樣,前者是80,后者是443。
- 4、http的連接很簡單,是無狀態(tài)的;HTTPS協(xié)議是由SSL+HTTP協(xié)議構(gòu)建的可進行加密傳輸、身份認證的網(wǎng)絡(luò)協(xié)議,比http協(xié)議安全。
https實現(xiàn)原理:
- (1)客戶使用https的URL訪問Web服務(wù)器,要求與Web服務(wù)器建立SSL連接。
- (2)Web服務(wù)器收到客戶端請求后,會將網(wǎng)站的證書信息(證書中包含公鑰)傳送一份給客戶端。
- (3)客戶端的瀏覽器與Web服務(wù)器開始協(xié)商SSL連接的安全等級,也就是信息加密的等級。
- (4)客戶端的瀏覽器根據(jù)雙方同意的安全等級,建立會話密鑰,然后利用網(wǎng)站的公鑰將會話密鑰加密,并傳送給網(wǎng)站。
- (5)Web服務(wù)器利用自己的私鑰解密出會話密鑰。
- (6)Web服務(wù)器利用會話密鑰加密與客戶端之間的通信。
7、Http位于TCP/IP模型中的第幾層?為什么說Http是可靠的數(shù)據(jù)傳輸協(xié)議?
tcp/ip的五層模型:
從下到上:物理層->數(shù)據(jù)鏈路層->網(wǎng)絡(luò)層->傳輸層->應(yīng)用層