android面試寶典

一.基礎篇java

1.activity生命週期android

主要場景驗證:ios

1.A啓動跳轉到B,B返回A。
控制檯打印結果算法

進入A
A=====onCreate()
A=====onStart()
A=====onResume()
A跳轉到B
A=====onPause()
B=====onCreate()
B=====onStart()
B=====onResume()
A=====onStop()
B返回A
B=====onPause()
A=====onStart()
A=====onResume()
B=====onStop()
B=====onDestroy()數據庫

2.A啓動,App進入後臺,App返回前臺
控制檯打印結果設計模式

進入A
A=====onCreate()
A=====onStart()
A=====onResume()
app進入後臺
A=====onPause()
A=====onStop()
app返回前臺
A=====onStart()
A=====onResume()
--------------------- 緩存

2.Android的多線程模型有哪幾種?網絡

Android提供了四種經常使用的操做多線程的方式,分別是: 
1. Handler+Thread 
2. AsyncTask 
3. ThreadPoolExecutor 
4. IntentService 多線程

3.ScrollView是否能夠和listView混合使用?如何能夠,說明混合使用的方式,若是不行,說明緣由。 
能夠,計算整個ListView的高度,填充數據後從新設置ListView高度,重寫onMeasure和onInterceptTouchEvent方法併發

4.在建立fragment時如何傳遞初始化參數?

public static MyFragment newInstance(Bundle args) {
    MyFragment f = new MyFragment();
    f.setArguments(args);
    return f;
}
調用fragment:

Bundle args = new Bundle();
args.putString("text","Hello");
MyFragment f = MyFragment.newInstance(args)

5.如何規避oom? 

1.使用更小的圖片

在設計給到資源圖片的時候,咱們須要特別留意這張圖片是否存在能夠壓縮的空間,是否可使用一張更小的圖片。

2.資源文件須要選擇合適的文件夾進行存放

咱們知道hdpi/xhdpi/xxhdpi等等不一樣dpi的文件夾下的圖片在不一樣的設備上會通過scale的處理。例如咱們只在hdpi的目錄下放置了一張100100的圖片,那麼根據換算關係,xxhdpi的手機去引用那張圖片就會被拉伸到200200。須要注意到在這種狀況下,內存佔用是會顯著提升的。對於不但願被拉伸的圖片,須要放到assets或者nodpi的目錄下。

3.謹慎使用static對象

由於static的生命週期過長,和應用的進程保持一致,使用不當極可能致使對象泄漏,在Android中應該謹慎使用static對象。

4.注意Bitmap複用以及對象的及時回收

5.避免在onDraw方法裏面執行對象的建立

相似onDraw等頻繁調用的方法,必定須要注意避免在這裏作建立對象的操做,由於他會迅速增長內存的使用,並且很容易引發頻繁的gc,甚至是內存抖動。

六、 Android的四大組件是哪些,它們的做用?

答:Activity:Activity是Android程序與用戶交互的窗口,是Android構造塊中最基本的一種,它須要爲保持各界面的狀態,作不少持久化的事情,妥善管理生命週期以及一些跳轉邏輯

service:後臺服務於Activity,封裝有一個完整的功能邏輯實現,接受上層指令,完成相關的事物,定義好須要接受的Intent提供同步和異步的接口

Content Provider:是Android提供的第三方應用數據的訪問方案,能夠派生Content Provider類,對外提供數據,能夠像數據庫同樣進行選擇排序,屏蔽內部數據的存儲細節,向外提供統一的藉口模型,大大簡化上層應用,對數據的整合提供了更方便的途徑

BroadCast Receiver:接受一種或者多種Intent做觸發事件,接受相關消息,作一些簡單處理,轉換成一條Notification,統一了Android的事件廣播模型

七、 android中的動畫有哪幾類,它們的特色和區別是什麼 

答:兩種,一種是Tween動畫、還有一種是Frame動畫。Tween動畫,這種實現方式可使視圖組件移動、放大、縮小以及產生透明度的變化;另外一種Frame動畫,傳統的動畫方法,經過順序的播放排列好的圖片來實現,相似電影。

八、 請介紹下Android的數據存儲方式。

答:使用SharedPreferences存儲數據;文件存儲數據;SQLite數據庫存儲數據;使用ContentProvider存儲數據;網絡存儲數據;

九、 如何啓用Service,如何停用Service。

服務的開發比較簡單,以下:

