
1、四大組件是什么?
1)Activity:用戶可操作的可視化界面,為用戶提供一個完成操作指令的視窗,一個Activity 通常是一個單獨的螢屏,Activity 通過 Intent 來進行通信,Android 中會維持一個Activity Stack,當一個新 Activity 創建時,它就會放到堆疊頂,這個 Activity 就處于運行狀態,
2)Service:服務,運行在手機后臺,適合執行不需和用戶互動且還需長期運行的任務,
3)ContentProvider:內容提供者,使一個應用程式的指定資料集提供給其他應用程式,其他應用可通過 ContentResolver 類從該內容提供者中獲取或存入資料,它提供了一種跨行程資料共享的方式,當資料被修改后,ContentResolver 介面的 notifyChange 函式通知那些注冊監控特定 URI 的 ContentObserver 物件,
如果 ContentProvider 和呼叫者在同一行程中,ContentProvider 的方法(query/insert/update/delete 等)和呼叫者在同一執行緒中;
如果ContentProvider 和呼叫者不在
同一行程,ContentProvider 方法會運行在它自身行程的一個 Binder 執行緒中,
4)Broadcast Receiver: 廣播接收者,運用在應用程式間傳輸資訊,可以使用廣播接收器來讓應用對一個外部事件做出回應,
2、四大組件的生命周期和簡單用法

1)Activity:
onCreate()->onStart()->onResume()->onPause()->onStop()->onDestory()
-
onCreate():為 Activity 設定布局,此時界面還不可見;
-
onStart(): Activity 可見但還不能與用戶互動,不能獲得焦點
-
onRestart():重新啟動 Activity 時被回呼
-
onResume(): Activity 可見且可與用戶進行互動
onPause(): 當前 Activity 暫停,不可與用戶互動,但還可見,在新
Activity 啟動前被系統調
用保存現有的 Activity 中的持久資料、停止影片等,
-
onStop(): 當 Activity 被新的 Activity 覆寫不可見時被系統呼叫
-
onDestory(): 當 Activity 被系統銷毀殺掉或是由于記憶體不足時呼叫
2)Service

a) onBind 方式系結的:
onCreate->onBind->onUnBind->onDestory(不管呼叫 bindService 幾次,onCreate 只會呼叫一次,onStart 不會被呼叫,
建立連接后,service 會一直運行,直到呼叫 unBindService 或是之前呼叫的 bindService 的 Context 不存在了,系統會自動停止Service,對應的 onDestory 會被呼叫)
b) startService 啟動的:
onCreate->onStartCommand->onDestory(start 多次,onCreate 只會被呼叫一次,onStart 會呼叫多次,該 service 會在后臺運行,直至被呼叫 stopService 或是stopSelf)
c) 又被啟動又被系結的服務
不管如何呼叫 onCreate()只被呼叫一次,startService 呼叫多少次,onStart 就會被呼叫多少次,而 unbindService 不會停止服務,必須呼叫 stopService或是 stopSelf 來停止服務,
必須 unbindService 和 stopService(stopSelf)同時都呼叫了才會停
止服務,
3)BroadcastReceiver

a) 動態注冊:存活周期是在 Context.registerReceiver 和 Context.unregisterReceiver 之間,BroadcastReceiver 每次收到廣播都是使用注冊傳入的物件處理的,
**b) 靜態注冊:行程在的情況下,receiver 會正常收到廣播,呼叫 onReceive 方法;生命周期只存活在 onReceive 函式中,此方法結束,BroadcastReceiver 就銷毀了,onReceive()只有十幾秒存活時間,在 onReceive()內操作超過 10S,就會報 ANR,
行程不存在的情況,廣播相應的行程會被拉,Application.onCreate 會被呼叫,再呼叫onReceive,
4)ContentProvider

和應用的生命周期一樣,它屬于系統應用,應用啟動時,它會跟
著初始化,應用關倍訓被殺,它會跟著結束,
3、Activity 之間的通信方式
1)通過 Intent 方式傳遞引數跳轉
2)通過廣播方式
3)通過介面回呼方式
4)借助類的靜態變數或全域變數
5)借助 SharedPreference 或是外部存盤,如資料庫或本地檔案
4、Activity 各種情況下的生命周期
- 兩個 Activity(A->B)切換(B 正常的 Activity)的生命周期:
onPause(A)->onCreate(B)->onStart(B)->onResume(B)->oStop(A)
這時如果按回退鍵回退到 A onPause(B)->onRestart(A)>onStart(A)->onResume(A)->oStop(B)
如果在切換到 B 后呼叫了 A.finish(),則會走到 onDestory(A),這時點回退鍵會退出應用
- 兩個 Activity(A->B)切換(B 透明主題的 Activity 或是 Dialog 風格的 Acivity)的生命周期:onPause(A)->onCreate(B)->onStart(B)->onResume(B)
這時如果回退到 A onPause(B)->onResume(A)->oStop(B)->onDestory(B)
- Activity(A)啟動后點擊 Home 鍵再回到應用的生命周期:onPause(A)->oStop(A)->onRestart(A)->onStart(A)->onResume(A)
5、如何退出Activity?
退出activity我們只需要呼叫finish就可以了,退出activity 會執行 onDestroy()方法,
如何一次性的退出多個Activity?
a、拋例外強制退出:
該方法通過拋例外,使程式Force Close,
驗證可以,但是,需要解決的問題是,如何使程式結束掉,而不彈出Force Close的視窗,
b、記錄打開的Activity:
每打開一個Activity,就記錄下來,放到application里面去存起來,在需要退出時,關閉每一個Activity即可,
6、Activity 與 Fragment 之間生命周期比較
Fragment 生命周期:onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume->onPause->onStop->onDestoryView->onDestory->onDetach
切換到該 Fragment:onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume
按下 Power 鍵:onPause->onSaveInstanceState->onStop
點亮螢屏解鎖:onStart->onRestoreInstanceState->onResume
切換到其他 Fragment: onPause->onStop->onDestoryView
切回到該 Fragment: onCreateView->onActivityCreated->onStart->onResume
退出應用:onPause->onStop->onDestoryView->onDestory->onDetach
7、Activity 上有 Dialog 的時候按 Home 鍵時的生命周期
AlertDialog 并不會影響 Activity 的生命周期,按 Home 鍵后才會使 Activity 走 onPause->onStop,AlertDialog 只是一個組件,并不會使 Activity 進入后臺,
8、兩個 Activity 之間跳轉時必然會執行的是哪幾個方法?
前一個 Activity 的 onPause,后一個 Activity 的 onResume
9、Activity 的四種啟動模式對比
1)standard:標準啟動模式(默認),每啟動一次 Activity,都會創建一個實體,即使從ActivityA startActivity ActivityA,也會再次創建 A 的實體放于堆疊頂,當回退時,回到上一個ActivityA 的實體,
2) singleTop:堆疊頂復用模式,每次啟動 Activity,如果待啟動的 Activity 位于堆疊頂,則不會重新創建 Activity 的實體,即不會走 onCreate->onStart,會直接進入 Activity 的 onPause->onNewIntent->onResume 方法
3) singleInstance: 單一實體模式,整個手機作業系統里只有一個該 Activity 實體存在,沒有其他 Actvity,后續請求均不會創建新的 Activity,若 task 中存在實體,執行實體的onNewIntent(),應用場景:鬧鐘、瀏覽器、電話
4) singleTask:堆疊內復用,啟動的 Activity 如果在指定的taskAffinity 的 task 堆疊中存在相應的實體,則會把它上面的 Activity 都出堆疊,直到當前 Activity 實體位于堆疊頂,執行相應的onNewIntent()方法,
如果指定的 task 不存在,創建指定taskAffinity 的 task,taskAffinity 的作用,進入指寫 taskAffinity 的 task,如果指定的 task 存在,將 task 移到前臺,如果指定的task 不存在,創建指定的 taskAffinity 的 task.應用場景:應用的主頁面
10、fragment 各種情況下的生命周期
正常情況下的生命周期:onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume->onPause->onStop->onDestoryView->onDestory->onDetach
Fragment 在 Activity 中 replace onPause(舊)->onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume->onStop(舊)->onDestoryView(舊)
如果添加到 backStack 中,呼叫 remove()方法 fragment 的方法會走到 onDestoryView,但不會執行 onDetach(),即 fragment 本身的實體是存在的,成員變數也存在,但是 view 被銷毀了,如果新替換的 Fragment 已在 BackStack 中,則不會執行 onAttach->onCreate
11、Fragment 狀態保存 onSaveInstanceState 是哪個類的方法,在什么情況下使用?
在對應的 FragmentActivity.onSaveInstanceState 方法會調FragmentController.saveAllState,其中會對 mActive 中各個 Fragment 的實體狀態和 View 狀態分別進行保存.當 Activity 在做狀態保存和恢復的時候, 在它其中的 fragment 自然也需要做狀態保存和恢復,
12、Fragment.startActivityForResult 是和 FragmentActivity 的 startActivityForResult?
如果希望在 Fragment 的 onActivityResult 接收資料,就要呼叫
Fragment.startActivityForResult,而不是Fragment.getActivity().startActivityForResult,
Fragment.startActivityForResult-Fragment.
startActivityForResult>FragmentActivitymHost.HostCallbacks.onStartActivityFromFragment>FragmentActivity.startActivityFromFragment,
13、如何實作 Fragment 的滑動?
ViewPager+FragmentPagerAdapter+List
##14、fragment 之間傳遞資料的方式?
1)在相應的 fragment 中撰寫方法
在需要回呼的 fragment 里獲取對應的 Fragment 實體,呼叫相應的方法;
2)采用介面回呼的方式進行資料傳遞;
- a) 在 Fragment1 中創建一個介面及介面對應的 set 方法;
- b) 在 Fragment1 中呼叫介面的方法;
- c)在 Fragment2 中實作該介面;
3)利用第三方開源框架 EventBus
15、service 和 activity 怎么進行資料互動?
1)通過 bindService 啟動服務
可以在 ServiceConnection 的 onServiceConnected 中獲取到Service 的實體,這樣就可以呼叫 service 的方法,如果 service 想呼叫 activity 的方法,可以在 service 中定義介面類及相應的 set 方法,在 activity 中實作相應的介面,這樣 service 就可以回呼介面言法;
2)通過廣播方式
16、簡單描述一下廣播接收者
廣播接收者有兩類,一種是系統本身就有的,一種是我們自己寫的廣播接收者,
廣播接收者注冊的方式也有兩種:
一種是動態注冊,
一種是靜態注冊,
只能用代碼注冊的廣播,這種廣播產生的頻率是比較高的,比如電量變化的廣播,螢屏解鎖的廣播,電量變化的廣播,
廣播接收者在注冊的時候可以指定優先級,用于提高接收到廣播的順序,
廣播一般是用于跨行程通訊的時候,
17、廣播的分類
1)普通廣播:完全異步的,可以在同一時刻(邏輯上)被所有接收者接收到,訊息傳遞的效率比較高,并且無法中斷廣播的傳播,
2)有序廣播:發送有序廣播后,廣播接收者將按預先宣告的優先級依次接收 Broadcast,
優先級高的優先接收到廣播,而在其 onReceiver()執行程序中,廣播不會傳播到下一個接收者,此時當前的廣播接收者可以 abortBroadcast()來終止廣播繼續向下傳播,也可以將intent 中的資料進行修改設定,然后將其傳播到下一個廣播接收者,sendOrderedBroadcast(intent, null);//發送有序廣播
3)粘性廣播:sendStickyBroadcast()來發送該型別的廣播資訊,這種的廣播的最大特點是,當粘性廣播發送后,最后的一個粘性廣播會滯留在作業系統中,如果在粘性廣播發送后的一段時間里,如果有新的符合廣播的動態注冊的廣播接收者注冊,將會收到這個廣播訊息,雖然這個廣播是在廣播接收者注冊之前發送的,另外一點,對于靜態注冊的廣播接收者來說,這個等同于普通廣播,
18、請描述一下廣播 BroadcastReceiver 的理解
BroadcastReceiver 是一種全域監聽器,用來實作系統中不同組件之間的通信,有時候也會用來作為傳輸少量而且發送頻率低的資料,但是如果資料的發送頻率比較高或者數量比較大就不建議用廣播接收者來接收了,因為這樣的效率很不好,因為BroadcastReceiver 接收資料的開銷還是比較大的,
19、View的繪制流程,自定義View注意的幾點?
View 的繪制程序遵循如下幾步:
- a.繪制背景 background.draw(canvas)
- b.繪制自己(onDraw)
- c.繪制 children(dispatchDraw)
- d.繪制裝飾(onDrawScrollBars)
View 繪制程序的傳遞是通過 dispatchDraw 來實作的,它會遍歷所有的子元素的draw 方法,如此 draw 事件就一層一層的傳遞下去了
ps:view 有一個特殊的方法 setWillNotDraw,如果一個 view 不需要繪制內容,即不需要重寫 onDraw 方法繪制,可以開啟這個標記,系統會進行相應的優化,
默認情況下,View 沒有開啟這個標記,默認認為需要實作 onDraw 方法繪制,當我們繼承 ViewGroup 實作自定義控制元件,并且明確知道不需要具備繪制功能時,可以開啟這個標記,如果我們重寫了 onDraw,那么要顯示的關閉這個標記子 view 寬高可以超過父 view?
可以
1.android:clipChildren = “false” 這個屬性要設定在父 view 上,代表其中的子View 可以超出螢屏,
2.子 view 要有具體的大小,一定要比父 view 大 才能超出,比如 父 view 高 度 100px 子 view 設定高度 150px,子 view 比父 view 大,這樣超出的屬性才有意義,(高度可以在代碼中動態賦值,但不能用 wrap_content /match_partent),
3.對父布局還有要求,要求使用 linearLayout(反正我用 RelativeLayout 是不行),你如果必須用其他布局可以在需要超出的 view 上面套一個 linearLayout 外面再套其他的布局,
4.最外面的布局如果設定的 padding 不能超出
自定義View注意的幾點?
1.讓 view 支持 wrap_content 屬性,在 onMeasure 方法中針對 AT_MOST 模式做專門處理,否則 wrap_content 會和 match_parent 效果一樣(繼承 ViewGroup 也同樣要在 onMeasure 中做這個判斷處理)
MeasureSpec.AT_MOST){
setMeasuredDimension(200,200); // wrap_content
情況下要設定一個默認
值,200 只是舉個例子,最終的值需要計算得到剛好包裹內容的寬高值
}else if(widthMeasureSpec == MeasureSpec.AT_MOST){
setMeasuredDimension(200,heightMeasureSpec );
}else if(heightMeasureSpec == MeasureSpec.AT_MOST){
setMeasuredDimension(heightMeasureSpec ,200);
}
2.讓 view 支持 padding(onDraw 的時候,寬高減去 padding 值,margin 由父布局控制,不需要 view 考慮),自定義 ViewGroup 需要考慮自身的 padding 和子view 的 margin 造成的影響
3.在 view 中盡量不要使用 handler,使用 view 本身的 post 方法
4.在 onDetachedFromWindow 中及時停止執行緒或影片
5.view 帶有滑動嵌套情形時,處理好滑動沖突
ACTION_DOWN 沒有攔截,ACTION_MOVE ACTION_UP 還會攔截嗎
20、Android執行緒間的通訊
Handler是用來進行執行緒間的通信,
Looper是用來管理所屬執行緒的訊息佇列MessageQueue的
每一個執行緒都需要有一個looper,每一個looper管理一個MessageQueue
Handler.sendMessage的意思是將某一個message放到MessageQueue中去,looper是個死回圈,不斷的讀MessageQueue中的新訊息,
要讓looper的死回圈運行起來,得呼叫Looper.loop()方法,
我們通常都會在子執行緒中,發一個訊息到主執行緒中的messagequeue中去,
21、Android 執行緒間通信有哪幾種方式?
1)共享變數(記憶體)
2)管道
3)handle 機制
runOnUiThread(Runnable)
view.post(Runnable)
22、Android 記憶體泄露原因
Android 記憶體泄漏指的是行程中某些物件(垃圾物件)已經沒有使用價值了,但是它們卻可以直接或間接地參考到 gc roots 導致無法被 GC 回收,無用的物件占據著記憶體空間,使得實際可使用記憶體變小,形象地說法就是記憶體泄漏了,
場景
1.類的靜態變數持有大資料物件
靜態變數長期維持到大資料物件的參考,阻止垃圾回收,
2.非靜態內部類的靜態實體
非靜態內部類會維持一個到外部類實體的參考,如果非靜態內部類的實體是靜態的,就會間接長期維持著外部類的參考,阻止被回收掉,
3.資源物件未關閉
資源性物件如 Cursor、File、Socket,應該在使用后及時關閉,未在 finally 中關閉,會導致例外情況下資源物件未被釋放的隱患,
4.注冊物件未反注冊
未反注冊會導致觀察者串列里維持著物件的參考,阻止垃圾回收,
5.Handler 臨時性記憶體泄露
Handler 通過發送 Message 與主執行緒互動,Message 發出之后是存盤在MessageQueue 中的,有些 Message 也不是馬上就被處理的,在 Message 中存在一個 target,是 Handler 的一個參考,如果 Message 在 Queue 中存在的時間越長,就會導致 Handler 無法被回收,
如果 Handler 是非靜態的,則會導致Activity 或者 Service 不會被回收,
由于 AsyncTask 內部也是 Handler 機制,同樣存在記憶體泄漏的風險,
此種記憶體泄露,一般是臨時性的,
22、記憶體泄露檢測有什么好方法?
1、DDMS Heap 發現記憶體泄露
dataObject totalSize 的大小,是否穩定在一個范圍內,如果操作程式,不斷增加,說明記憶體泄露
2、使用 Heap Tool 進行記憶體快照前后對比
BlankActivity 手動觸發 GC 進行前后對比,物件是否被及時回收定位:
1)、MAT 插件打開.hprof 具體定位記憶體泄露:
查看 histogram 項,選中某一個物件,查看它的 GC 參考鏈,因為存在 GC 參考鏈的,說明無法回收
2)、AndroidStudio 的 Allocation Tracker:
觀測到期間的記憶體分配,哪些物件被創建,什么時候創建,從而準確定位
23、WebView 的性能優化
一個加載網頁的程序中,native、網路、后端處理、CPU 都會
參與,各自都有必要的作業和依賴關系;讓他們相互并行處理
而不是相互阻塞才可以讓網頁加載更快:
1.WebView 初始化慢,可以在初始化同時先請求資料,讓后端和網路不要閑著,
2.常用 JS 本地化及延遲加載,使用第三方瀏覽內核后端處理慢,可以讓服務器分 trunk 輸出,在后端計算的同時前端也加載網路靜態資源,
3.腳本執行慢,就讓腳本在最后運行,不阻塞頁面決議,同時,合理的預加載、預快取可以讓加載速度的瓶頸更小,
4.WebView 初始化慢,就隨時初始化好一個 WebView待用,
5.DNS 和鏈接慢,想辦法復用客戶端使用的域名和鏈接,
24、Android 中圖片的三級快取策略
三級快取:
?記憶體快取,優先加載,速度最快;
?本地快取,次優先加載,速度快;
?網路快取,最后加載,速度慢,浪費流量 ;
三級快取策略,最實在的意義就是 減少不必要的流量消耗,增加加載速度,
三級快取的原理:
?首次加載的時候通過網路加載,獲取圖片,然后保存到記憶體和 SD 卡中,
?之后運行 APP 時,優先訪問記憶體中的圖片快取,
?如果記憶體沒有,則加載本地 SD 卡中的圖片,
具體的快取策略可以是這樣的:記憶體作為一級快取,本地作為二級快取,網路加載為最后,
其中,記憶體使用 LruCache ,其內部通過 LinkedhCache,加載圖片的時候,首先使用 LRU 方式進行尋找,找不到指定內容,按照三級快取的方式,進行本地搜索,還沒有就網路加載,ashMap 來持有外界快取物件的強參考;對于本地快取,使用 DiskLru
這個就是我整理的一些題目Android最基礎的面試了,如果有寫的有不好的地方希望大家多多指點 謝謝大家!!
最后
小編還整理了一些 其他Android 開發相關的學習檔案、Android 核心筆記等等檔案,希望能幫助到大家學習提升,如有需要參考的可以點擊鏈接領取點擊這里免費領取

轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/286969.html
標籤:其他