第一步:繼承Service類

1

public class SMSService extends Service {}

第二步:在AndroidManifest.xml文件中的<application>節點裏對服務進行配置:<service android:name=".SMSService" />

服務不能本身運行,須要經過調用Context.startService()或Context.bindService()方法啓動服務。這兩個方法均可以啓動Service,可是它們的使用場合有所不一樣。使用startService()方法啓用服務,調用者與服務之間沒有關連,即便調用者退出了,服務仍然運行。使用bindService()方法啓用服務,調用者與服務綁定在了一塊兒,調用者一旦退出,服務也就終止,大有「不求同時生,必須同時死」的特色。

若是打算採用Context.startService()方法啓動服務,在服務未被建立時,系統會先調用服務的onCreate()方法,接着調用onStart()方法。若是調用startService()方法前服務已經被建立,屢次調用startService()方法並不會致使屢次建立服務,但會致使屢次調用onStart()方法。採用startService()方法啓動的服務,只能調用Context.stopService()方法結束服務,服務結束時會調用onDestroy()方法。

若是打算採用Context.bindService()方法啓動服務,在服務未被建立時,系統會先調用服務的onCreate()方法,接着調用onBind()方法。這個時候調用者和服務綁定在一塊兒,調用者退出了,系統就會先調用服務的onUnbind()方法,接着調用onDestroy()方法。若是調用bindService()方法前服務已經被綁定,屢次調用bindService()方法並不會致使屢次建立服務及綁定(也就是說onCreate()和onBind()方法並不會被屢次調用)。若是調用者但願與正在綁定的服務解除綁定,能夠調用unbindService()方法,調用該方法也會致使系統調用服務的onUnbind()-->onDestroy()方法。

服務經常使用生命週期回調方法以下:

onCreate() 該方法在服務被建立時調用,該方法只會被調用一次,不管調用多少次startService()或bindService()方法,服務也只被建立一次。

onDestroy()該方法在服務被終止時調用。

與採用Context.startService()方法啓動服務有關的生命週期方法

onStart() 只有採用Context.startService()方法啓動服務時纔會回調該方法。該方法在服務開始運行時被調用。屢次調用startService()方法儘管不會屢次建立服務,但onStart() 方法會被屢次調用。

與採用Context.bindService()方法啓動服務有關的生命週期方法

onBind()只有採用Context.bindService()方法啓動服務時纔會回調該方法。該方法在調用者與服務綁定時被調用,當調用者與服務已經綁定,屢次調用Context.bindService()方法並不會致使該方法被屢次調用。

onUnbind()只有採用Context.bindService()方法啓動服務時纔會回調該方法。該方法在調用者與服務解除綁定時被調用

十、 註冊廣播有幾種方式,這些方式有何優缺點?請談談Android引入廣播機制的用意。

答:首先寫一個類要繼承BroadcastReceiver

第一種:在清單文件中聲明,添加

<receive android:name=".IncomingSMSReceiver " >

<intent-filter>

<action android:name="android.provider.Telephony.SMS_RECEIVED")

<intent-filter>

<receiver>

第二種使用代碼進行註冊如:

IntentFilter filter =  new IntentFilter("android.provider.Telephony.SMS_RECEIVED");

IncomingSMSReceiver receiver = new IncomgSMSReceiver();

registerReceiver(receiver.filter);

兩種註冊類型的區別是:

1)第一種不是常駐型廣播,也就是說廣播跟隨程序的生命週期。

2)第二種是常駐型,也就是說當應用程序關閉後,若是有信息廣播來,程序也會被系統調用自動運行。

十一、 簡要解釋一下activity、 intent 、intent filter、service、Broadcase、BroadcaseReceiver

答:一個activity呈現了一個用戶能夠操做的可視化用戶界面;一個service不包含可見的用戶界面,而是在後臺運行,能夠與一個activity綁定,經過綁定暴露出來接口並與其進行通訊;一個broadcast receiver是一個接收廣播消息並作出迴應的component,broadcast receiver沒有界面;一個intent是一個Intent對象,它保存了消息的內容。對於activity和service來講,它指定了請求的操做名稱和待操做數據的URI,Intent對象能夠顯式的指定一個目標component。若是這樣的話,android會找到這個component(基於manifest文件中的聲明)並激活它。但若是一個目標不是顯式指定的,android必須找到響應intent的最佳component。它是經過將Intent對象和目標的intent filter相比較來完成這一工做的;一個component的intent filter告訴android該component能處理的intent。intent filter也是在manifest文件中聲明的。

十二、 若是後臺的Activity因爲某緣由被系統回收了,如何在被系統回收以前保存當前狀態?

答:重寫onSaveInstanceState()方法,在此方法中保存須要保存的數據,該方法將會在activity被回收以前調用。經過重寫onRestoreInstanceState()方法能夠從中提取保存好的數據

1三、 如何將一個Activity設置成窗口的樣式。

答:<activity>中配置:android :theme="@android:style/Theme.Dialog"

另外android:theme="@android:style/Theme.Translucent" 是設置透明

1四、Service生命週期?

service 啓動方式有兩種,一種是經過startService()方式進行啓動,另外一種是經過bindService()方式進行啓動。不一樣的啓動方式他們的生命週期是不同.

經過startService()這種方式啓動的service,生命週期是這樣:調用startService() --> onCreate()--> onStartConmon()--> onDestroy()。這種方式啓動的話,須要注意一下幾個問題,第一:當咱們經過startService被調用之後,屢次在調用startService(),onCreate()方法也只會被調用一次,而onStartConmon()會被屢次調用當咱們調用stopService()的時候,onDestroy()就會被調用,從而銷燬服務。第二:當咱們經過startService啓動時候,經過intent傳值,在onStartConmon()方法中獲取值的時候,必定要先判斷intent是否爲null。

經過bindService()方式進行綁定,這種方式綁定service,生命週期走法:bindService-->onCreate()-->onBind()-->unBind()-->onDestroy()  bingservice 這種方式進行啓動service好處是更加便利activity中操做service,好比加入service中有幾個方法,a,b ,若是要在activity中調用,在須要在activity獲取ServiceConnection對象,經過ServiceConnection來獲取service中內部類的類對象,而後經過這個類對象就能夠調用類中的方法,固然這個類須要繼承Binder對象

1五、Broadcast註冊方式與區別 

此處延伸:什麼狀況下用動態註冊

 

Broadcast廣播,註冊方式主要有兩種.

第一種是靜態註冊,也可成爲常駐型廣播,這種廣播須要在Androidmanifest.xml中進行註冊,這中方式註冊的廣播,不受頁面生命週期的影響,即便退出了頁面,也能夠收到廣播這種廣播通常用於想開機自啓動啊等等,因爲這種註冊的方式的廣播是常駐型廣播,因此會佔用CPU的資源。

 

第二種是動態註冊,而動態註冊的話,是在代碼中註冊的,這種註冊方式也叫很是駐型廣播,收到生命週期的影響,退出頁面後,就不會收到廣播,咱們一般運用在更新UI方面。這種註冊方式優先級較高。最後須要解綁,否會會內存泄露

廣播是分爲有序廣播和無序廣播。

1六、View的繪製流程

自定義控件:

一、組合控件。這種自定義控件不須要咱們本身繪製,而是使用原生控件組合成的新控件。如標題欄。

二、繼承原有的控件。這種自定義控件在原生控件提供的方法外,能夠本身添加一些方法。如製做圓角,圓形圖片。

三、徹底自定義控件:這個View上所展示的內容所有都是咱們本身繪製出來的。好比說製做水波紋進度條。

 

View的繪製流程:OnMeasure()——>OnLayout()——>OnDraw()

 

第一步:OnMeasure():測量視圖大小。從頂層父View到子View遞歸調用measure方法,measure方法又回調OnMeasure。

 

第二步:OnLayout():肯定View位置,進行頁面佈局。從頂層父View向子View的遞歸調用view.layout方法的過程,即父View根據上一步measure子View所獲得的佈局大小和佈局參數,將子View放在合適的位置上。

 

第三步:OnDraw():繪製視圖。ViewRoot建立一個Canvas對象,而後調用OnDraw()。六個步驟:①、繪製視圖的背景;②、保存畫布的圖層(Layer);③、繪製View的內容;④、繪製View子視圖,若是沒有就不用;

⑤、還原圖層(Layer);⑥、繪製滾動條。

 

1七、View,ViewGroup事件分發

1. Touch事件分發中只有兩個主角:ViewGroup和View。ViewGroup包含onInterceptTouchEvent、dispatchTouchEvent、onTouchEvent三個相關事件。View包含dispatchTouchEvent、onTouchEvent兩個相關事件。其中ViewGroup又繼承於View。

2.ViewGroup和View組成了一個樹狀結構,根節點爲Activity內部包含的一個ViwGroup。

3.觸摸事件由Action_Down、Action_Move、Aciton_UP組成,其中一次完整的觸摸事件中,Down和Up都只有一個,Move有若干個,能夠爲0個。

4.當Acitivty接收到Touch事件時,將遍歷子View進行Down事件的分發。ViewGroup的遍歷能夠當作是遞歸的。分發的目的是爲了找到真正要處理本次完整觸摸事件的View,這個View會在onTouchuEvent結果返回true。

5.當某個子View返回true時,會停止Down事件的分發,同時在ViewGroup中記錄該子View。接下去的Move和Up事件將由該子View直接進行處理。因爲子View是保存在ViewGroup中的,多層ViewGroup的節點結構時,上級ViewGroup保存的會是真實處理事件的View所在的ViewGroup對象:如ViewGroup0-ViewGroup1-TextView的結構中,TextView返回了true,它將被保存在ViewGroup1中,而ViewGroup1也會返回true,被保存在ViewGroup0中。當Move和UP事件來時,會先從ViewGroup0傳遞至ViewGroup1,再由ViewGroup1傳遞至TextView。

6.當ViewGroup中全部子View都不捕獲Down事件時,將觸發ViewGroup自身的onTouch事件。觸發的方式是調用super.dispatchTouchEvent函數,即父類View的dispatchTouchEvent方法。在全部子View都不處理的狀況下,觸發Acitivity的onTouchEvent方法。

7.onInterceptTouchEvent有兩個做用:1.攔截Down事件的分發。2.停止Up和Move事件向目標View傳遞,使得目標View所在的ViewGroup捕獲Up和Move事件。

 

1八、Android UI適配

字體使用sp,使用dp,多使用match_parent,wrap_content,weight

圖片資源,不一樣圖片的的分辨率,放在相應的文件夾下可以使用百分比代替。

1九、HybridApp WebView和JS交互

Android與JS經過WebView互相調用方法,其實是:

Android去調用JS的代碼

1. 經過WebView的loadUrl(),使用該方法比較簡潔,方便。可是效率比較低,獲取返回值比較困難。

2. 經過WebView的evaluateJavascript(),該方法效率高,可是4.4以上的版本才支持,4.4如下版本不支持。因此建議二者混合使用。

JS去調用Android的代碼

1. 經過WebView的addJavascriptInterface()進行對象映射 ,該方法使用簡單,僅將Android對象和JS對象映射便可,可是存在比較大的漏洞。

 

漏洞產生緣由是:當JS拿到Android這個對象後,就能夠調用這個Android對象中全部的方法,包括系統類(java.lang.Runtime 類),從而進行任意代碼執行。

解決方式:

(1)Google 在Android 4.2 版本中規定對被調用的函數以 @JavascriptInterface進行註解從而避免漏洞攻擊。

(2)在Android 4.2版本以前採用攔截prompt()進行漏洞修復。

 

2. 經過 WebViewClient 的shouldOverrideUrlLoading ()方法回調攔截 url 。這種方式的優勢:不存在方式1的漏洞;缺點:JS獲取Android方法的返回值複雜。(ios主要用的是這個方式)

 

(1)Android經過 WebViewClient 的回調方法shouldOverrideUrlLoading ()攔截 url

(2)解析該 url 的協議

(3)若是檢測到是預先約定好的協議,就調用相應方法

 

3. 經過 WebChromeClient 的onJsAlert()、onJsConfirm()、onJsPrompt()方法回調攔截JS對話框alert()、confirm()、prompt() 消息

這種方式的優勢:不存在方式1的漏洞;缺點:JS獲取Android方法的返回值複雜。

20、設計模式

此處延伸: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; 

    } 

}

 

2一、RecyclerView和ListView的區別

RecyclerView能夠完成ListView,GridView的效果,還能夠完成瀑布流的效果。同時還能夠設置列表的滾動方向(垂直或者水平);

RecyclerView中view的複用不須要開發者本身寫代碼,系統已經幫封裝完成了。

RecyclerView能夠進行局部刷新。

RecyclerView提供了API來實現item的動畫效果。

在性能上:

若是須要頻繁的刷新數據,須要添加動畫,則RecyclerView有較大的優點。

若是隻是做爲列表展現,則二者區別並非很大。

 

2二、Universal-ImageLoader,Picasso,Fresco,Glide對比

Fresco 是 Facebook 推出的開源圖片緩存工具,主要特色包括:兩個內存緩存加上 Native 緩存構成了三級緩存,

優勢:

1. 圖片存儲在安卓系統的匿名共享內存, 而不是虛擬機的堆內存中, 圖片的中間緩衝數據也存放在本地堆內存, 因此, 應用程序有更多的內存使用, 不會由於圖片加載而致使oom, 同時也減小垃圾回收器頻繁調用回收 Bitmap 致使的界面卡頓, 性能更高。

 

2. 漸進式加載 JPEG 圖片, 支持圖片從模糊到清晰加載。

 

3. 圖片能夠以任意的中心點顯示在 ImageView, 而不只僅是圖片的中心。

 

4. JPEG 圖片改變大小也是在 native 進行的, 不是在虛擬機的堆內存, 一樣減小 OOM。

 

5. 很好的支持 GIF 圖片的顯示。

 

缺點:

1. 框架較大, 影響 Apk 體積

2. 使用較繁瑣

 

Universal-ImageLoader:(估計因爲HttpClient被Google放棄,做者就放棄維護這個框架)

優勢:

1.支持下載進度監聽

2.能夠在 View 滾動中暫停圖片加載,經過 PauseOnScrollListener 接口能夠在 View 滾動中暫停圖片加載。

3.默認實現多種內存緩存算法 這幾個圖片緩存均可以配置緩存算法,不過 ImageLoader 默認實現了較多緩存算法,如 Size 最大先刪除、使用最少先刪除、最近最少使用、先進先刪除、時間最長先刪除等。

4.支持本地緩存文件名規則定義

     

Picasso 優勢

1. 自帶統計監控功能。支持圖片緩存使用的監控,包括緩存命中率、已使用內存大小、節省的流量等。

 

2.支持優先級處理。每次任務調度前會選擇優先級高的任務,好比 App 頁面中 Banner 的優先級高於 Icon 時就很適用。

 

3.支持延遲到圖片尺寸計算完成加載

 

4.支持飛行模式、併發線程數根據網絡類型而變。 手機切換到飛行模式或網絡類型變換時會自動調整線程池最大併發數,好比 wifi 最大併發爲 4,4g 爲 3,3g 爲 2。  這裏 Picasso 根據網絡類型來決定最大併發數,而不是 CPU 核數。

 

5.「無」本地緩存。無」本地緩存,不是說沒有本地緩存,而是 Picasso 本身沒有實現,交給了 Square 的另一個網絡庫 okhttp 去實現,這樣的好處是能夠經過請求 Response Header 中的 Cache-Control 及 Expired 控制圖片的過時時間。

 

 Glide 優勢

1. 不只僅能夠進行圖片緩存還能夠緩存媒體文件。Glide 不只是一個圖片緩存,它支持 Gif、WebP、縮略圖。甚至是 Video,因此更該當作一個媒體緩存。

 

2. 支持優先級處理。

 

 

3. 與 Activity/Fragment 生命週期一致,支持 trimMemory。Glide 對每一個 context 都保持一個 RequestManager,經過 FragmentTransaction 保持與 Activity/Fragment 生命週期一致,而且有對應的 trimMemory 接口實現可供調用。

 

4. 支持 okhttp、Volley。Glide 默認經過 UrlConnection 獲取數據,能夠配合 okhttp 或是 Volley 使用。實際 ImageLoader、Picasso 也都支持 okhttp、Volley。

 

 

5. 內存友好。Glide 的內存緩存有個 active 的設計,從內存緩存中取數據時,不像通常的實現用 get,而是用 remove,再將這個緩存數據放到一個 value 爲軟引用的 activeResources map 中,並計數引用數,在圖片加載完成後進行判斷,若是引用計數爲空則回收掉。內存緩存更小圖片,Glide 以 url、view_width、view_height、屏幕的分辨率等作爲聯合 key,將處理後的圖片緩存在內存緩存中,而不是原始圖片以節省大小與 Activity/Fragment 生命週期一致,支持 trimMemory。圖片默認使用默認 RGB_565 而不是 ARGB_888,雖然清晰度差些,但圖片更小,也可配置到 ARGB_888。

 

6.Glide 能夠經過 signature 或不使用本地緩存支持 url 過時

相關文章
相關標籤/搜索