安卓面試題
Android interview questions
作者:韓夢飛沙
2017年7月3日,14:52:44
- 1. 要做一個儘可能流暢的ListView,你平時在工作中如何進行優化的?
①Item佈局,層級越少越好,使用hierarchyview工具檢視優化。
②複用convertView
③使用ViewHolder
④item中有圖片時,非同步載入
⑤快速滑動時,不載入圖片
⑥item中有圖片時,應對圖片進行適當壓縮
⑦實現資料的分頁載入
- 2.
對於android 的安全問題,你知道多少
①錯誤匯出元件
② 引數校驗不嚴
③WebView引入各種安全問題,webview中的js注入
④不混淆、不防二次打包
⑤明文儲存關鍵資訊
⑦ 錯誤使用HTTPS
⑧山寨加密方法
⑨濫用許可權、記憶體洩露、使用debug簽名
- 3.
如何縮減APK包大小?
程式碼
保持良好的程式設計習慣,不要重複或者不用的程式碼,謹慎新增libs,移除使用不到的libs。
使用proguard混淆程式碼,它會對不用的程式碼做優化,並且混淆後也能夠減少安裝包的大小。
native code的部分,大多數情況下只需要支援armabi與x86的架構即可。如果非必須,可以考慮拿掉x86的部分。
資源
使用Lint工具查詢沒有使用到的資源。去除不使用的圖片,String,XML等等。 assets目錄下的資源請確保沒有用不上的檔案。
生成APK的時候,aapt工具本身會對png做優化,但是在此之前還可以使用其他工具如tinypng對圖片進行進一步的壓縮預處理。
jpeg還是png,根據需要做選擇,在某些時候jpeg可以減少圖片的體積。 對於9.png的圖片,可拉伸區域儘量切小,另外可以通過使用9.png拉伸達到大圖效果的時候儘量不要使用整張大圖。
策略
有選擇性的提供hdpi,xhdpi,xxhdpi的圖片資源。建議優先提供xhdpi的圖片,對於mdpi,ldpi與xxxhdpi根據需要提供有差異的部分即可。
儘可能的重用已有的圖片資源。例如對稱的圖片,只需要提供一張,另外一張圖片可以通過程式碼旋轉的方式實現。
能用程式碼繪製實現的功能,儘量不要使用大量的圖片。例如減少使用多張圖片組成animate-list的AnimationDrawable,這種方式提供了多張圖片很佔空間。
- 4. Android與伺服器互動的方式中的對稱加密和非對稱加密是什麼?
對稱加密,就是加密和解密資料都是使用同一個key,這方面的演算法有DES。
非對稱加密,加密和解密是使用不同的key。傳送資料之前要先和服務端約定生成公鑰和私鑰,使用公鑰加密的資料可以用私鑰解密,反之。這方面的演算法
5,裝置橫豎屏切換的時候,接下來會發生什麼?
1、不設定Activity的android:configChanges時,切屏會重新呼叫各個生命週期,切橫屏時會執行一次,切豎屏時會執行兩次
2、設定Activity的android:configChanges=”orientation”時,切屏還是會重新呼叫各個生命週期,切橫、豎屏時只會執行一次
3、設定Activity的android:configChanges=”orientation|keyboardHidden”時,切屏不會重新呼叫各個生命週期,只會執行onConfigurationChanged方法
6.Android啟動Service的兩種方式是什麼? 它們的適用情況是什麼?
如果後臺服務開始後基本可以獨立執行的話,可以用startService。音樂播放器就可以這樣用。它們會一直執行直到你呼叫 stopSelf或者stopService。你可以通過傳送Intent或者接收Intent來與正在執行的後臺服務通訊,但大部分時間,你只是啟動服務並讓它獨立執行。如果你需要與後臺服務通過一個持續的連線來比較頻繁地通訊,建議使用bind()。比如你需要定位服務不停地把更新後的地理位置傳給UI。Binder比Intent開發起來複雜一些,但如果真的需要,你也只能使用它。
startService:生命週期與呼叫者不同。啟動後若呼叫者未呼叫stopService而直接退出,Service仍會執行
bindService:生命週期與呼叫者繫結,呼叫者一旦退出,Service就會呼叫unBind->onDestroy
7.談談你對Android中Context的理解?
Context:包含上下文資訊(外部值) 的一個引數. Android 中的 Context 分三種,Application Context ,Activity Context ,Service Context.
它描述的是一個應用程式環境的資訊,通過它我們可以獲取應用程式的資源和類,也包括一些應用級別操作,例如:啟動一個Activity,傳送廣播,接受Intent資訊等
8.Service的onCreate回撥在UI執行緒中嗎?
Service生命週期的各個回撥和其他的應用元件一樣,是跑在主執行緒中,會影響到你的UI操作或者阻塞主執行緒中的其他事情
9.請介紹下AsyncTask的內部實現,適用的場景是?
AsyncTask內部也是Handler機制來完成的,只不過Android提供了執行框架來提供執行緒池來執行相應地任務,因為執行緒池的大小問題,所以AsyncTask只應該用來執行耗時時間較短的任務,比如HTTP請求,大規模的下載和資料庫的更改不適用於AsyncTask,因為會導致執行緒池堵塞,沒有執行緒來執行其他的任務,導致的情形是會發生AsyncTask根本執行不了的問題。
10.談談你對binder機制的理解?
binder是一種IPC機制,程式間通訊的一種工具.
Java層可以利用aidl工具來實現相應的介面.
11.Android中程式間通訊有哪些實現方式?
Intent,Binder(AIDL),Messenger,BroadcastReceiver
12.介紹下實現一個自定義view的基本流程
1、自定義View的屬性 編寫attr.xml檔案
2、在layout佈局檔案中引用,同時引用名稱空間
3、在View的構造方法中獲得我們自定義的屬性 ,在自定義控制元件中進行讀取(構造方法拿到attr.xml檔案值)
4、重寫onMesure
5、重寫onDraw
13.Android中touch事件的傳遞機制是怎樣的?
1.Touch事件傳遞的相關API有dispatchTouchEvent、onTouchEvent、onInterceptTouchEvent
2.Touch事件相關的類有View、ViewGroup、Activity
3.Touch事件會被封裝成MotionEvent物件,該物件封裝了手勢按下、移動、鬆開等動作
4.Touch事件通常從Activity#dispatchTouchEvent發出,只要沒有被消費,會一直往下傳遞,到最底層的View。
5.如果Touch事件傳遞到的每個View都不消費事件,那麼Touch事件會反向向上傳遞,最終交由Activity#onTouchEvent處理.
6.onInterceptTouchEvent為ViewGroup特有,可以攔截事件.
7.Down事件到來時,如果一個View沒有消費該事件,那麼後續的MOVE/UP事件都不會再給它
14.Android多執行緒的實現方式有哪些?
Thread & AsyncTask
Thread 可以與Loop 和 Handler 共用建立訊息處理佇列
AsyncTask 可以作為執行緒池並行處理多工
15.Android開發中何時使用多程式?使用多程式的好處是什麼?
要想知道如何使用多程式,先要知道Android裡的多程式概念。一般情況下,一個應用程式就是一個程式,這個程式名稱就是應用程式包名。我們知道程式是系統分配資源和排程的基本單位,所以每個程式都有自己獨立的資源和記憶體空間,別的程式是不能任意訪問其他程式的記憶體和資源的。
那如何讓自己的應用擁有多個程式?
很簡單,我們的四大元件在AndroidManifest檔案中註冊的時候,有個屬性是android:process,1.這裡可以指定元件的所處的程式。預設就是應用的主程式。指定為別的程式之後,系統在啟動這個元件的時候,就先建立(如果還沒建立的話)這個程式,然後再建立該元件。你可以過載Application類的onCreate方法,列印出它的程式名稱,就可以清楚的看見了。再設定android:process屬性時候,有個地方需要注意:如果是android:process=”:deamon”,以:開頭的名字,則表示這是一個應用程式的私有程式,否則它是一個全域性程式。私有程式的程式名稱是會在冒號前自動加上包名,而全域性程式則不會。一般我們都是有私有程式,很少使用全域性程式。他們的具體區別不知道有沒有誰能補充一下。
2.使用多程式顯而易見的好處就是分擔主程式的記憶體壓力。我們的應用越做越大,記憶體越來越多,將一些獨立的元件放到不同的程式,它就不佔用主程式的記憶體空間了。當然還有其他好處,有心人會發現Android後臺程式裡有很多應用是多個程式的,因為它們要常駐後臺,特別是即時通訊或者社交應用,不過現在多程式已經被用爛了。典型用法是在啟動一個不可見的輕量級私有程式,在後臺收發訊息,或者做一些耗時的事情,或者開機啟動這個程式,然後做監聽等。還有就是防止主程式被殺守護程式,守護程式和主程式之間相互監視,有一方被殺就重新啟動它。應該還有還有其他好處,這裡就不多說了。
3.壞處的話,多佔用了系統的空間,大家都這麼用的話系統記憶體很容易佔滿而導致卡頓。消耗使用者的電量。應用程式架構會變複雜,應為要處理多程式之間的通訊。這裡又是另外一個問題了。
16.ANR是什麼?怎樣避免和解決ANR?
ANR:Application Not Responding,即應用無響應
ANR一般有三種型別:
1:KeyDispatchTimeout(5 seconds) –主要型別
按鍵或觸控事件在特定時間內無響應
2:BroadcastTimeout(10
seconds)
BroadcastReceiver在特定時間內無法處理完成
3:ServiceTimeout(20
seconds) –小概率型別
Service在特定的時間內無法處理完成
超時的原因一般有兩種:
(1)當前的事件沒有機會得到處理(UI執行緒正在處理前一個事件沒有及時完成或者looper被某種原因阻塞住)
(2)當前的事件正在處理,但沒有及時完成
UI執行緒儘量只做跟UI相關的工作,耗時的工作(資料庫操作,I/O,連線網路或者其他可能阻礙UI執行緒的操作)放入單獨的執行緒處理,儘量用Handler來處理UI thread和thread之間的互動。
UI執行緒主要包括如下:
Activity:onCreate(), onResume(), onDestroy(), onKeyDown(), onClick()
AsyncTask: onPreExecute(), onProgressUpdate(), onPostExecute(), onCancel()
Mainthread handler: handleMessage(), post(runnable r)
other
17.Android下解決滑動衝突的常見思路是什麼?
相關的滑動元件 重寫onInterceptTouchEvent,然後判斷根據xy值,來決定是否要攔截當前操作
18.如何把一個應用設定為系統應用?
成為系統應用,首先要在 對應裝置的 Android 原始碼 SDK 下編譯,編譯好之後:
此 Android 裝置是 Debug 版本,並且已經 root,直接將此 apk 用 adb 工具 push 到 system/app 或 system/priv-app 下即可。
如果非 root 裝置,需要編譯後重新燒寫裝置映象即可。
有些許可權(如 WRITE_SECURE_SETTINGS ),是不開放給第三方應用的,只能在對應裝置原始碼中編譯然後作為系統 app 使用。
19、Android記憶體洩露研究
Android記憶體洩漏指的是程式中某些物件(垃圾物件)已經沒有使用價值了,但是它們卻可以直接或間接地引用到gc roots導致無法被GC回收。無用的物件佔據著記憶體空間,使得實際可使用記憶體變小,形象地說法就是記憶體洩漏了。
場景
類的靜態變數持有大資料物件
靜態變數長期維持到大資料物件的引用,阻止垃圾回收。
非靜態內部類的靜態例項
非靜態內部類會維持一個到外部類例項的引用,如果非靜態內部類的例項是靜態的,就會間接長期維持著外部類的引用,阻止被回收掉。
資源物件未關閉
資源性物件如Cursor、File、Socket,應該在使用後及時關閉。未在finally中關閉,會導致異常情況下資源物件未被釋放的隱患。
註冊物件未反註冊
未反註冊會導致觀察者列表裡維持著物件的引用,阻止垃圾回收。
Handler臨時性記憶體洩露
Handler通過傳送Message與主執行緒互動,Message發出之後是儲存在MessageQueue中的,有些Message也不是馬上就被處理的。在Message中存在一個 target,是Handler的一個引用,如果Message在Queue中存在的時間越長,就會導致Handler無法被回收。如果Handler是非靜態的,則會導致Activity或者Service不會被回收。
由於AsyncTask內部也是Handler機制,同樣存在記憶體洩漏的風險。
此種記憶體洩露,一般是臨時性的。
20.記憶體洩露檢測有什麼好方法?
檢測:
1、DDMS Heap發現記憶體洩露
dataObject totalSize的大小,是否穩定在一個範圍內,如果操作程式,不斷增加,說明記憶體洩露
2、使用Heap Tool進行記憶體快照前後對比
BlankActivity手動觸發GC進行前後對比,物件是否被及時回收
定位:
1、MAT外掛開啟.hprof具體定位記憶體洩露:
檢視histogram項,選中某一個物件,檢視它的GC引用鏈,因為存在GC引用鏈的,說明無法回收
2、AndroidStudio的Allocation Tracker:
觀測到期間的記憶體分配,哪些物件被建立,什麼時候建立,從而準確定位
一、Android的四大元件
1.Android的四大元件
Activity的主要作用是展示一個介面並和使用者互動,它扮演的是一種前臺介面的角色。
Service是一種計算型元件,用於在後臺執行一系列計算任務,但因為其本身還是執行在主執行緒中的,因此耗時的後臺計算仍然需要在單獨的執行緒中去完成。
BroadcastReceiver是一種訊息型元件,用於在不同的元件乃至不同的應用之間傳遞訊息。廣播註冊有兩種方式,動態註冊通過Context.registerReceiver()來實現,必須要應用啟動才能註冊;靜態註冊則在AndroidManifest檔案中進行,應用安裝時會被系統解析,不需要啟動應用就可接收廣播。
ContentProvider是一種共享型元件,用於向其他元件乃至其他應用共享資料。
2.Activity的四種啟動模式:standard、singleTop、singleTask和singleInstance
1. standard 標準模式。每次啟動一個Activity都會重新建立一個新的例項,不管這個例項是否已經存在;
2. singleTop 棧頂複用模式。如果新Activity已經位於任務棧的棧頂,那麼此Activity不會被重新建立,會呼叫Activity的onNewIntent方法,onCreate和onStart並不會被呼叫。(常用於應用的搜尋頁面)
3. singleTask 棧內複用模式。只要該Activity在一個棧中有例項存在,就會把它上面的Activity都清除掉,讓它置於棧頂,因為singleTask預設是具有clearTop的效果,最後onNewIntent會被回撥。如果不存在就建立一個新的Activity,壓入棧中。(常用於應用的首頁MainAcitivity)
4. singleInstance:單例項模式,這是一種加強的singleTask模式,它除了具有singleTask模式的所有特性外,還加強一點,那就是具有此種模式的Activity只能單獨地位於一個任務棧中。
任務棧是一種 “後進先出”的棧結構。
3.小知識點
1. 當前Activity的onPause方法執行結束後才會執行下一個Activity的onCreate方法,所以在onPause方法中不適合做耗時較長的工作,這會影響到頁面之間的跳轉效率;也就意味者,我們應當儘量在onStop方法中做操作,從而使得新Activity儘快的顯示出來並切換到前臺。
2. 新Activity是透明主題時,舊Activity不會走onStop;
3. 系統只有在Activity異常終止的時候才會呼叫onSavedInstanceState和onRestoreInstanceState來儲存和恢復資料,其他情況不會觸發這個過程。
4. 避免螢幕旋轉時Activity重啟生命週期,可以在AndroidManifest.xml中對應Activity標籤宣告時加上“android:configChanges=”orientation|screenSize””即可;
二、IPC機制
1、如何實現多程式?
給四大元件(Activity、Service、Receiver、ContentProvider)在AndroidManifest.xml中指定”android:process”屬性可以在應用內實現多程式,如果程式名以”:”開頭,說明該程式屬於私有程式,其他應用的元件不可以和它跑在同一個程式中,如果經常名不以”:”開頭,則屬於全域性程式,其它應用通過ShareUID方式可以和它跑在同一個程式中。
2.兩個序列化類Parcelable和Serializable的區別:
Serializable是Java中的序列化介面,其使用起來簡單但是開銷很大,序列化和反序列化過程需要大量的I/O操作。而Parcelable是Android中的序列化方式,因此更適合於用在Android平臺上,它的缺點就是使用起來稍微麻煩點,但是它的效率很高。Parceable主要用在記憶體序列化上,通過Parcelable將物件序列化到儲存裝置中或者將物件序列化後通過網路傳輸也都是可以的,但是這個過程會稍顯複雜,此種情況建議使用Serializable。
三、View機制
1.View事件分發過程
事件的分發過程由三個很重要的方法來共同完成:dispatchTouchEvent、onInterceptTouchEvent和onTouchEvent:
1. dispatchTouchEvent:用來進行事件的分發,如果事件能夠傳遞給當前View,那麼此方法一定會被呼叫,返回結果受當前View的onTouchEvent和View的dispatchTouchEvent方法的影響,表示是否當消耗當前事件;
2. onInterceptTouchEvent:用來判斷是否攔截某個事件,如果當前View攔截了某個事件,那麼在同一個事件序列當中,此方法不會被再次呼叫,返回結果表示是否攔截當前事件;
3. onTouchEvent:在dispatchTouchEvent方法中呼叫,用來處理點選事件,返回結果表示是否消耗當前事件,如果不消耗,則在同一個事件序列中,當前View無法再次接收到事件。
一些結論:攔截的一定是事件序列;不消耗ACTION_DOWN,則事件序列都會由其父元素處理;只消耗ACTION_DOWN事件,該事件會消失,消失的事件最終會交給Activity來處理;requestDisallowInterceptTouchEvent方法可以在子元素中干預父元素的事件分發過程,除了ACTION_DOWN;
2.三種方式來實現View的滑動和對比
1. 通過View本身提供的scrollTo/scrollBy方法來實現滑動;操作簡單,適合對View內容的滑動;
2. 通過動畫給View施加平移效果來實現滑動;操作簡單,適用於沒有互動的View和實現複雜的動畫效果;
3. 通過改變View的LayoutParams使得View重新佈局從而實現滑動;改變佈局引數操作稍微複雜,適用於有互動的View;
3.View的工作原理
View的繪製流程是從ViewRoot的performTraversals方法開始的,它經過measure、layout和draw三個過程才能最終將一個View繪製出來,其中measure用來測量View的寬和高,layout用來確定View在父容器中的放置位置,而draw則負責將View繪製在螢幕上。
4.setContentView()方法的由來
DecorView作為頂級View,一般情況下它內部包含一個豎直方向的LinearLayout,在這個LinearLayout裡面有上下兩個部分(具體情況和Android版本及主體有關),上面的是標題欄,下面的是內容欄。在Activity中通過setContentView所設定的佈局檔案其實就是被加到內容欄之中的,而內容欄的id是content,在程式碼中可以通過ViewGroup content = findViewById(R.android.id.content)來得到content對應的layout;
這就是為什麼Acticity的Oncreate中的setContentView()方法得來的原因,而不是叫setView()。
四、Handler和MessageQueue、Looper的關係以及原理
1.MessageQueue的工作原理:主要方法為enqueueMessage和next
- enqueueMessag主要就是一個單連結串列的插入操作
- next方法是一個無限迴圈,如果訊息佇列中沒有訊息,next方法就阻塞,有新訊息到來時,next方法會返回這條訊息並將其從單連結串列中刪除
2.Looper的工作原理:
- prepare方法,為當前沒有Looper的執行緒建立Looper。
- prepareMainLooper和getMainLooper方法用於建立和獲取ActivityThread的Looper。
- quit和quitSafely方法,前者立即退出,後者只是設定一個標記,當訊息佇列中的所有訊息處理完畢後會才安全退出。子執行緒中建立的Looper建議不需要的時候都要手動終止。 d. loop方法,死迴圈,阻塞獲取msg並丟給msg.target.dispatchMessage方法去處理,這裡的target就是handler。
3.Handler的工作原理:
- 無論sendMessage還是post最終都是呼叫的sendMessageAtTime方法。
- 傳送訊息其實就是把一條訊息通過MessageQueue的enqueueMessage方法加入訊息佇列,Looper收到訊息就會呼叫handler的dispatchMessage方法
- 當我們直接Handler h = new Handler()時,本質呼叫的是Handler(Callback callback, Boolean async)構造方法,這個方法裡會呼叫Looper.myLooper()方法,這個方法其實就是返回的ThreadLocal裡儲存的當前執行緒的Looper,這也就解釋了為什麼我們在主執行緒中這樣new Handler沒有問題,而在子執行緒中這樣會丟擲異常,因為子執行緒中並沒有Looper,所以必須先呼叫Looper.prepare,但是ActivityThread會在初始化的時候建立主執行緒也就是UI執行緒的Looper,所以我們在Activity中直接new Handler是沒有問題的。
五、AsyncTask和執行緒池
1.AsyncTask的注意事項
AsyncTask的類必須在主執行緒載入,Android4.1及以上已經被系統自動完成了;
AsyncTask物件必須在主執行緒建立;
execute方法需要在UI執行緒呼叫;
一個AsyncTask物件只能呼叫一次;
Android1.6之前序列執行,Android1.6採用執行緒池並行處理任務,Android3.0開始,採用一個執行緒執行任務,但也可以通過executeOnExecutor方法來並行執行任務。
2.常見的4個執行緒池型別
- FixedThreadPool:執行緒數量固定的執行緒池,當所有執行緒都處於活動狀態時,新任務會處於等待狀態,只有核心執行緒並且不會回收(無超時機制),能快速的響應外界請求。
- CachedThreadPool:執行緒數量不定的執行緒池,最大執行緒數為Integer.MAX_VALUE(相當於任意大),當所有執行緒都處於活動狀態時,會建立新執行緒來處理任務;執行緒池的空閒程式超時時長為60秒,超過就會被回收;任何任務都會被立即執行,適合執行大量的耗時較少的任務。
- ScheduledThreadPool:核心執行緒數量固定,非核心執行緒數量無限制,非核心執行緒閒置時會被立刻回收,用於執行定時任務和具有固定週期的重複任務。
- SingleThreadExecutor:只有一個核心執行緒,所有任務都在這個執行緒中序列執行,不需要處理執行緒同步問題
1、請你自我介紹一下你自己?
回答提示:一般人回答這個問題過於平常,只說姓名、年齡、愛好、工作經驗,這些在簡歷上都有。其實,企業最希望知道的是求職者能否勝任工作,包括:最強的技能、最深入研究的知識領域、個性中最積極的部分、做過的最成功的事,主要的成就等,這些都可以和學習無關,也可以和學習有關,但要突出積極的個性和做事的能力,說得合情合理企業才會相信。
2、你對加班的看法?
回答提示:事實上做為一枚程式猿,加班熬夜是我們的標配,比較少的公司會有不加班的現象,因為你不知道什麼時候你的程式就是那麼不聽話的崩潰了,這時你就得第一時間去處理好bug,緊急的修復並上線。
回答樣本:如果是工作需要我會義不容辭加班,我現在單身,沒有任何家庭負擔,可以全身心的投入工作。但同時,我也會提高工作效率,減少不必要的加班。
3、你覺得你個性上最大的優點是什麼?
回答提示:沉著冷靜、條理清楚、立場堅定、頑強向上、樂於助人和關心他人、適應能力和幽默感、樂觀和友愛。
4、說說你最大的缺點?
回答提示:這個問題企業問的概率很大,通常不希望聽到直接回答的缺點是什麼等,如果求職者說自己小心眼、愛忌妒人、非常懶、脾氣大、工作效率低,企業肯定不會錄用你。絕對不要自作聰明地回答“我最大的缺點是過於追求完美”,有的人以為這樣回答會顯得自己比較出色,但事實上,他已經岌岌可危了。業喜歡求職者從自己的優點說起,中間加一些小缺點,最後再把問題轉回到優點上,突出優點的部分,企業喜歡聰明的求職者。
5、你對薪資的要求?
回答提示:如果你對薪酬的要求太低,那顯然貶低自己的能力;如果你對薪酬的要求太高,那又會顯得你分量過重,公司受用不起。一些僱主通常都事先對求聘的職位定下開支預算,因而他們第一次提出的價錢往往是他們所能給予的最高價錢,他們問你只不過想證實一下這筆錢是否足以引起你對該工作的興趣。如果你自己必須說出具體數目,請不要說一個寬泛的範圍,那樣你將只能得到最低限度的數字。最好給出一個具體的數字,這樣表明你已經對當今的人才市場作了調查,知道像自己這樣學歷的僱員有什麼樣的價值。
回答樣本一:我對工資沒有硬性要求,我相信貴公司在處理我的問題上會友善合理。我注重的是找對工作機會,所以只要條件公平,我則不會計較太多。
回答樣本二:我受過系統的軟體程式設計的訓練,不需要進行大量的培訓,而且我本人也對程式設計特別感興趣。因此,我希望公司能根據我的情況和市場標準的水平,給我合理的薪水。
實戰面試談薪水
在面試時和公司談薪資,有幾點是要注意的:
•不要在一面、二面、三面等等過程中主動打探薪水、福利等,一般這會給對方留下比較差的印象,認為你只在乎錢。
•在確認公司準備聘用你之前不要談錢,因為只有公司決定聘用你的時候,才是合適的時機。
•不要先開口談錢,如果公司決定聘用你,那他們肯定會在做出決定後和你談薪水。
•確定誰是要和你談薪水的那個人,有時是 HR ,有時是副總、總監之類的,你無需詢問,也會有機會知道的。如果是 HR 來和你談薪水,她們多半是從技術線拿到了一個範圍,然後會先壓低了來和你談,要做好心理準備,適當堅持一個比 HR 提出的更高的薪水。如果是技術線上的領導直接和你談,我想你先要對面試的過程有個總結,瞭解這個人對你的印象,他是對你有強烈的興趣,還是覺得你差強人意。如果是後者,你堅持高於對方給出的薪水,很可能沒戲。無論哪種,你都要對這個職位表示出足夠的興趣來,同時也要表明你在意的不是薪水本身,而是薪水是否能與你的能力、你可以對公司帶來的價值相匹配。
•被問及期望的薪水這類問題時,不要說具體的數字,如果一定要說,說一個範圍。
•不要透露你現在的薪水,因為公司往往會根據你現在的薪水來給你定價。
•如果實在躲不過,一定要說現在的薪水,切忌撒圓不了的謊,虛報一大截子並不是明智的做法。 HR 們遠比你想象的有能力,她們很可能和你之前所在公司的 HR 或某些人認識,能在做背景調查時問到你的薪水。
•如果對方拿你現在的薪水說事兒(碰巧你現在薪水較低),你應該表明你現在的薪水與能力嚴重錯位,是不合理的,體現不了你的價值
不管你瞭解了多少談判技巧,擺平自己的心態很重要。有一部分程式設計師覺得談薪資談來談去怪不好意思怪傷感情的,其實不必,就跟你在商場買衣服一樣,爭取到合理的價位是人之常情,而且如果你不情不願地進到了公司,時候發現被壓低了工資,會產生非常消極的影響,不管對自己還是對公司,所以呢,你肯進入公司之前談個明白,是對雙方負責任的體現,因此你就不必擔心這個過程會有多大的不良影響。
6、在三到五年的時間內,你的職業規劃?
回答提示:這是每一個應聘者都不希望被問到的問題,但是幾乎每個人都會被問到,比較多的答案是“管理者”。但是近幾年來,許多公司都已經建立了專門的技術途徑。這些工作地位往往被稱作“顧問”、“參議技師”或“高階軟體工程師”等等。當然,說出其他一些你感興趣的職位也是可以的,比如產品銷售部經理,生產部經理等一些與你的專業有相關背景的工作。要知道,考官總是喜歡有進取心的應聘者,此時如果說“不知道”,或許就會使你喪失一個好機會。最普通的回答應該是“我準備在技術領域有所作為”或“我希望能按照公司的管理思路發展”。
7、你還有什麼問題要問嗎?
回答提示:企業的這個問題看上去可有可無,其實很關鍵,企業不喜歡說“沒問題”的人,因為其很注重員工的個性和創新能力。企業不喜歡求職者問個人福利之類的問題,如果有人這樣問:貴公司對新入公司的員工有沒有什麼培訓專案,我可以參加嗎?或者說貴公司的晉升機制是什麼樣的?企業將很歡迎,因為體現出你對學習的熱情和對公司的忠誠度以及你的上
8、談談你對跳槽的看法?
回答提示:①正常的“跳槽”能促進人才合理流動,應該支援。②頻繁的跳槽對單位和個人雙方都不利,應該反對。進心。
9、為什麼要離職?
回答提示:回答這個問題時一定要小心,就算在前一個工作受到再大的委屈,對公司有多少的怨言,都千萬不要表現出來,尤其要避免對公司本身主管的批評,避免面試官的負面情緒及印象。建議此時最好的回答方式是將問題歸咎在自己身上,例如覺得工作沒有學習發展的空間,自己想在面試工作的相關產業中多加學習,或是前一份工作與自己的生涯規劃不合等等,回答的答案最好是積極正面的。
回答樣本:我希望能獲得一份更好的工作,如果機會來臨,我會抓住。我覺得目前的工作,已經達到頂峰,即沒有升遷機會。
10、你對於我們公司瞭解多少?
回答提示:在去公司面試前上網查一下該公司主營業務。如回答:貴公司有意改變策略,加強與國外大廠的OEM合作,自有品牌的部分則透過海外經銷商。
11、請說出你選擇這份工作的動機?
回答提示:這是想知道面試者對這份工作的熱忱及理解度,並篩選因一時興起而來應試的人,如果是無經驗者,可以強調“就算職種不同,也希望有機會發揮之前的經驗”。
12、你最擅長的技術方向是什麼?
回答提示:說和你要應聘的職位相關的課程,表現一下自己的熱誠沒有什麼壞處。
13、喜歡這份工作的哪一點?
回答提示:相信其實大家心中一定都有答案了吧!每個人的價值觀不同,自然評斷的標準也會不同,但是,在回答面試官這個問題時可不能太直接就把自己心理的話說出來,尤其是薪資方面的問題,不過一些無傷大雅的回答是不錯的考慮,如交通方便,工作性質及內容頗能符合自己的興趣等等都是不錯的答案,不過如果這時自己能仔細思考出這份工作的與眾不同之處,相信在面試上會大大加分。
14、你為什麼願意到我們公司來工作?
回答提示:對於這個問題,你要格外小心,如果你已經對該單位作了研究,你可以回答一些詳細的原因,像“公司本身的高技術開發環境很吸引我。”、“我同公司出生在同樣的時代,我希望能夠進入一家與我共同成長的公司。”、“你們公司一直都穩定發展,在近幾年來在市場上很有競爭力。”、“我認為貴公司能夠給我提供一個與眾不同的發展道路。”這都顯示出你已經做了一些調查,也說明你對自己的未來有了較為具體的遠景規劃。
15、在完成某項工作時,你認為領導要求的方式不是最好的,自己還有更好的方法,你應該怎麼做?
回答提示:①.原則上我會尊重和服從領導的工作安排;同時私底下找機會以請教的口吻,婉轉地表達自己的想法,看看領導是否能改變想法。②如果領導沒有采納我的建議,我也同樣會按領導的要求認真地去完成這項工作。③.還有一種情況,假如領導要求的方式違背原則,我會堅決提出反對意見,如領導仍固執己見,我會毫不猶豫地再向上級領導反映。
16、如何安排自己的時間?會不會排斥加班?
回答提示:基本上,如果上班工作有效率,工作量合理的話,應該不太需要加班。可是我也知道有時候很難避免加班,加上現在工作都採用責任制,所以我會調配自己的時間,全力配合。
分析:雖然不會有人心甘情願的加班,但依舊要表現出高配合度的誠意。
17、何時可以到職?
回答提示:大多數企業會關心就職時間,最好是回答“如果被錄用的話,到職日可按公司規定上班”,但如果還未辭去上一個工作、上班時間又太近,似乎有些強人所難,因為交接至少要一個月的時間,應進一步說明原因,錄取公司應該會通融的。
18、想過創業嗎?
回答提示:這個問題可以顯示你的衝勁,但如果你的回答是“有”的話,千萬小心,下一個問題可能就是:那麼為什麼你不這樣做呢?
19、怎樣看待學歷和能力?
回答提示:學歷我想只要是大學專科的學歷,就表明覺得我具備了根本的學習能力。剩下的,你是學士也好,還是博士也好,對於這一點的討論,不是看你學了多少知識,而是看你在這個領域上發揮了什麼,也就是所說的能力問題。一個人工作能力的高低直接決定其職場命運,而學歷的高低只是進入一個企業的敲門磚,如果貴公司把學歷卡在博士上,我就無法進入貴公司,當然這不一定只是我個人的損失,如果一個專科生都能完成的工作,您又何必非要招聘一位博士生呢?
常見的人事面試問題就整理到這裡,這些都是面試中常問到的問題,只要看一遍就可以了,想想面試的時候該怎麼措辭才恰當,雖然我們不是很擅長交際,但是我們的學習能力是很強的,做程式設計的,那智商,你懂得!
Android開發面試經——2.常見Android基礎筆試題
1、Android四大元件是什麼?作用以及應用場景?
Android 的四大元件分別是是Activity,Service,BroadcastReceiver和ContentProvider;
Activity:
從字面上理解,Activity是活動的意思。一個Activity通常展現為一個視覺化的使用者介面,是Android程式與使用者互動的視窗,也是Android元件中最基本也是最複雜的一個元件。從視覺效果來看,一個Activity佔據當前的視窗,響應所有視窗事件,具備有控制元件,選單等介面元素。從內部邏輯來看,Activity需要為了保持各個介面狀態,需要做很多持久化的事情,還需要妥善管理生命週期,和一些轉跳邏輯。
Service
服務是執行在後臺的一個元件,從某從意義上說,服務就像一個沒有介面的Activity。它們在很多Android的概念方面比較接近,封裝有一個完整的功能邏輯實現,接受上層指令,完成相關的事件,定義好需要接受的Intent提供同步和非同步的介面。
BroadcastReceiver
廣播接收者,不執行任何任務,廣播是一種廣泛運用的在應用程式之間傳輸資訊的機制 。而 BroadcastReceiver 是對傳送出來的廣播進行過濾接收並響應的一類元件。Broadcast Receiver 不包含任何使用者介面。然而它們可以啟動一個Activity以響應接受到的資訊,或者通過NotificationManager通知使用者。可以通過多種方式使使用者知道有新的通知產生:閃動背景燈、震動裝置、發出聲音等等。通常程式會在狀態列上放置一個持久的圖示,使用者可以開啟這個圖示並讀取通知資訊。在Android中還有一個很重要的概念就是Intent,如果說Intent是一個對動作和行為的抽象描述,負責元件之間程式之間進行訊息傳遞。那麼Broadcast Receiver元件就提供了一種把Intent作為一個訊息廣播出去,由所有對其感興趣的程式對其作出反應的機制。
Content Provider
即內容提供者,作為應用程式之間唯一的共享資料的途徑,Content Provider 主要的功能就是儲存並檢索資料以及向其他應用程式提供訪問資料。
對應用而言,也可以將底層資料封裝成ContentProvider,這樣可以有效的遮蔽底層操作的細節,並且使程式保持良好的擴充套件性和開放性。Android提供了一些主要資料型別的Contentprovider,比如音訊、視訊、圖片和私人通訊錄等。可在android.provider包下面找到一些android提供的Contentprovider。可以獲得這些Contentprovider,查詢它們包含的資料,當然前提是已獲得適當的讀取許可權。如果我們想公開自己應用程式的資料,可以建立自己的 Content provider 的介面。
2、android中的動畫有哪幾類,它們的特點和區別是什麼?
兩種,一種是Tween動畫、還有一種是Frame動畫。Tween動畫,這種實現方式可以使檢視元件移動、放大、縮小以及產生透明度的變化;另一種Frame動畫,傳統的動畫方法,通過順序的播放排列好的圖片來實現,類似電影。
3、後臺的activity被系統回收怎麼辦?如何在被系統回收之前儲存當前狀態?
當一個Activity被pause或者stop的時候,這個Activity的物件實際上還是儲存在記憶體中,因此這個Activity中的資訊(成員和狀態資訊)還可以重新獲取到.
如果系統為了整理記憶體而銷燬了Activity物件時,系統沒法簡單的原封不動地恢復先前的Activity物件及其狀態資訊.
Activity中提供了一個方法:onSavedInstanceState(Bundle obj).當系統銷燬一個Activity時,會將Activity的狀態資訊已鍵值對形式存放在bundle物件中.
第一次啟動Activity時,這個bundle物件是空的,null.如果Activity被系統銷燬了,然後使用者要回退回去看的話,系統會呼叫這個Activity的onCreate方法,並把bundle物件傳遞過去.
4. 請描述一下Activity 生命週期。
5. 如何將一個Activity設定成視窗的樣式。
在AndroidManifest.xml 中定義Activity的地方一句話android:theme=”@android:style/Theme.Dialog”或android:theme=”@android:style/Theme.Translucent”就變成半透明的
6.註冊廣播有幾種方式,有何優缺點?
有兩種,一種是程式碼動態註冊:
//生成廣播處理
smsBroadCastReceiver = new SmsBroadCastReceiver();
//例項化過濾器並設定要過濾的廣播
IntentFilter intentFilter = new IntentFilter(“android.provider.Telephony.SMS_RECEIVED”);
//註冊廣播
BroadCastReceiverActivity.this.registerReceiver(smsBroadCastReceiver,
intentFilter);
一種是在AndroidManifest.xml中配置廣播
<!--廣播註冊-->
<receiver android:name=".SmsBroadCastReceiver">
<intent-filter android:priority="20">
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
· 1
· 2
· 3
· 4
· 5
· 6
兩種註冊型別的區別是:
1)第一種不是常駐型廣播,也就是說廣播跟隨程式的生命週期
2)第二種是常駐型,也就是說當應用程式關閉後,如果有資訊廣播來,程式也會被系統呼叫自動執行。
註冊的方法有兩種,一種是靜態註冊,一種是動態註冊。
動態註冊優點: 在 Android 的廣播機制中, 動態註冊的優先順序是要高於靜態註冊優先順序的 , 因此在必要的情況下,我們是需要動態註冊廣播接收器的。
靜態註冊優點:動態註冊廣播接收器還有一個特點,就是當用來註冊的 Activity 關掉後 ,廣播也就失效了。同時反映了靜態註冊的一個優勢,就是無需擔憂廣播接收器是否被關閉 , 只要裝置是開啟狀態,廣播接收器就是開啟著的。
7.IntentService有何優點?
普通的service ,預設執行在ui main 主執行緒
這是帶有非同步處理的service類,
非同步處理的方法 OnHandleIntent()
OnHandleIntent() 處理耗時的操作
Android的程式處理器現在會盡可能的不kill掉你
8.橫豎屏切換時候activity的生命週期?
1、不設定Activity的android:configChanges時,切屏會重新呼叫各個生命週期,切橫屏時會執行一次,切豎屏時會執行兩次
2、設定Activity的android:configChanges=”orientation”時,切屏還是會重新呼叫各個生命週期,切橫、豎屏時只會執行一次
3、設定Activity的android:configChanges=”orientation|keyboardHidden”時,切屏不會重新呼叫各個生命週期,只會執行onConfigurationChanged方法
9、如何將SQLite資料庫(dictionary.db檔案)與apk檔案一起釋出? 如何將開啟res raw目錄中的資料庫檔案?
解答:以將dictionary.db檔案複製到res raw目錄中 ,在Android中不能直接開啟res
raw目錄中的資料庫檔案,而需要在程式第一次啟動時將該檔案複製到手機記憶體或SD卡的某個目錄中,然後再開啟該資料庫檔案。複製的基本方法是使用getResources().openRawResource方法獲得res raw目錄中資源的 InputStream物件,然後將該InputStream物件中的資料寫入其他的目錄中相應檔案中。在Android
SDK中可以使用SQLiteDatabase.openOrCreateDatabase方法來開啟任意目錄中的SQLite
;
10.AndroidManifest.xml檔案中主要包含哪些資訊
說明應用程式的Java 包,該包名是應用程式的唯一標識;
描述應用程式的元件:該應用程式由哪些activity,service,broadcast receiver和content provider組成;
宣告應用程式所必須具備的許可權,用以訪問受保護的部分API,以及與其他應用程式的互動;
宣告應用程式所需要的Android API的最低版本級別,比如1.0,1.1,1.5;
manifest:根節點,描述了 package 中所有的內容。
uses-permission:請求你的 package 正常運作所需賦予的安全許可。
permission: 宣告瞭安全許可來限制哪些程式能你
package 中的元件和功能。
instrumentation:宣告瞭用來測試此 package 或其他 package 指令元件的程式碼。
application:包含 package 中 application 級別元件宣告的根節點。
activity:Activity 是用來與使用者互動的主要工具。
receiver:IntentReceiver 能使的 application 獲得資料的改變或者發生的操作,即使它當 前不在執行。
service:Service 是能在後臺執行任意時間的元件。
provider:ContentProvider 是用來管理持久化資料併發布給其他應用程式使用的元件。
11.Android資料儲存方式
一.SharedPreferences方式:它是 Android提供的用來儲存一些簡單配置資訊的一種機制,採用了
XML 格式將資料儲存到裝置中。只能在同一個包內使用,不能在不同的包之間使用。
二.檔案儲存方式 /data/data/包名/files 記憶體裡面
/ context.openFileInput(name) 預設是私有的訪問許可權
三.SQLite資料庫方式:SQLite 是 Android 所帶的一個標準的資料庫, 它支援 SQL語句,它是一個輕量級的嵌入式資料庫。
四.內容提供器(Content provider)方式:主要用於應用程式之間進行資料交換,從而能夠讓其他的應用儲存或讀取此 Content Provider 的各種資料型別。
五. 網路儲存方式: 通過網路上提供給我們的儲存空間來上傳(儲存)和下載(獲取)我們儲存 在網路空間中的資料資訊。
12.Android中常見五種佈局介紹
FrameLayout(幀佈局): 從螢幕的左上角開始佈局,疊加顯示, 實際應用 播放器的暫停按鈕.
LinearLayout (線性佈局):可分為垂直佈局,水平佈局;
AbsoluteLayout(絕對佈局):用X,Y座標來指定元素的位置;
RelativeLayout(相對佈局): 相對佈局可以理解為某一個元素為參照物,來定位的佈局方式。
TableLayout(表格佈局):表格佈局類似Html裡面的Table。每一個TableLayout裡面有表格行TableRow,TableRow裡面可以具體定義每一個元素,設定他的對齊方式 android:gravity=”” 。
每一個佈局都有自己適合的方式,另外,這五個佈局元素可以相互巢狀應用,做出美觀的介面。
13.Activity的四種啟動模式?,activity與task的啟動方式有哪些,她們的含義具體說明
standard: 標準模式,一呼叫 startActivity()方法就會產生一個新的例項。
singleTop: 如果已經有一個例項位於 Activity 棧的頂部時, 就不產生新的例項, 而只是呼叫Activity 中的 newInstance()方法。如果不位於棧頂,會產生一個新的例項。
singleTask: 會在一個新的 task 中產生這個例項,以後每次呼叫都會使用這個,不會去產生 新的例項了。
singleInstance: 這個跟 singleTask 基本上是一樣, 只有一個區別: 在這個模式下的
Activity例項所處的 task 中,只能有這個 activity例項,不能有其他的例項。
14.Android 中的長度單位詳解
如果設定表示長度 、 高度等屬性時可以使用
dp 或 sp。但如果設定字型,需要使用 sp。dp 是與密度無關,sp 除了與密度無關外,還與 scale 無關。如果螢幕密度為160,這時 dp 和 sp 和 px 是一樣
的。1dp=1sp=1px,
也就是說,如果使用 dp 和 sp,系統會根據螢幕密度的變化自動進行轉換
px :表示螢幕實際的象素
in:表示英寸,是螢幕的物理尺寸。每英寸等於2.54 釐米。
15.android 析中有哪幾種解析 l xml 的類, , , , 官方推薦哪種?以及它們的原理和區別
DOM 解析
優點:
1.XML 樹在記憶體中完整儲存,因此可以直接修改其資料和結構.
2.可以通過該解析器隨時訪問 XML 樹中的任何一個節點.
3.DOM 解析器的 API 在使用上也相對比較簡單.
缺點:如果 XML 文件體積比較大時,將文件讀入記憶體是非常消耗系統資源的
Ø SAX 解析
優點:
SAX 對記憶體的要求比較低,因為它讓開發人員自己來決定所要處理的標籤.特別是當開發人 員只需要處理文件中所包含的部分資料時,SAX
這種擴充套件能力得到了更好的體現.
缺點:
用 SAX 方式進行 XML 解析時,需要順序執行,所以很難訪問到同一文件中的不同資料.此外,在基於該方式的解析編碼過程也相對複雜
Ø Xmlpull 解析(官方推薦使用)
android SDK 提供了 xmlpull api,xmlpull 和 sax 類似,是基於流(stream)操作檔案,然後根據節點事件回撥開發者編寫的處理程式.因為是基於流的處理,因此 xmlpull 和 sax 都比較節
約記憶體資源,不會象 dom 那樣要把所有節點以對橡樹的形式展現在記憶體中.xmlpull 比 sax 更 簡明,而且不需要掃描完整個流.
16.ListView 的優化方案
(1),如果自定義介面卡,那麼在 getView 方法中要考慮方法傳進來的引數 contentView 是否 為 null,如果為 null 就建立 contentView 並返回,如果不為
null 則直接使用。在這個方法中,儘可能少建立 view。
(2),給 contentView 設定 tag(setTag()),傳入一個 viewHolder 物件,用於快取要顯示的數 據,可以達到影像資料非同步載入的效果
(3),如果 listview 需要顯示的 item 很多,就要考慮分頁載入。比如一共要顯示100條或者更多的時候,我們可以考慮先載入20條,等使用者拉到列表底部的時候,再去載入接下來的20 條。
(4) 快速滑動時不載入圖片
(5) 如果自定義的item中有圖片,需要處理圖片(減少圖片所佔記憶體)
1.對圖片進行邊界壓縮 2.用option類來儲存圖片大小 3.避免圖片的實時縮放,最好預先縮放到檢視大小
(6)儘量避免在listview介面卡中使用執行緒,因為執行緒是產生記憶體洩露的主要原因在於執行緒的生命週期不可控。
17.Android中intent的作用
在一個 Android 應用中,主要是由一些元件組成(Activity,Service,ContentProvider,etc.) 在這些元件之間的通訊中,由
Intent 協助完成。
Intent 負責對應用中一次操作的動作、動作涉及資料、附加資料
進行描述,Android 則根據此 Intent 的描述,負責找到對應的元件,將 Intent 傳遞給呼叫的元件,並完成元件的呼叫。Intent 在這裡起著實現呼叫者與被呼叫者之間的解耦作用。
有兩種方式,一種是顯示匹配,一種是隱示匹配;
顯示:明確的指定要跳轉的Activity,或者Service等;
隱示:隱式匹配,首先要匹配 Intent 的幾項值:Action,Category, Data/Type,Component如果填寫了 Componet 就是這就形成了顯示匹配。
1.如果你填寫了 Action, 如果有一個程式的
Manifest.xml 中的某一個 Activity 的 IntentFilter 段中定義了包含了相同的 Action 那麼這個 Intent 就與這個目標 Action 匹配, 如果這個 Filter段中沒有定義
Type,Category,那麼這個 Activity 就匹配了。但是如果手機中有兩個以上的程式匹配,那麼就會彈出一個對話可框來提示說明。
2,data/type,你可以用 Uri 來做為 data,比如 Uri uri = Uri.parse(http://www.google.com );
Intent i = new Intent(Intent.ACTION_VIEW,uri);手機的 Intent 分發過程中,會根據 http://www.google.com 的 scheme 判斷出資料型別 type手機的 Brower 則能匹配它,在
Brower 的 Manifest.xml 中的 IntenFilter中首先有ACTION_VIEW Action,也能處理 http:的 type;
3,至於分類 Category,一般不要去在 Intent 中設定它,如果你寫 Intent 的接收者,就在Manifest.xml 的 Activity 的 IntentFilter 中包含 android.category.DEFAULT,這樣所有不設定Category(Intent.addCategory(String
c);)的 Intent 都會與這個 Category 匹配。
4,extras(附加資訊) ,是其它所有附加資訊的集合。使用
extras 可以為元件提供擴充套件資訊 ,比如,如果要執行“傳送電子郵件”這個動作,可以將電子郵件的標題、正文等儲存在
extras裡,傳給電子郵件傳送元件。
18.如何退出 Activity ?如何安全退出?
對於單一 Activity 的應用來說,退出很簡單,直接 finish()即可。
當然,也可以用 killProcess()和 System.exit()這樣的方法。
為了程式設計方便,最好定義一個 Activity 基類,處理這些共通問題。
1、記錄開啟的 Activity:
每開啟一個 Activity,就記錄下來。在需要退出時,關閉每一個 Activity 即可。
2、傳送特定廣播:
在需要結束應用時,傳送一個特定的廣播,每個 Activity 收到廣播後,關閉即可。
1、Overload和Override的區別。Overloaded的方法是否可以改變返回值的型別?
方法的重寫Overriding和過載Overloading是Java多型性的不同表現。重寫Overriding是父類與子類之間多型性的一種表現,過載Overloading是一個類中多型性的一種表現。如果在子類中定義某方法與其父類有相同的名稱和引數,我們說該方法被重寫 (Overriding)。子類的物件使用這個方法時,將呼叫子類中的定義,對它而言,父類中的定義如同被”遮蔽”了。如果在一個類中定義了多個同名的方法,它們或有不同的引數個數或有不同的引數型別,則稱為方法的過載(Overloading)。Overloaded的方法是可以改變返回值的型別。
2、String和StringBuffer,StringBuilder的區別
String 字串常量
StringBuffer 字串變數(執行緒安全)
StringBuilder 字串變數(非執行緒安全)
String的長度是不可變的,StringBuffer,StringBuilder的長度是可變的。如果你對字串中的內容經常進行操作,特別是內容要修改時,那麼使用StringBuffer,如果最後需要String,那麼使用StringBuffer的toString()方法。
3、說出ArrayList,Vector, LinkedList的儲存效能和特性
ArrayList和Vector都是使用陣列方式儲存資料,此陣列元素數大於實際儲存的資料以便增加和插入元素,它們都允許直接按序號索引元素,但是插入元素要涉及陣列元素移動等記憶體操作,所以索引資料快而插入資料慢,Vector由於使用了synchronized方法(執行緒安全),通常效能上較ArrayList差,而LinkedList使用雙向連結串列實現儲存,按序號索引資料需要進行前向或後向遍歷,但是插入資料時只需要記錄本項的前後項即可,所以插入速度較快。
4.字串“abcde”通過寫一個函式不讓呼叫第三方的字串,實現一個字串倒序,比如字串“abcde”變成“edcba”
String src = “abcde”;
String dst = new StringBuffer(src).reverse().toString();
5、Collection 和 Collections的區別。
Collection是集合類的上級介面,繼承與他的介面主要有Set 和List.
Collections是針對集合類的一個幫助類,他提供一系列靜態方法實現對各種集合的搜尋、排序、執行緒安全化等操作
6、final, finally, finalize的區別。
final 用於宣告屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。
finally是異常處理語句結構的一部分,表示總是執行。
finalize是Object類的一個方法,在垃圾收集器執行的時候會呼叫被回收物件的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉檔案等。
7、sleep() 和 wait() 有什麼區別?
1.這兩個方法來自不同的類分別是,sleep來自Thread類,和wait來自Object類。
2.最主要是sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其他執行緒可以使用同步控制塊或者方法。sleep不出讓系統資源;wait是進入執行緒等待池等待,出讓系統資源,其他執行緒可以佔用CPU。一般wait不會加時間限制,因為如果wait執行緒的執行資源不夠,再出來也沒用,要等待其他執行緒呼叫notify/notifyAll喚醒等待池中的所有執行緒,才會進入就緒佇列等待OS分配系統資源。sleep(milliseconds)可以用時間指定使它自動喚醒過來,如果時間不到只能呼叫interrupt()強行打斷。
3.wait,notify和notifyAll只能在同步控制方法或者同步控制塊裡面使用,而sleep可以在任何地方使用
4. Sleep需要捕獲異常,而wait不需要
8、同步和非同步有何異同,在什麼情況下分別使用他們?舉例說明。
如果資料將線上程間共享。例如正在寫的資料以後可能被另一個執行緒讀到,或者正在讀的資料可能已經被另一個執行緒寫過了,那麼這些資料就是共享資料,必須進行同步存取。
當應用程式在物件上呼叫了一個需要花費很長時間來執行的方法,並且不希望讓程式等待方法的返回時,就應該使用非同步程式設計,在很多情況下采用非同步途徑往往更有效率。
9,抽象類與介面的區別(abstract與interface的區別)
abstract可以修飾抽象方法,而一個類只要有一個抽象方法,就必須用abstract定義該類,即抽象類。
用interface修飾的類,裡面的方法都是抽象方法,因此在定義介面的時候,可以直接不加那些修飾,系統會預設的添上去。介面裡面的欄位都是公有常量,即public static final修飾的欄位。
10、執行緒中wait,join,sleep,yield, notify,notifyall,synchronized,區別及聯絡
1).sleep()方法
在指定時間內讓當前正在執行的執行緒暫停執行,但不會釋放“鎖標誌”。不推薦使用。sleep()使當前執行緒進入阻塞狀態,在指定時間內不會執行。
2).wait()方法
在其他執行緒呼叫物件的notify或notifyAll方法前,導致當前執行緒等待。執行緒會釋放掉它所佔有的“鎖標誌”,從而使別的執行緒有機會搶佔該鎖。
喚醒當前物件鎖的等待執行緒使用notify或notifyAll方法,waite() 和notify()必須在synchronized函式或synchronized block中進行呼叫。
yield方法暫停當前正在執行的執行緒物件。yield()只是使當前執行緒重新回到可執行狀態,所以執行
3)yield()的執行緒有可能在進入到可執行狀態後馬上又被執行。yield()只能使同優先順序或更高優先順序的執行緒有執行的機會。
4).join方法
等待該執行緒終止。等待呼叫join方法的執行緒結束,再繼續執行。如:t.join();//主要用於等待t執行緒執行結束,若無此句,main則會執行完畢,導致結果不可預測。
11、介面是否可繼承介面? 抽象類是否可實現(implements)介面? 抽象類是否可繼承實體類(concrete class)?
介面可以繼承介面。抽象類可以實現(implements)介面,抽象類是否可繼承實體類,但前提是實體類必須有明確的建構函式。
12、abstract的method是否可同時是static,是否可同時是native,是否可同時是synchronized?
13、是否可以繼承String類?
String類是final類故不可以繼承。
14、Java switch支援的資料型別:
java支援的資料型別有五種
他們分別是:
byte、char、short、int、列舉
以上是JDK1.6以前的版本。JDK1.7時,又增加了String,所以相對於JDK1.7而言就是六種了
15、什麼是單例模式,請寫出一個來:
Singleton模式主要作用是保證在Java應用程式中,一個類Class只有一個例項存在。
一般Singleton模式通常有幾種種形式:
第一種形式: 定義一個類,它的建構函式為private的,它有一個static的private的該類變數,在類初始化時例項話,通過一個public的getInstance方法獲取對它的引用,繼而呼叫其中的方法。
publicclass
Singleton {
privateSingleton
(){}
//注意這是private 只供內部呼叫
private
static
Singleton instance =
newSingleton();
//這裡提供了一個供外部訪問本class的靜態方法,可以直接訪問
public
static
Singleton
getInstance() {
return
instance;
}
}
第二種形式
:
publicclass
Singleton {
private
static
Singleton instance =
null;
public
static
synchronized Singleton
getInstance() {
//這個方法比上面有所改進,不用每次都進行生成物件,只是第一次
//使用時生成例項,提高了效率!
if
(instance==
null)
instance
=
newSingleton();
return instance; }
}
其他形式:
定義一個類,它的建構函式為private的,所有方法為static的。
一般認為第一種形式要更加安全些
16、Java常用的設計模式?說明工廠模式。
Java中的23種設計模式:
Factory(工廠模式), Builder(建造模式), Factory Method(工廠方法模式),
Prototype(原始模型模式),Singleton(單例模式), Facade(門面模式),
Adapter(介面卡模式), Bridge(橋樑模式), Composite(合成模式),
Decorator(裝飾模式), Flyweight(享元模式), Proxy(代理模式),
Command(命令模式), Interpreter(直譯器模式), Visitor(訪問者模式),
Iterator(迭代子模式), Mediator(調停者模式), Memento(備忘錄模式),
Observer(觀察者模式), State(狀態模式), Strategy(策略模式),
Template Method(模板方法模式), Chain Of Responsibleity(責任鏈模式)
工廠模式:工廠模式是一種經常被使用到的模式,根據工廠模式實現的類可以根據提供的資料生成一組類中某一個類的例項,
通常這一組類有一個公共的抽象父類並且實現了相同的方法,但是這些方法針對不同的資料進行了不同的操作。
首先需要定義一個基類,該類的子類通過不同的方法實現了基類中的方法。然後需要定義一個工廠類,工廠類可以根據條件
生成不同的子類例項。當得到子類的例項後,開發人員可以呼叫基類中的方法而不必考慮到底返回的是哪一個子類的例項。
Android開發面試經——4.常見Android進階筆試題(更新中...)
1.什麼是ANR,如何避免?
ANR:Application Not Responding。
在 Android 中,活動管理器和視窗管理器這兩個系統服務負責監視應用程式的響應。當出現下列情況時,Android 就會顯示 ANR 對話方塊了:
①.使用者對應用程式的操作(如輸入事件,按鍵、觸控式螢幕事件)在5秒內無響應
②. 廣播接受器(BroadcastReceiver)在10秒內仍未執行完畢
Android 應用程式完全執行在一個獨立的執行緒中(例如 main)。這就意味著,任何在主 執行緒中執行的,需要消耗大量時間的操作都會引發
ANR。因為此時,你的應用程式已經沒有機會去響應輸入事件和意向廣播(Intentbroadcast)。
避免方法:Activity 應該在它的關鍵生命週期方法(如 onCreate()和 onResume())裡儘可能少的去做建立操作,
潛在的耗時操作。例如網路或資料庫操作,或者高耗時的計算如改變點陣圖尺寸,應該在子執行緒裡(或者非同步方式)來完成。
主執行緒應該為子執行緒提供一個 Handler,以便完成時能夠提交給主執行緒。
2.Handler機制原理?
andriod 提供了 Handler 和 Looper 來滿足執行緒間的通訊。Handler 先進先出原則。
Looper 類用來管理特定執行緒內物件之間的訊息交換 (MessageExchange)。
1)Looper: 一個執行緒可以產生一個 Looper 物件,由它來管理此執行緒裡的 MessageQueue(訊息佇列)。
2)Handler: 你可以構造 Handler 物件來與 Looper 溝通,以便 push 新訊息到 MessageQueue 裡;或者接收 Looper 從 MessageQueue 取出)所送來的訊息。
3) Message Queue(訊息佇列 ): 用來存放執行緒放入的訊息。
4)執行緒: UI thread 通常就是 main thread, 而 Android 啟動程式時會替它建立一個
MessageQueue。
3.請解釋下在單執行緒模型中Message、Handler、Message Queue、Looper之間的關係。
簡單的說,Handler獲取當前執行緒中的 looper物件,looper 用來從存放 Message 的 MessageQueue中取出 Message,再有 Handler 進行 Message 的分發和處理.
Message Queue(訊息佇列): 用來存放通過
Handler 釋出的訊息, 通常附屬於某一個建立它的執行緒,可以通過
Looper.myQueue()得到當前執行緒的訊息佇列
Handler:可以釋出或者處理一個訊息或者操作一個 Runnable,通過 Handler釋出訊息, 訊息將只會傳送到與它關聯的訊息佇列,然也只能處理該訊息佇列中的訊息
Looper:是 Handler 和訊息佇列之間通訊橋樑,程式元件首先通過 Handler 把訊息傳遞給 Looper,Looper 把訊息放入佇列。Looper 也把訊息佇列裡的訊息廣播給所有的
Handler:Handler 接受到訊息後呼叫 handleMessage進行處理
Message:訊息的型別,在 Handler 類中的 handleMessage 方法中得到單個的訊息進行處理
在單執行緒模型下, 為了執行緒通訊問題,
Android 設計了一個 Message Queue(訊息佇列), 執行緒間可以通過該
Message Queue 並結合 Handler 和 Looper 元件進行資訊交換。
下面將對它 們進行分別介紹:
1. Message
Message 訊息,理解為執行緒間交流的資訊,處理資料後臺執行緒需要更新 UI ,則傳送Message 內含一些資料給 UI 執行緒。
2. Handler
Handler處理者,是 Message 的主要處理者,負責 Message 的傳送,Message 內容的執行處理。後臺執行緒就是通過傳進來的 Handler物件引用來 sendMessage(Message)。
而使用 Handler,需要 implement 該類的 handleMessage(Message)方法,它是處理這些
Message 的操作內容,例如 Update UI 。通常需要子類化 Handler 來實現 handleMessage方法。
3. Message Queue
Message Queue 訊息佇列,用來存放通過 Handler 釋出的訊息,按照先進先出執行。每個 message queue 都會有一個對應的 Handler。Handler 會向 messagequeue 通過兩種方法傳送訊息:sendMessage 或 post。這兩種訊息都會插在 message queue 隊尾並
按先進先出執行。但通過這兩種方法傳送的訊息執行的方式略有不同:通過 sendMessage傳送的是一個 message 物件,會被 Handler 的 handleMessage()函式處理;而通過 post 方法傳送的是一個 runnable 物件,則會自己執行。
4. Looper
Looper 是每條執行緒裡的 Message Queue 的管家。Android 沒有 Global 的MessageQueue,而 Android 會自動替主執行緒(UI 執行緒)建立 Message Queue,但在子執行緒裡並沒有建立 Message Queue。 所以呼叫
Looper.getMainLooper()得到的主執行緒的 Looper 不為 NULL,但呼叫 Looper.myLooper()得到當前執行緒的 Looper 就有可能為 NULL。
4.Android 中執行緒與執行緒,程式與程式之間如何通訊
1、一個 Android 程式開始執行時,會單獨啟動一個 Process。
預設情況下,所有這個程式中的 Activity 或者 Service 都會跑在這個 Process。
預設情況下,一個 Android 程式也只有一個 Process,但一個 Process 下卻可以有許多個 Thread。
2、一個 Android 程式開始執行時,就有一個主執行緒 MainThread 被建立。該執行緒主要負責 UI 介面的顯示、更新和控制元件互動,所以又叫 UI Thread。
一個 Android 程式建立之初,一個 Process 呈現的是單執行緒模型–即 Main Thread,
所有的任務都在一個執行緒中執行。所以,Main Thread 所呼叫的每一個函式,其耗時應該
越短越好。而對於比較費時的工作,應該設法交給子執行緒去做,以避免阻塞主執行緒(主執行緒被阻塞,會導致程式假死 現象) 。
3、Android 單執行緒模型:Android UI 操作並不是執行緒安全的並且這些操作必須在 UI 執行緒中執行。如果在子執行緒中直接修改 UI,會導致異常。
4.Android 的 的 IPC ( 程式間通訊 ) 機制
IPC 是內部程式通訊的簡稱, 是共享 ” 命名管道 ” 的資源。Android 中的 IPC機制是為了讓
Activity 和 Service之間可以隨時的進行互動,故在 Android 中該機制,只適用於 Activity 和 Service之間的通訊,類似於遠端方法呼叫,類似於 C/S 模式的訪問。通過定義 AIDL 介面檔案來定義 IPC 介面。Servier 端實現 IPC介面,Client 端呼叫 IPC介面本地代理。
5.Android應用程式框架
6.View, surfaceView, GLSurfaceView的區別
View 是最基礎的,必須在 UI 主執行緒內更新畫面,速度較慢。
SurfaceView 是 view 的子類,類似使用雙緩機制,在新的執行緒中更新畫面所以重新整理介面速度比 view 快 GLSurfaceView 是 SurfaceView 的子類,opengl 專用的。
區別:SurfaceView是從View基類中派生出來的顯示類,直接子類有GLSurfaceView和VideoView,可以看出GL和視訊播放以及Camera攝像頭一般均使用SurfaceView
SurfaceView和View最本質的區別在於,surfaceView是在一個新起的單獨執行緒中可以重新繪製畫面而View必須在UI的主執行緒中更新畫面。
那麼在UI的主執行緒中更新畫面 可能會引發問題,比如你更新畫面的時間過長,那麼你的主UI執行緒會被你正在畫的函式阻塞。那麼將無法響應按鍵,觸屏等訊息。
當使用surfaceView 由於是在新的執行緒中更新畫面所以不會阻塞你的UI主執行緒。但這也帶來了另外一個問題,就是事件同步。比如你觸屏了一下,你需要surfaceView中thread處理,一般就需要有一個event queue的設計來儲存touch event,這會稍稍複雜一點,因為涉及到執行緒同步。
7. AIDL的全稱是什麼?如何工作?
AIDL 全稱 Android Interface Definition Language(Android 介面描述語言)是一種介面描述語言 ;
編譯器可以通過 aidl檔案生成一段程式碼, 通過預先定義的介面達到兩個程式內
部通訊程式跨界物件訪問的目的.AIDL 的 IPC 的機制和 COM 或 CORBA 類似 , 是基於介面的, 但它是輕量級的。 它使用代理類在客戶端和實現層間傳遞值 .
如果要使用 AIDL, 需要完成2件事情 :
1. 引入AIDL的相關類 .;
2. 呼叫 aidl產生的 class.理論上 , 引數可以傳遞基本資料型別和String, 還有就是Bundle的派生類
當A程式要去呼叫B程式中的service時,並實現通訊,我們通常都是通過AIDL來操作的 。
A工程:
首先我們在net.blogjava.mobile.aidlservice包中建立一個RemoteService.aidl檔案,在裡面我們自定義一個介面,含有方法get。ADT外掛會在gen目錄下自動生成一個RemoteService.java檔案,該類中含有一個名為RemoteService.stub的內部類,該內部類中含有aidl檔案介面的get方法。
說明一:aidl檔案的位置不固定,可以任意
然後定義自己的MyService類,在MyService類中自定義一個內部類去繼承RemoteService.stub這個內部類,實現get方法。在onBind方法中返回這個內部類的物件,系統會自動將這個物件封裝成IBinder物件,傳遞給他的呼叫者。
其次需要在AndroidManifest.xml檔案中配置MyService類,程式碼如下:
<!-- 註冊服務 -->
<service android:name=".MyService">
<intent-filter>
<!-- 指定呼叫AIDL服務的ID -->
<action android:name="net.blogjava.mobile.aidlservice.RemoteService" />
</intent-filter>
</service>
為什麼要指定呼叫AIDL服務的ID,就是要告訴外界MyService這個類能夠被別的程式訪問,只要別的程式知道這個ID,正是有了這個ID,B工程才能找到A工程實現通訊。
說明:AIDL並不需要許可權
B工程:
首先我們要將A工程中生成的RemoteService.java檔案拷貝到B工程中,在bindService方法中繫結aidl服務
繫結AIDL服務就是將RemoteService的ID作為intent的action引數。
說明:如果我們單獨將RemoteService.aidl檔案放在一個包裡,那個在我們將gen目錄下的該包拷貝到B工程中。如果我們將RemoteService.aidl檔案和我們的其他類存放在一起,那麼我們在B工程中就要建立相應的包,以保證RmoteService.java檔案的報名正確,我們不能修改RemoteService.java檔案
bindService(new Inten(“net.blogjava.mobile.aidlservice.RemoteService”),
serviceConnection, Context.BIND_AUTO_CREATE);
ServiceConnection的onServiceConnected(ComponentName name, IBinder service)方法中的service引數就是A工程中MyService類中繼承了RemoteService.stub類的內部類的物件。
8.關於AndroidOOM,以及如何避免?
Android的虛擬機器是基於暫存器的Dalvik,它的最大堆大小一般是16M,有的機器為24M。因此我們所能利用的記憶體空間是有限的。如果我們的記憶體佔用超過了一定的水平就會出現OutOfMemory的錯誤。
①.為什麼會出現記憶體不夠用的情況呢?我想原因主要有兩個:由於我們程式的失誤,長期保持某些資源(如Context)的引用,造成記憶體洩露,資源造成得不到釋放。儲存了多個耗用記憶體過大的物件(如Bitmap),造成記憶體超出限制。
② .如何避免優化?
1、應該儘量避免static成員變數引用資源耗費過多的例項,比如Context。Context儘量使用Application Context,因為Application的Context的生命週期比較長,引用它不會出現記憶體洩露的問題。使用WeakReference代替強引用。比如可以使用WeakReference mContextRef;
2、執行緒也是造成記憶體洩露的一個重要的源頭。執行緒產生記憶體洩露的主要原因在於執行緒生命週期的不可控。將執行緒的內部類,改為靜態內部類。3、Bitmap問題:可以說出現OutOfMemory問題的絕大多數人,都是因為Bitmap的問題。因為Bitmap佔用的記憶體實在是太多了,它是一個“超級大胖子”,特別是解析度大的圖片,如果要顯示多張那問題就更顯著了。
如何解決Bitmap帶給我們的記憶體問題?
及時的銷燬。 雖然,系統能夠確認Bitmap分配的記憶體最終會被銷燬,但是由於它佔用的記憶體過多,所以很可能會超過java堆的限制。因此,在用完Bitmap時,要及時的recycle掉。recycle並不能確定立即就會將Bitmap釋放掉,但是會給虛擬機器一個暗示:“該圖片可以釋放了”。設定一定的取樣率。 有時候,我們要顯示的區域很小,沒有必要將整個圖片都載入出來,而只需要記載一個縮小過的圖片,這時候可以設定一定的取樣率,那麼就可以大大減小佔用的記憶體。如下面的程式碼: BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;//圖片寬高都為原來的二分之一,即圖片為原來的四分之一。
4、巧妙的運用軟引用(SoftRefrence) 有些時候,我們使用Bitmap後沒有保留對它的引用,因此就無法呼叫Recycle函式。這時候巧妙的運用軟引用,可以使Bitmap在記憶體快不足時得到有效的釋放
5、及時釋放Cursor;
6、儘量使用9path圖片。Adapter要使用convertView複用等等;
9. AsyncTask 的介紹
在開發 Android 移動客戶端的時候往往要使用多執行緒來進行操作, 我們通常會將耗時的操作放在單獨的執行緒執行, 避免其佔用主執行緒而給使用者帶來不好的使用者體驗。 但是在子執行緒中無法 去操作主執行緒(UI
執行緒) ,在子執行緒中操作
UI 執行緒會出現錯誤。因此 android 提供了一個類 Handler 來在子執行緒中來更新 UI 執行緒,用發訊息的機制更新 UI 介面,呈現給使用者。 這樣就解決了子執行緒更新
UI 的問題。但是費時的任務操作總會啟動一些匿名的子執行緒,太多的子執行緒給系統帶來巨大的負擔,隨之帶來一些效能問題。因此 android 提供了一個工具類AsyncTask,顧名思義非同步執行任務。這個 AsyncTask 生來就是處理一些後臺的比較耗時的任務,給使用者帶來良好使用者體驗的,從程式設計的語法上顯得優雅了許多,不再需要子執行緒和Handler就可以完成非同步操作並且重新整理使用者介面。
10.說說mvc模式的原理,它在android中的運用
答:android的官方建議應用程式的開發採用mvc模式。何謂mvc?
mvc是model,view,controller的縮寫,mvc包含三個部分:
l、模型(model)物件:是應用程式的主體部分,所有的業務邏輯都應該寫在該層。
2、檢視(view)物件:是應用程式中負責生成使用者介面的部分。也是在整個mvc架構中使用者唯一可以看到的一層,接收使用者的輸入,顯示處理結果。
3、控制器(control)物件:是根據使用者的輸入,控制使用者介面資料顯示及更新model物件狀態的部分,控制器更重要的一種導航功能,想用使用者出發的相關事件,交給m處理。
android鼓勵弱耦合和元件的重用,在android中mvc的具體體現如下:
1)檢視層(view):一般採用xml檔案進行介面的描述,使用的時候可以非常方便的引入,當然,如何你對android瞭解的比較的多了話,就一定 可以想到在android中也可以使用javascript+html等的方式作為view層,當然這裡需要進行java和javascript之間的通 信,幸運的是,android提供了它們之間非常方便的通訊實現。
2)控制層(controller):android的控制層的重 任通常落在了眾多的acitvity的肩上,這句話也就暗含了不要在acitivity中寫程式碼,要通過activity交割model業務邏輯層處理, 這樣做的另外一個原因是android中的acitivity的響應時間是5s,如果耗時的操作放在這裡,程式就很容易被回收掉。
3)模型層(model):對資料庫的操作、對網路等的操作都應該在model裡面處理,當然對業務計算等操作也是必須放在的該層的。
11.根據自己的理解描述下Android數字簽名。
答:(1)所有的應用程式都必須有數字證照,Android系統不會安裝一個沒有數字證照的應用程式
(2)Android程式包使用的數字證照可以是自簽名的,不需要一個權威的數字證照機構簽名認證
(3)如果要正式釋出一個Android ,必須使用一個合適的私鑰生成的數字證照來給程式簽名,而不能使用adt外掛或者ant工具生成的除錯證照來發布。
(4)數字證照都是有有效期的,Android只是在應用程式安裝的時候才會檢查證照的有效期。如果程式已經安裝在系統中,即使證照過期也不會影響程式的正常功能
12. 談談對 Android NDK 的理解
NDK 全稱:Native Development Kit。
1、NDK 是一系列工具的集合。 * NDK 提供了一系列的工具,幫助開發者快速開發 C(或 C++)的動態庫,並能自動將 so 和 java 應用
一起打包成 apk。這些工具對開發者的幫助是巨大的。 * NDK 整合了交叉編譯器,並提供了相應的 mk 檔案隔離 CPU、平臺、ABI 等差異,開發人員只需要簡單修改 mk 檔案(指出“哪些檔案需要編譯”、“編譯特性要求”等) ,就可以建立出
so。 * NDK 可以自動地將
so 和 Java 應用一起打包,極大地減輕了開發人員的打包工作。
2、NDK 提供了一份穩定、功能有限的 API 標頭檔案宣告。 Google 明確宣告該 API 是穩定的,在後續所有版本中都穩定支援當前釋出的 API。從該版本的 NDK 中看出,這些 API 支援的功能非常有限,
包含有:C 標準庫(libc) 、標準數學庫(libm) 、壓縮庫(libz) 、Log 庫(liblog) 。
13.ViewStub的應用
在開發應用程式的時候,經常會遇到這樣的情況,會在執行時動態根據條件來決定顯示哪個View或某個佈局。那麼最通常的想法就是把可能用到的View都寫在上面,先把它們的可見性都設為View.GONE,然後在程式碼中動態的更改它的可見性。這樣的做法的優點是邏輯簡單而且控制起來比較靈活。但是它的缺點就是,耗費資源。雖然把View的初始可見View.GONE但是在Inflate佈局的時候View仍然會被Inflate,也就是說仍然會建立物件,會被例項化,會被設定屬性。也就是說,會耗費記憶體等資源。
推薦的做法是使用android.view.ViewStub,ViewStub是一個輕量級的View,它一個看不見的,不佔佈局位置,佔用資源非常小的控制元件。可以為ViewStub指定一個佈局,在Inflate佈局的時候,只有ViewStub會被初始化,然後當ViewStub被設定為可見的時候,或是呼叫了ViewStub.inflate()的時候,ViewStub所向的佈局就會被Inflate和例項化,然後ViewStub的佈局屬性都會傳給它所指向的佈局。這樣,就可以使用ViewStub來方便的在執行時,要還是不要顯示某個佈局。
但ViewStub也不是萬能的,下面總結下ViewStub能做的事兒和什麼時候該用ViewStub,什麼時候該用可見性的控制。
首先來說說ViewStub的一些特點:
1. ViewStub只能Inflate一次,之後ViewStub物件會被置為空。按句話說,某個被ViewStub指定的佈局被Inflate後,就不會夠再通過ViewStub來控制它了。
2. ViewStub只能用來Inflate一個佈局檔案,而不是某個具體的View,當然也可以把View寫在某個佈局檔案中。
基於以上的特點,那麼可以考慮使用ViewStub的情況有:
1. 在程式的執行期間,某個佈局在Inflate後,就不會有變化,除非重新啟動。
因為ViewStub只能Inflate一次,之後會被置空,所以無法指望後面接著使用ViewStub來控制佈局。所以當需要在執行時不止一次的顯示和隱藏某個佈局,那麼ViewStub是做不到的。這時就只能使用View的可見性來控制了。
2. 想要控制顯示與隱藏的是一個佈局檔案,而非某個View。
因為設定給ViewStub的只能是某個佈局檔案的Id,所以無法讓它來控制某個View。
所以,如果想要控制某個View(如Button或TextView)的顯示與隱藏,或者想要在執行時不斷的顯示與隱藏某個佈局或View,只能使用View的可見性來控制。
1.HttpURLConnection和HttpClient他們各自的優缺點是什麼?
HttpUrlConnection 在 2.3 以前的版本是有 bug 的,所以之前的版本推薦使用 HttpClient,但是 google 現在已經不維護 HttpClient 了,5.1裡面已經把 HttpClient 標過期。另外 HttpURLConnection 支援gzip壓縮等,推薦首選它。
在 Froyo(2.2) 之前,HttpURLConnection 有個重大 Bug,呼叫 close() 函式會影響連線池,導致連線複用失效,所以在
Froyo 之前使用 HttpURLConnection 需要關閉 keepAlive。
另外在 Gingerbread(2.3) HttpURLConnection 預設開啟了 gzip 壓縮,提高了
HTTPS 的效能,Ice Cream Sandwich(4.0) HttpURLConnection 支援了請求結果快取。
再加上 HttpURLConnection 本身 API 相對簡單,所以對 Android 來說,在 2.3 之後建議使用
HttpURLConnection,之前建議使用 AndroidHttpClient。
2.Android開發中XML解析方式的比較,及優缺點?
DOM,SAX,Pull解析。
SAX解析器的優點是解析速度快,佔用記憶體少;
DOM在記憶體中以樹形結構存放,因此檢索和更新效率會更高。但是對於特別大的文件,解析和載入整個文件將會很耗資源,不適合移動端;
PULL解析器的執行方式和SAX類似,都是基於事件的模式,PULL解析器小巧輕便,解析速度快,簡單易用,非常適合在Android移動裝置中使用,Android系統內部在解析各種XML時也是用PULL解析器。
3.請問平時開發過程中,你是如何做到多解析度適配的?
1.根據不同解析度建立不同的佈局檔案
2.根據解析度不同建立不同解析度的資源圖片
3.在程式啟動時,獲取當前螢幕的解析度和密度,在程式碼中進行適配
4.為不同解析度的寫不同的dimen檔案。
5.其實還有就是多使用fragement
4. 談談你在工作中是怎樣解決一個bug的?
1.看Log日誌
2.Log解決不了就斷點除錯
3.如果debug不行
4.就在異常程式碼的附近Log.e(“error”,”1”);,2,3,4,5,6,7,8,9 每隔一行一個Log輸出,看結果
5.找到問題,自行找思路。如果是技術瓶頸,就google之
5.宣告ViewHolder內部類時,為什麼建議使用static關鍵字?
其實這個是考靜態內部類和非靜態內部類的主要區別之一。非靜態內部類會隱式持有外部類的引用,就像大家經常將自定義的adapter在Activity類裡,然後在adapter類裡面是可以隨意呼叫外部activity的方法的。當你將內部類定義為static時,你就呼叫不了外部類的例項方法了,因為這時候靜態內部類是不持有外部類的引用的。宣告ViewHolder靜態內部類,可以將ViewHolder和外部類解引用。大家會說一般ViewHolder都很簡單,不定義為static也沒事吧。確實如此,但是如果你將它定義為static的,說明你懂這些含義。萬一有一天你在這個ViewHolder加入一些複雜邏輯,做了一些耗時工作,那麼如果ViewHolder是非靜態內部類的話,就很容易出現記憶體洩露。如果是靜態的話,你就不能直接引用外部類,迫使你關注如何避免相互引用。 所以將 ViewHolder內部類 定義為靜態的,是一種好習慣.
非靜態內部類隱式持有外部類的強引用,只是可能會導致記憶體洩露,而一般情況下在使用viewhodler是不會導致記憶體洩露的,加static是一個比較好的習慣
6.如何在不失真的條件下顯示一張超高清的圖片或者長圖?
1、通過計算BitmapFactory.Options 物件的inSamleSize 值 等比的壓縮圖片 。
2、使用WebView來載入該圖片;
3、使用MapView或者TileView來顯示圖片(類似地圖的機制);
7. Android中有哪些方法實現定時和延時任務?它們的適用場景是什麼?
倒數計時類
用CountDownTimer
延遲類
CountDownTimer,可巧妙的將countDownInterval設成和millisInFuture一樣,這樣就只會呼叫一次onTick和一次onFinish
handler.sendMessageDelayed,可參考CountDownTimer的內部實現,簡化一下,個人比較推薦這個
TimerTask,程式碼寫起來比較亂
Thread.sleep,感覺這種不太好
使用Handler方法postDelay(runnable, delayTime)
定時類
參照延遲類的,自己計算好要延遲多少時間
handler.sendMessageAtTime
AlarmManager,適用於定時比較長遠的時間,例如鬧鈴
8.談談你對StrongReference、WeakReference和SoftReference的認識
強引用(StrongReference):就是在程式碼中普遍存在的,類似Object obj = new Object()這類的引用,只要強引用還存在,GC永遠不會回收掉被引用的物件。
軟引用(SoftReference):用來描述一些還有用但非必須的物件。對於軟引用關聯著的物件,在系統將要發生記憶體溢位異常時,將會把這些物件列入回收範圍之中進行第二次回收。如果這次回收還沒有足夠的記憶體,才會丟擲記憶體溢位異常。在JDK 1.2之後,提供了SoftReference類來實習軟引用。
弱引用(WeakReference):也是用來描述非必須物件的,但是它的強度比軟引用更弱一些,被弱引用關聯的物件只能生存到了下一次GC發生之前。當GC工作時,無論當時記憶體是否足夠,都會回收只被弱引用關聯的物件。在JDK 1.2之後,提供了WeakReference類來實現弱引用。
虛引用(PhantomReference):這個引用po主沒有提到,不過也可以順帶了解一下。虛引用也稱幽靈引用或者幻影引用,它是最弱的一種引用關係。一個物件是否有虛引用的存在,完全不會對其生存時間構成影響,也無法通過虛引用來取得一個物件例項。為一個物件設定虛引用的唯一目的就是在這個物件被GC回收是收到一個系統通知。在JDK 1.2之後提供了PhantomReference類來實現虛引用。
9.你應用中的網路層是怎麼設計的?
1. android-async-http.
封裝了下常用的方法,get post 上傳 下載 ,所有的請求我都是用的同步請求.
具體的用法一般都是和業務邏輯在一起,而我的業務邏輯是用非同步去處理的.
關於網路請求結果的快取,我是單獨處理的.並沒有放在網路層.
2.在HttpUrlConnection基礎上封裝, 包括請求成功, 失敗, 請求中, 網路問題等封裝, 利用廣播與UI互動
3.直接使用xUtils,afinal,okHttp,Volley等開源第三方框架;
Bitmap是android中經常使用的一個類,它代表了一個圖片資源。
Bitmap消耗記憶體很嚴重,如果不注意優化程式碼,經常會出現OOM問題,優化方式通常有這麼幾種:
1. 使用快取;
2. 壓縮圖片;
3. 及時回收;
10.談談你對Bitmap的理解, 什麼時候應該手動呼叫bitmap.recycle()?
至於什麼時候需要手動呼叫recycle,這就看具體場景了,原則是當我們不再使用Bitmao時,需要回收之。另外,我們需要注意,2.3之前Bitmap物件與畫素資料是分開存放的,Bitmap物件存在java Heap中而畫素資料存放在Native Memory中,這時很有必要呼叫recycle回收記憶體。但是2.3之後,Bitmap物件和畫素資料都是存在Heap中,GC可以回收其記憶體。
11.ViewPager中載入Fragment的優化問題?如何做到微信那樣切換介面時的延時載入?
利用fragment中的setUserVisibleHint這個方法可以來做到.
privateboolean
hasLoadedOnce =
false;
// your boolean field
@Override
publicvoid
setUserVisibleHint
(
booleanisVisibleToUser) {
super
.setUserVisibleHint(isVisibleToUser);
if
(
this.isVisible()) {
// we check that the fragment is becoming visible
if
(isVisibleToUser && !hasLoadedOnce) {
//do something
}
}
}
}
12什麼是aar?aar和jar有什麼區別?
“aar”包是 Android 的類庫專案的二進位制發行包。
副檔名是.aar,maven 專案型別應該也是aar,但檔案本身是帶有以下各項的 zip 檔案:
/AndroidManifest.xml
(mandatory)
/classes.jar (mandatory)
/res/ (mandatory)
/R.txt (mandatory)
/assets/ (optional)
/libs/*.jar (optional)
/jni//*.so (optional)
/proguard.txt (optional)
/lint.jar (optional)
這些條目是直接位於 zip 檔案根目錄的。
其中R.txt 檔案是aapt帶引數–output-text-symbols的輸出結果。
jar打包不能包含資原始檔,比如一些drawable檔案、xml資原始檔之類的,aar可以。
13.如何加密Url防止被黑?
加密到JNI裡面還是會通過抓包工具抓取到.最後的方式就是進行HTTPS證照雙向加密驗證
14.Android fragment和activity的區別
你可以理解Fragment是一種特殊的View,負責一個模組或者一個特殊部分的展示。
大部分Fragment是依託於Activity存在的,由Activity的FragmentManager來管理
Fragment可以解決多Activity的問題,即將3.0之前的頻繁Activity跳轉改成一個Activity內Fragment的切換。
Fragment可以解決碎片化的問題。
fragment是android3.0新增的
fragment可以重用
fragment必須巢狀在activity中使用,它的生命週期受activity的影響。
15.Service和廣播 BroadcastReceivre會不會出現ANR?
Service,廣播 會出現ANR
服務, 廣播都是主執行緒中, 既然是主執行緒 當然會anr 所以耗時操作還是必須另起執行緒
通俗的說超時時間:Activity 5秒, Broadcast 10秒, Server 20秒
16.你在平時開發中會使用到哪些設計模式,能談談這些設計模式的使用場景嗎?
平時用的比較多有單例模式(在記憶體中僅例項化一個物件時使用),介面卡模式(典型的就是ListView和GridView的介面卡),建造者模式(AlertDialog.Builder),觀察者模式可能比較隱蔽,在Android原始碼中BaseAdapater的NotifyDataSetChanged的實現(?)
單例:DownloadManager
1.靜態內部類、內部類、匿名內部類,為什麼內部類會持有外部類的引用?持有的引用是this?還是其它?
靜態內部類:使用static修飾的內部類
內部類:就是在某個類的內部又定義了一個類,內部類所嵌入的類稱為外部類
匿名內部類:使用new生成的內部類
因為內部類的產生依賴於外部類,持有的引用是類名.this
2.Java中try catch finally的執行順序
先執行try中程式碼,如果發生異常執行catch中程式碼,最後一定會執行finally中程式碼
3.equals與==的區別:
==是判斷兩個變數或例項是不是指向同一個記憶體空間 equals是判斷兩個變數或例項所指向的記憶體空間的值是不是相
4.Object有哪些公用方法?
方法equals測試的是兩個物件是否相等
方法clone進行物件拷貝
方法getClass返回和當前物件相關的Class物件
方法notify,notifyall,wait都是用來對給定物件進行執行緒同步的
5.String、StringBuffer與StringBuilder的區別
String 型別和 StringBuffer 型別的主要效能區別其實在於 String 是不可變的物件 StringBuffer和StringBuilder底層是 char[]陣列實現的 StringBuffer是執行緒安全的,而StringBuilder是執行緒不安全的
6.Java的四種引用的區別
強引用:如果一個物件具有強引用,它就不會被垃圾回收器回收。即使當前記憶體空間不足,JVM 也不會回收它,而是丟擲 OutOfMemoryError 錯誤,使程式異常終止。如果想中斷強引用和某個物件之間的關聯,可以顯式地將引用賦值為null,這樣一來的話,JVM在合適的時間就會回收該物件
軟引用:在使用軟引用時,如果記憶體的空間足夠,軟引用就能繼續被使用,而不會被垃圾回收器回收,只有在記憶體不足時,軟引用才會被垃圾回收器回收。
弱引用:具有弱引用的物件擁有的生命週期更短暫。因為當 JVM 進行垃圾回收,一旦發現弱引用物件,無論當前記憶體空間是否充足,都會將弱引用回收。不過由於垃圾回收器是一個優先順序較低的執行緒,所以並不一定能迅速發現弱引用物件
虛引用:顧名思義,就是形同虛設,如果一個物件僅持有虛引用,那麼它相當於沒有引用,在任何時候都可能被垃圾回收器回收。
7.介紹垃圾回收機制
標記回收法:遍歷物件圖並且記錄可到達的物件,以便刪除不可到達的物件,一般使用單執行緒工作並且可能產生記憶體碎片
標記-壓縮回收法:前期與第一種方法相同,只是多了一步,將所有的存活物件壓縮到記憶體的一端,這樣記憶體碎片就可以合成一大塊可再利用的記憶體區域,提高了記憶體利用率
複製回收法:把現有記憶體空間分成兩部分,gc執行時,它把可到達物件複製到另一半空間,再清空正在使用的空間的全部物件。這種方法適用於短生存期的物件,持續複製長生存期的物件則導致效率降低。
分代回收發:把記憶體空間分為兩個或者多個域,如年輕代和老年代,年輕代的特點是物件會很快被回收,因此在年輕代使用效率比較高的演算法。當一個物件經過幾次回收後依然存活,物件就會被放入稱為老年的記憶體空間,老年代則採取標記-壓縮演算法
集合、資料結構相關
1.你用過哪些集合類
資料結構中用於儲存資料的有哪些
陣列
陣列儲存區間是連續的,佔用記憶體嚴重,故空間複雜的很大。但陣列的二分查詢時間複雜度小,為O(1);陣列的特點是:定址容易,插入和刪除困難;
連結串列
連結串列儲存區間離散,佔用記憶體比較寬鬆,故空間複雜度很小,但時間複雜度很大,達O(N)。連結串列的特點是:定址困難,插入和刪除容易。
2.說說hashMap是怎樣實現的
雜湊表:由陣列+連結串列組成的
當我們往HashMap中put元素的時候,先根據key的hashCode重新計算hash值,根據hash值得到這個元素在陣列中的位置(即下標),如果陣列該位置上已經存放有其他元素了,那麼在這個位置上的元素將以連結串列的形式存放,新加入的放在鏈頭,最先加入的放在鏈尾。如果陣列該位置上沒有元素,就直接將該元素放到此陣列中的該位置上。
3.ArrayList,LinkedList的區別
ArrayList是實現了基於動態陣列的資料結構,LinkedList基於連結串列的資料結構。
對於隨機訪問get和set,ArrayList覺得優於LinkedList,因為LinkedList要移動指標。
對於新增和刪除操作add和remove,LinedList比較佔優勢,因為ArrayList要移動資料。
4.ArrayList和Vector的主要區別是什麼?
ArrayList 和Vector底層是採用陣列方式儲存資料
Vector:
執行緒同步
當Vector中的元素超過它的初始大小時,Vector會將它的容量翻倍,
ArrayList:
執行緒不同步,但效能很好
當ArrayList中的元素超過它的初始大小時,ArrayList只增加50%的大小
5.HashMap和 HashTable 的區別:
HashTable比較老,是基於Dictionary 類實現的,HashTable 則是基於 Map介面實現的
HashTable 是執行緒安全的, HashMap 則是執行緒不安全的
HashMap可以讓你將空值作為一個表的條目的key或value
演算法相關
1.排序演算法和穩定性,快排什麼時候情況最壞?
2.給最外層的rootview,把這個根檢視下的全部button背景設定成紅色,手寫程式碼,不許用遞迴
演算法原理:
Android的view檢視是按樹形結構分佈,所以按樹形結構遍歷
迴圈判斷每一層的ViewGroup元素,將其入棧;否則判斷當前view是否是Button類例項,是則改寫背景色
當前ViewGroup檢查childView完成後,判斷棧是否非空,取出棧頂元素ViewGroup重複步驟2直至棧為空。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
void changeAllBtnBGColor(View view, int color) { if (view == null || !(view instanceof ViewGroup)) return; Stack m = new Stack<>(); while (view != null) { ViewGroup tmpGroup = (ViewGroup) view; int count = tmpGroup.getChildCount(); for (int i = 0; i < count; i++) { View child = tmpGroup.getChildAt(i); if (child instanceof ViewGroup) m.add(child); else if (child instanceof Button) { child.setBackgroundColor(color); } } if (m.isEmpty()) break; else view = m.pop(); } } |
Thread、AsynTask相關
1.wait()和sleep()的區別
sleep來自Thread類,和wait來自Object類
呼叫sleep()方法的過程中,執行緒不會釋放物件鎖。而 呼叫 wait 方法執行緒會釋放物件鎖
sleep睡眠後不出讓系統資源,wait讓出系統資源其他執行緒可以佔用CPU
sleep(milliseconds)需要指定一個睡眠時間,時間一到會自動喚醒
2.若Activity已經銷燬,此時AsynTask執行完並且返回結果,會報異常嗎?
當一個App旋轉時,整個Activity會被銷燬和重建。當Activity重啟時,AsyncTask中對該Activity的引用是無效的,因此onPostExecute()就不會起作用,若AsynTask正在執行,折會報 view not attached to window manager 異常
同樣也是生命週期的問題,在 Activity 的onDestory()方法中呼叫Asyntask.cancal方法,讓二者的生命週期同步
3.Activity銷燬但Task如果沒有銷燬掉,當Activity重啟時這個AsyncTask該如何解決?
還是螢幕旋轉這個例子,在重建Activity的時候,會回掉Activity.onRetainNonConfigurationInstance()重新傳遞一個新的物件給AsyncTask,完成引用的更新
4.Android 執行緒間通訊有哪幾種方式(重要)
共享記憶體(變數);
檔案,資料庫;
Handler;
Java 裡的 wait(),notify(),notifyAll()
5.請介紹下 AsyncTask的內部實現,適用的場景是
AsyncTask 內部也是 Handler 機制來完成的,只不過 Android 提供了執行框架來提供執行緒池來
執行相應地任務,因為執行緒池的大小問題,所以 AsyncTask 只應該用來執行耗時時間較短的任務,
比如 HTTP 請求,大規模的下載和資料庫的更改不適用於 AsyncTask,因為會導致執行緒池堵塞,沒有
執行緒來執行其他的任務,導致的情形是會發生 AsyncTask 根本執行不了的問題。
網路相關
1.TCP三次握手
2.為什麼TCP是可靠的,UDP早不可靠的?為什麼UDP比TCP快?
TCP/IP協議高,因為其擁有三次握手雙向機制,這一機制保證校驗了資料,保證了他的可靠性。
UDP就沒有了,udp資訊發出後,不驗證是否到達對方,所以不可靠。
但是就速度來說,還是UDP協議更高,畢竟其無需重複返回驗證,只是一次性的
3.http協議瞭解多少,說說裡面的協議頭部有哪些欄位?
http(超文字傳輸協議)是一個基於請求與響應模式的、無狀態的、應用層的協議;http請求由三部分組成,分別是:請求行、訊息報頭、請求正文。
HTTP訊息報頭包括普通報頭、請求報頭、響應報頭、實體報頭
4.https瞭解多少
HTTPS(全稱:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全為目標的HTTP通道,簡單講是HTTP的安全版。即HTTP下加入SSL層,HTTPS的安全基礎是SSL,因此加密的詳細內容就需要SSL。
5.談談 HTTP 中Get 和 Post 方法的區別
GET - 從指定的伺服器中獲取資料,明文傳送內容
POST - 提交資料給指定的伺服器處理
1. POST請求不能被快取下來
2. POST請求不會儲存在瀏覽器瀏覽記錄中
3. 以POST請求的URL無法儲存為瀏覽器書籤
4. POST請求沒有長度限制
6.推送心跳包是TCP包還是UDP包或者HTTP包
心跳包的實現是呼叫了socket.sendUrgentData(0xFF)這句程式碼實現的,所以,當然是TCP包。
7.如何實現檔案斷點上傳
在 Android 中上傳檔案可以採用 HTTP 方式,也可以採用 Socket 方式,但是 HTTP 方式不能上傳
大檔案,這裡介紹一種通過 Socket 方式來進行斷點續傳的方式,服務端會記錄下檔案的上傳進度,
當某一次上傳過程意外終止後,下一次可以繼續上傳,這裡用到的其實還是 J2SE 裡的知識。
這個上傳程式的原理是:客戶端第一次上傳時向服務端傳送
“Content-Length=35;filename=WinRAR_3.90_SC.exe;sourceid=“這種格式的字串,服務端
收到後會查詢該檔案是否有上傳記錄,如果有就返回已經上傳的位置,否則返回新生成的 sourceid
以及 position 為 0,類似 sourceid=2324838389;position=0“這樣的字串,客戶端收到返回後
的字串後再從指定的位置開始上傳檔案。
Fragment相關
1.Fragment 如何實現類似 Activity 棧的壓棧和出棧效果的?
Fragment 的事物管理器內部維持了一個雙向連結串列結構,該結構可以記錄我們每次 add 的
Fragment 和 replace 的 Fragment,然後當我們點選 back 按鈕的時候會自動幫我們實現退棧操作。
2.Fragment 在你們專案中的使用
Fragment 是 android3.0 以後引入的的概念,做區域性內容更新更方便,原來為了到達這一點要
把多個佈局放到一個 activity 裡面,現在可以用多 Fragment 來代替,只有在需要的時候才載入
Fragment,提高效能。
Fragment 的好處:
1. Fragment 可以使你能夠將 activity 分離成多個可重用的元件,每個都有它自己的生命週期和
UI。
2. Fragment 可以輕鬆得建立動態靈活的 UI 設計,可以適應於不同的螢幕尺寸。從手機到平板電
腦。
3. Fragment 是一個獨立的模組,緊緊地與 activity 繫結在一起。可以執行中動態地移除、加入、
交換等。
4. Fragment 提供一個新的方式讓你在不同的安卓裝置上統一你的 UI。
5. Fragment 解決 Activity 間的切換不流暢,輕量切換。
6. Fragment 替代 TabActivity 做導航,效能更好。
7. Fragment 在 4.2.版本中新增巢狀 fragment 使用方法,能夠生成更好的介面效果
3.如何切換 fragement,不重新例項化
正確的切換方式是 add(),切換時 hide(),add()另一個 Fragment;再次切換時,只需 hide()當前,
show()另一個
四大元件相關
1.Activity和Fragment生命週期有哪些?
Activity——onCreate->onStart->onResume->onPause->onStop->onDestroy
Fragment——onAttach->onCreate->onCreateView->onActivityCreated->onStart->onResume->onPause->onStop->onDestroyView->onDestroy->onDetach
2.廣播的兩種註冊方式及有什麼區別
3.記憶體不足時,怎麼保持Activity的一些狀態,在哪個方法裡面做具體操作?
Activity的 onSaveInstanceState() 和 onRestoreInstanceState()並不是生命週期方法,它們不同於 onCreate()、onPause()等生命週期方法,它們並不一定會被觸發。當應用遇到意外情況(如:記憶體不足、使用者直接按Home鍵)由系統銷燬一個Activity,onSaveInstanceState() 會被呼叫。但是當使用者主動去銷燬一個Activity時,例如在應用中按返回鍵,onSaveInstanceState()就不會被呼叫。除非該activity是被使用者主動銷燬的,通常onSaveInstanceState()只適合用於儲存一些臨時性的狀態,而onPause()適合用於資料的持久化儲存。
4.啟動service的兩種方法?有什麼區別?
一種是startService(),另一種是bindService()。這兩者的區別是第一種方式呼叫者開啟了服務,即會與服務失去聯絡,兩者沒有關聯。即使訪問者退出了,服務仍在執行。如需解除服務必須顯式的呼叫stopService方法。主要用於呼叫者與服務沒有互動的情況下,也就是呼叫者不需要獲取服務裡的業務方法。比如電話錄音。而後者呼叫者與服務繫結在一起的。當呼叫者退出的時候,服務也隨之退出。用於需要與服務互動。
5.Android中的Context, Activity,Appliction有什麼區別?
相同:Activity和Application都是Context的子類。
Context從字面上理解就是上下文的意思,在實際應用中它也確實是起到了管理上下文環境中各個引數和變數的總用,方便我們可以簡單的訪問到各種資源。
不同:維護的生命週期不同。 Context維護的是當前的Activity的生命週期,Application維護的是整個專案的生命週期。
使用context的時候,小心記憶體洩露,防止記憶體洩露,注意一下幾個方面:
1. 不要讓生命週期長的物件引用activity context,即保證引用activity的物件要與activity本身生命週期是一樣的。
2. 對於生命週期長的物件,可以使用application,context。
3. 避免非靜態的內部類,儘量使用靜態類,避免生命週期問題,注意內部類對外部物件引用導致的生命週期變化。
6.Context是什麼?
它描述的是一個應用程式環境的資訊,即上下文。
該類是一個抽象(abstract class)類,Android提供了該抽象類的具體實現類(ContextIml)。
通過它我們可以獲取應用程式的資源和類,也包括一些應用級別操作,例如:啟動一個Activity,傳送廣播,接受Intent,資訊,等。
7.Service 是否在 main thread 中執行, service 裡面是否能執行耗時的操
作?
預設情況,如果沒有顯示的指 servic 所執行的程式, Service 和 activity 是執行在當前 app 所在進
程的 main thread(UI 主執行緒)裡面。
service 裡面不能執行耗時的操作(網路請求,拷貝資料庫,大檔案 )
<service< p=""></service<>
特殊情況 ,可以在清單檔案配置 service 執行所在的程式 ,讓
service 在另外的程式中執行
1 2 3 4 5 |
<service android:name="com.baidu.location.f" android:enabled="true" android:process=":remote" > </service> |
8.Activity 怎麼和 Service 繫結,怎麼在 Activity 中啟動自己對應的
Service?
Activity 通過 bindService(Intent service, ServiceConnection conn, int flags)跟 Service 進行
繫結,當繫結成功的時候 Service 會將代理物件通過回撥的形式傳給 conn,這樣我們就拿到了
Service 提供的服務代理物件。
在 Activity 中可以通過 startService 和 bindService 方法啟動 Service。一般情況下如果想獲取
Service 的服務物件那麼肯定需要通過 bindService()方法,比如音樂播放器,第三方支付等。如
果僅僅只是為了開啟一個後臺任務那麼可以使用 startService()方法。
9.說說 Activity、Intent、Service 是什麼關係
他們都是 Android 開發中使用頻率最高的類。其中 Activity 和 Service 都是 Android 四大元件
之一。他倆都是 Context 類的子類 ContextWrapper 的子類,因此他倆可以算是兄弟關係吧。不過
兄弟倆各有各自的本領,Activity 負責使用者介面的顯示和互動,Service 負責後臺任務的處理。Activity
和 Service 之間可以通過 Intent 傳遞資料,因此可以把 Intent 看作是通訊使者。
10.請描述一下 BroadcastReceiver
BroadCastReceiver 是 Android 四大元件之一,主要用於接收系統或者 app 傳送的廣播事件。
廣播分兩種:有序廣播和無序廣播。
內部通訊實現機制:通過 Android 系統的 Binder 機制實現通訊。
1. 無序廣播:完全非同步,邏輯上可以被任何廣播接收者接收到。優點是效率較高。缺點是一個接收者不
能將處理結果傳遞給下一個接收者,並無法終止廣播 intent 的傳播。
2. 有序廣播:按照被接收者的優先順序順序,在被接收者中依次傳播。比如有三個廣播接收者 A,B,C,
優先順序是 A > B > C。那這個訊息先傳給 A,再傳給 B,最後傳給 C。每個接收者有權終止廣播,比
如 B 終止廣播,C 就無法接收到。此外 A 接收到廣播後可以對結果物件進行操作,當廣播傳給 B 時,
B 可以從結果物件中取得 A 存入的資料。
在通過 Context.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,
initialCode, initialData, initialExtras)時我們可以指定 resultReceiver 廣播接收者,這個接收者我們
可以認為是最終接收者,通常情況下如果比他優先順序更高的接收者如果沒有終止廣播,那麼他的
onReceive 會被執行兩次,第一次是正常的按照優先順序順序執行,第二次是作為最終接收者接收。
如果比他優先順序高的接收者終止了廣播,那麼他依然能接收到廣播
11.為什麼要用 ContentProvider?它和 sql 的實現上有什麼差別?
ContentProvider 遮蔽了資料儲存的細節,內部實現對使用者完全透明,使用者只需要關心運算元據的
uri 就可以了,ContentProvider 可以實現不同 app 之間共享。
Sql 也有增刪改查的方法,但是 sql 只能查詢本應用下的資料庫。而 ContentProvider 還可
以去增刪改查本地檔案. xml 檔案的讀取等。
12.說說 ContentProvider、ContentResolver、ContentObserver 之間的關係
a. ContentProvider 內容提供者,用於對外提供資料
b. ContentResolver.notifyChange(uri)發出訊息
c. ContentResolver 內容解析者,用於獲取內容提供者提供的資料
d. ContentObserver 內容監聽器,可以監聽資料的改變狀態
e. ContentResolver.registerContentObserver()監聽訊息。
View 相關
1.onInterceptTouchEvent()和onTouchEvent()的區別
onInterceptTouchEvent()用於攔截觸控事件
onTouchEvent()用於處理觸控事件
2.RemoteView在哪些功能中使用
APPwidget和Notification中
3. SurfaceView和View的區別是什麼?
SurfaceView中採用了雙快取技術,在單獨的執行緒中更新介面
View在UI執行緒中更新介面
4.View的繪製過程
一個View要顯示在介面上,需要經歷一個View樹的遍歷過程,這個過程又可以分為三個過程,也就是自定義View中的三要素:大小,位置,畫什麼,即onMesure(),onLayout(),onDraw()。
1.onMesure()確定一個View的大小;
2.onLayout()確定View在父節點上的位置;
3.onDraw()繪製View 的內容;
5.如何自定義ViewGroup
1.指定的LayoutParams
2.onMeasure中計算所有childView的寬和高,然後根據childView的寬和高,計算自己的寬和高。(當然,如果不是wrap_content,直接使用父ViewGroup傳入的計算值即可)
3.onLayout中對所有的childView進行佈局。
6.View中onTouch,onTouchEvent,onClick的執行順序
dispatchTouchEvent—->onTouch—->onTouchEvent—–>onClick。在所有ACTION_UP事件之後才觸發onClick點選事件。
效能優化相關
1.ListView卡頓的原因與效能優化,越多越好
重用converView: 通過複用converview來減少不必要的view的建立,另外Infalte操作會把xml檔案例項化成相應的View例項,屬於IO操作,是耗時操作。
減少findViewById()操作: 將xml檔案中的元素封裝成viewholder靜態類,通過converview的setTag和getTag方法將view與相應的holder物件繫結在一起,避免不必要的findviewbyid操作
避免在 getView 方法中做耗時的操作: 例如載入本地 Image 需要載入記憶體以及解析 Bitmap ,都是比較耗時的操作,如果使用者快速滑動listview,會因為getview邏輯過於複雜耗時而造成滑動卡頓現象。使用者滑動時候不要載入圖片,待滑動完成再載入,可以使用這個第三方庫glide
Item的佈局層次結構儘量簡單,避免佈局太深或者不必要的重繪
儘量能保證 Adapter 的 hasStableIds() 返回 true 這樣在 notifyDataSetChanged() 的時候,如果item內容並沒有變化,ListView 將不會重新繪製這個 View,達到優化的目的
在一些場景中,ScollView內會包含多個ListView,可以把listview的高度寫死固定下來。 由於ScollView在快速滑動過程中需要大量計算每一個listview的高度,阻塞了UI執行緒導致卡頓現象出現,如果我們每一個item的高度都是均勻的,可以通過計算把listview的高度確定下來,避免卡頓現象出現
使用 RecycleView 代替listview: 每個item內容的變動,listview都需要去呼叫notifyDataSetChanged來更新全部的item,太浪費效能了。RecycleView可以實現當個item的區域性重新整理,並且引入了增加和刪除的動態效果,在效能上和定製上都有很大的改善
ListView 中元素避免半透明: 半透明繪製需要大量乘法計算,在滑動時不停重繪會造成大量的計算,在比較差的機子上會比較卡。 在設計上能不半透明就不不半透明。實在要弄就把在滑動的時候把半透明設定成不透明,滑動完再重新設定成半透明。
儘量開啟硬體加速: 硬體加速提升巨大,避免使用一些不支援的函式導致含淚關閉某個地方的硬體加速。當然這一條不只是對 ListView。
2.如何避免 OOM 問題的出現
使用更加輕量的資料結構 例如,我們可以考慮使用ArrayMap/SparseArray而不是HashMap等傳統資料結構。通常的HashMap的實現方式更加消耗記憶體,因為它需要一個額外的例項物件來記錄Mapping操作。另外,SparseArray更加高效,在於他們避免了對key與value的自動裝箱(autoboxing),並且避免了裝箱後的解箱。
避免在Android裡面使用Enum Android官方培訓課程提到過“Enums often require more than twice as much memory as static constants. You should strictly avoid using enums on Android.”,具體原理請參考《Android效能優化典範(三)》,所以請避免在Android裡面使用到列舉。
減小Bitmap物件的記憶體佔用 Bitmap是一個極容易消耗記憶體的大胖子,減小建立出來的Bitmap的記憶體佔用可謂是重中之重,,通常來說有以下2個措施: ++inSampleSize++:縮放比例,在把圖片載入記憶體之前,我們需要先計算出一個合適的縮放比例,避免不必要的大圖載入。 ++decode format++:解碼格式,選擇ARGB_6666/RBG_545/ARGB_4444/ALPHA_6,存在很大差異
Bitmap物件的複用 縮小Bitmap的同時,也需要提高BitMap物件的複用率,避免頻繁建立BitMap物件,複用的方法有以下2個措施 LRUCache : “最近最少使用演算法”在Android中有極其普遍的應用。ListView與GridView等顯示大量圖片的控制元件裡,就是使用LRU的機制來快取處理好的Bitmap,把近期最少使用的資料從快取中移除,保留使用最頻繁的資料, inBitMap高階特性:利用inBitmap的高階特性提高Android系統在Bitmap分配與釋放執行效率。使用inBitmap屬性可以告知Bitmap解碼器去嘗試使用已經存在的記憶體區域,新解碼的Bitmap會嘗試去使用之前那張Bitmap在Heap中所佔據的pixel data記憶體區域,而不是去問記憶體重新申請一塊區域來存放Bitmap。利用這種特性,即使是上千張的圖片,也只會僅僅只需要佔用螢幕所能夠顯示的圖片數量的記憶體大小
使用更小的圖片 在涉及給到資源圖片時,我們需要特別留意這張圖片是否存在可以壓縮的空間,是否可以使用更小的圖片。儘量使用更小的圖片不僅可以減少記憶體的使用,還能避免出現大量的InflationException。假設有一張很大的圖片被XML檔案直接引用,很有可能在初始化檢視時會因為記憶體不足而發生InflationException,這個問題的根本原因其實是發生了OOM。
StringBuilder 在有些時候,程式碼中會需要使用到大量的字串拼接的操作,這種時候有必要考慮使用StringBuilder來替代頻繁的“+”。
避免在onDraw方法裡面執行物件的建立 類似onDraw等頻繁呼叫的方法,一定需要注意避免在這裡做建立物件的操作,因為他會迅速增加記憶體的使用,而且很容易引起頻繁的gc,甚至是記憶體抖動。
避免物件的記憶體洩露
3.三級快取的原理
從快取中載入。
從本地檔案中載入(資料庫,SD)
從網路載入。
a.載入 bitmap 的時候無需考慮 bitmap 載入過程中出現的 oom(記憶體溢位)和 android 容器快速
滑動的時候出現的圖片錯位等現象。(16M)
b. 支援載入網路圖片和本地圖片。
c. 記憶體管理使用的 lru 演算法(移除裡面是有頻率最少的物件),更好的管理 bitmap 的記憶體
Android其他
1.講一下android中程式的優先順序?
前臺程式
可見程式
服務程式
後臺程式
空程式
2.介紹Handle的機制
Handler通過呼叫sendmessage方法把訊息放在訊息佇列MessageQueue中,Looper負責把訊息從訊息佇列中取出來,重新再交給Handler進行處理,三者形成一個迴圈
通過構建一個訊息佇列,把所有的Message進行統一的管理,當Message不用了,並不作為垃圾回收,而是放入訊息佇列中,供下次handler建立訊息時候使用,提高了訊息物件的複用,減少系統垃圾回收的次數
每一個執行緒,都會單獨對應的一個looper,這個looper通過ThreadLocal來建立,保證每個執行緒只建立一個looper,looper初始化後就會呼叫looper.loop建立一個MessageQueue,這個方法在UI執行緒初始化的時候就會完成,我們不需要手動建立
3.Dalvik虛擬機器與JVM有什麼區別
Dalvik 基於暫存器,而 JVM 基於棧。基於暫存器的虛擬機器對於更大的程式來說,在它們編譯的時候,花費的時間更短。
Dalvik執行.dex格式的位元組碼,而JVM執行.class格式的位元組碼。
4.每個應用程式對應多少個Dalvik虛擬機器
每一個Android應用在底層都會對應一個獨立的Dalvik虛擬機器例項,其程式碼在虛擬機器的解釋下得以執行 ,而所有的Android應用的執行緒都對應一個Linux執行緒
5.應用常駐後臺,避免被第三方殺掉的方法
Service設定成START_STICKY kill 後會被重啟(等待5秒左右),重傳Intent,保持與重啟前一樣
通過 startForeground將程式設定為前臺程式, 做前臺服務,優先順序和前臺應用一個級別,除非在系統記憶體非常缺,否則此程式不會被 kill
雙程式Service: 讓2個程式互相保護對方,其中一個Service被清理後,另外沒被清理的程式可以立即重啟程式
用C編寫守護程式(即子程式) : Android系統中當前程式(Process)fork出來的子程式,被系統認為是兩個不同的程式。當父程式被殺死的時候,子程式仍然可以存活,並不受影響(Android5.0以上的版本不可行
聯絡廠商,加入白名單
6.根據自己的理解描述下Android數字簽名。
所有的應用程式都必須有數字證照,Android系統不會安裝一個沒有數字證照的應用程式
Android程式包使用的數字證照可以是自簽名的,不需要一個權威的數字證照機構簽名認證
如果要正式釋出一個Android程式,必須使用一個合適的私鑰生成的數字證照來給程式簽名,而不能使用adt外掛或者ant工具生成的除錯證照來發布。
數字證照都是有有效期的,Android只是在應用程式安裝的時候才會檢查證照的有效期。如果程式已經安裝在系統中,即使證照過期也不會影響程式的正常功能。
7.Dalvik基於JVM的改進
幾個class變為一個dex,constant pool,省記憶體
Zygote,copy-on-write shared,省記憶體,省cpu,省電
基於暫存器的bytecode,省指令,省cpu,省電
Trace-based JIT,省cpu,省電,省記憶體
8.ARGB_8888佔用記憶體大小
本題的答案,是4byte,即ARGB各佔用8個位元來描述。
9.apk安裝解除安裝的原理
安裝過程:複製apk安裝包到data/app目錄下,解壓並掃描安裝包,把dex檔案(dalvik位元組碼)儲存到dalvik-cache目錄,並data/data目錄下建立對應的應用資料目錄。
解除安裝過程:刪除安裝過程中在上述三個目錄下建立的檔案及目錄。
10.通過Intent傳遞一些二進位制資料的方法有哪些?
使用Serializable介面實現序列化,這是Java常用的方法。
實現Parcelable介面,這裡Android的部分類比如Bitmap類就已經實現了,同時Parcelable在Android AIDL中交換資料也很常見的。
11.橫豎屏切換時Activity的生命週期
此時的生命週期跟清單檔案裡的配置有關係。
不設定Activity的android:configChanges時,切屏會重新呼叫各個生命週期預設首先銷燬當前activity,然後重新載入。
設定Activity android:configChanges=”orientation|keyboardHidden|screenSize”時,切屏不會重新呼叫各個生命週期,只會執行onConfigurationChanged方法
12.Serializable 和 Parcelable 的區別
在使用記憶體的時候,Parcelable 類比 Serializable 效能高,所以推薦使用 Parcelable 類。
1. Serializable 在序列化的時候會產生大量的臨時變數,從而引起頻繁的 GC。
2. Parcelable 不能使用在要將資料儲存在磁碟上的情況。儘管 Serializable 效率低點,但在這
種情況下,還是建議你用 Serializable 。
13.Android 中如何捕獲未捕獲的異常
自 定 義 一 個 Application , 比 如 叫 MyApplication 繼 承 Application 實 現
UncaughtExceptionHandler。
覆寫 UncaughtExceptionHandler 的 onCreate 和 uncaughtException 方法。
14.Android 的許可權規則
Android 中的 apk 必須簽名
基於 UserID 的程式級別的安全機制
預設 apk 生成的資料對外是不可見的
AndroidManifest.xml 中的顯式許可權宣告
15.多執行緒間通訊和多程式之間通訊有什麼不同,分別怎麼實現?
一、程式間的通訊方式
1. 管道( pipe ):管道是一種半雙工的通訊方式,資料只能單向流動,而且只能在具有親緣關係的
程式間使用。程式的親緣關係通常是指父子程式關係。
2. 有名管道 (namedpipe) : 有名管道也是半雙工的通訊方式,但是它允許無親緣關係程式間的
通訊。
3. 訊號量(semophore ) : 訊號量是一個計數器,可以用來控制多個程式對共享資源的訪問。它
常作為一種鎖機制,防止某程式正在訪問共享資源時,其他程式也訪問該資源。因此,主要作為進
程間以及同一程式內不同執行緒之間的同步手段。
4. 訊息佇列( messagequeue ) : 訊息佇列是由訊息的連結串列,存放在核心中並由訊息佇列識別符號
標識。訊息佇列克服了訊號傳遞資訊少、管道只能承載無格式位元組流以及緩衝區大小受限等缺點。
5. 訊號 (sinal ) : 訊號是一種比較複雜的通訊方式,用於通知接收程式某個事件已經發生。
6. 共享記憶體(shared memory ) :共享記憶體就是對映一段能被其他程式所訪問的記憶體,這段共享內
存由一個程式建立,但多個程式都可以訪問。共享記憶體是最快的 IPC 方式,它是針對其他程式間
通訊方式執行效率低而專門設計的。它往往與其他通訊機制,如訊號兩,配合使用,來實現程式間
的同步和通訊。
7. 套接字(socket ) : 套解口也是一種程式間通訊機制,與其他通訊機制不同的是,它可用於不同
及其間的程式通訊。
二、執行緒間的通訊方式
1. 鎖機制:包括互斥鎖、條件變數、讀寫鎖
*互斥鎖提供了以排他方式防止資料結構被併發修改的方法。
*讀寫鎖允許多個執行緒同時讀共享資料,而對寫操作是互斥的。
*條件變數可以以原子的方式阻塞程式,直到某個特定條件為真為止。對條件的測試是在互斥鎖
的保護下進行的。條件變數始終與互斥鎖一起使用。
2. 訊號量機制(Semaphore):包括無名執行緒訊號量和命名執行緒訊號量
3. 訊號機制(Signal):類似程式間的訊號處理
執行緒間的通訊目的主要是用於執行緒同步,所以執行緒沒有像程式通訊中的用於資料交換的通訊機
制。
16.說說 LruCache 底層原理
LruCache 使用一個 LinkedHashMap 簡單的實現記憶體的快取,沒有軟引用,都是強引用。如果添
加的資料大於設定的最大值,就刪除最先快取的資料來調整記憶體。
maxSize 是通過構造方法初始化的值,他表示這個快取能快取的最大值是多少。
size 在新增和移除快取都被更新值,他通過 safeSizeOf 這個方法更新值。safeSizeOf 預設返回 1,
但一般我們會根據 maxSize 重寫這個方法,比如認為 maxSize 代表是 KB 的話,那麼就以 KB 為單
位返回該項所佔的記憶體大小。
除異常外首先會判斷 size 是否超過 maxSize,如果超過了就取出最先插入的快取,如果不為空就
刪掉,並把 size 減去該項所佔的大小。這個操作將一直迴圈下去,直到 size 比 maxSize 小或者快取
為空。
1. Activity建立在哪些視窗元件之上?順帶涉及View的事件傳遞問題。
沒讀懂問題,=。=不知道是不是問Activity的UI結構,如果是可以參考這篇文章。
對於View的事件傳遞,則可以從 Activity --> ViewGroup --> ...... --> Activity 的** U型 **消費結構去說。
2. 什麼情況下,Activity的onNewInstent()方法會執行?Activity的啟動模式相關。
當此Activity的例項已經存在,並且此時的啟動模式為SingleTask和SingleInstance,另外當這個例項位於棧頂且啟動模式為SingleTop時也會觸發onNewInstent()。
3. Activity A使用startForResult啟動Activity B,B什麼都不做並返回A,A中的onActivityResult回撥是否會執行?
startActivity()方法,最終都是呼叫startActivityForResult()方法。預設的requestCode = -1 resultCode = RESULT_CANCELED = 0,當你的requestCode != -1時,onActivityResult()一定會被呼叫。
4. Fragment能否不依賴於Activity存在?簡析一下Fragment的棧管理。
Fragment不能獨立存在,它必須嵌入到activity中,而且Fragment的生命週期直接受所在的activity的影響。
// Create new fragment and transaction
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// Replace whatever is in the fragment_container view with this fragment,
// and add the transaction to the back stack
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null);
// Commit the transaction
transaction.commit();
transaction只是記錄了從一個狀態到另一個狀態的變化過程,即比如從FragmentA替換到FragmentB的過程,當通過函式transaction.addToBackStack(null)將這個事務新增到回退棧,則會記錄這個事務的狀態變化過程,如從FragmentA —>FragmentB,當使用者點選手機回退鍵時,因為transaction的狀態變化過程被儲存,則可以將事務的狀態變化過程還原,即將FragmentB —> FragmentA.
新增到回退棧的函式:transaction.addToBackStack(null);
參考文章: http://blog.csdn.net/u011026329/article/details/47903177
5. 能否將一個Activity放到系統的最近任務列表裡,獨立於宿主app任務卡之外?
我印象中是可以做到了,平時沒用到,知道的同學請@我,謝謝!
6. 對於同一個Service,在被start啟動之後還能不能被bind?
能
服務基本上分為兩種形式:
啟動
當應用元件(如
Activity)通過呼叫 startService() 啟動服務時,服務即處於“啟動”狀態。一旦啟動,服務即可在後臺無限期執行,即使啟動服務的元件已被銷燬也不受影響。 已啟動的服務通常是執行單一操作,而且不會將結果返回給呼叫方。例如,它可能通過網路下載或上傳檔案。 操作完成後,服務會自行停止執行。
繫結
當應用元件通過呼叫
bindService() 繫結到服務時,服務即處於“繫結”狀態。繫結服務提供了一個客戶端-伺服器介面,允許元件與服務進行互動、傳送請求、獲取結果,甚至是利用程式間通訊 (IPC) 跨程式執行這些操作。 僅當與另一個應用元件繫結時,繫結服務才會執行。 多個元件可以同時繫結到該服務,但全部取消繫結後,該服務即會被銷燬。
雖然本文件是分開概括討論這兩種服務,但是您的服務可以同時以這兩種方式執行,也就是說,它既可以是啟動服務(以無限期執行),也允許繫結。問題只是在於您是否實現了一組回撥方法:onStartCommand()(允許元件啟動服務)和
onBind()(允許繫結服務)。
來自官方文件
7. Service有哪些派生類?這些派生類的使用場景是什麼?
這個問題不知道問的具體是什麼,如果是要 IntentService那麼可以參考官方文件的解釋與使用說明:
擴充套件 IntentService 類
由於大多數啟動服務都不必同時處理多個請求(實際上,這種多執行緒情況可能很危險),因此使用 IntentService 類實現服務也許是最好的選擇。
IntentService 執行以下操作:
建立預設的工作執行緒,用於在應用的主執行緒外執行傳遞給 onStartCommand() 的所有 Intent。
建立工作佇列,用於將 Intent 逐一傳遞給 onHandleIntent() 實現,這樣您就永遠不必擔心多執行緒問題。
在處理完所有啟動請求後停止服務,因此您永遠不必呼叫 stopSelf()。
提供 onBind() 的預設實現(返回 null)。
提供 onStartCommand() 的預設實現,可將 Intent 依次傳送到工作佇列和 onHandleIntent() 實現。
綜上所述,您只需實現 onHandleIntent() 來完成客戶端提供的工作即可。(不過,您還需要為服務提供小型建構函式。)
以下是 IntentService 的實現示例:
public class HelloIntentService extends IntentService {
/**
* A constructor is required, and must call the super IntentService(String)
* constructor with a name for the worker thread.
*/
public HelloIntentService() {
super("HelloIntentService");
}
/**
* The IntentService calls this method from the default worker thread with
* the intent that started the service. When this method returns, IntentService
* stops the service, as appropriate.
*/
@Override
protected void onHandleIntent(Intent intent) {
// Normally we would do some work here, like download a file.
// For our sample, we just sleep for 5 seconds.
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// Restore interrupt status.
Thread.currentThread().interrupt();
}
}
}
您只需要一個建構函式和一個 onHandleIntent() 實現即可。
如果您決定還重寫其他回撥方法(如 onCreate()、onStartCommand() 或 onDestroy()),請確保呼叫超類實現,以便 IntentService 能夠妥善處理工作執行緒的生命週期。
例如,onStartCommand() 必須返回預設實現(即,如何將 Intent 傳遞給 onHandleIntent()):
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
return super.onStartCommand(intent,flags,startId);
}
除 onHandleIntent() 之外,您無需從中呼叫超類的唯一方法就是 onBind()(僅當服務允許繫結時,才需要實現該方法)。
8. Service與其它元件之間的通訊實現方式有哪些?
- binder
- broadcast
- 其他參見執行緒和程式的通訊方式
9. View的post(Runnable r)方法裡,r會帶來一個新的執行緒嗎?多執行緒相關。
不會,最終還是handler傳送訊息,執行在UI執行緒。
如下是原始碼和註釋:
/**
* <p>Causes the Runnable to be added to the message queue.
* The runnable will be run on the user interface thread.</p>
*
* @param action The Runnable that will be executed.
*
* @return Returns true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting.
*
* @see #postDelayed
* @see #removeCallbacks
*/
public boolean post(Runnable action) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.post(action);
}
// Postpone the runnable until we know on which thread it needs to run.
// Assume that the runnable will be successfully placed after attach.
getRunQueue().post(action);
return true;
}
10. 在非UI執行緒中使用Handler需要注意哪些問題?
new Thread(){
public void run(){
Looper.prepare();//給當前執行緒初始化Looper
Toast.makeText(getApplicationContext(),"更新UI",0).show();//Toast初始化的時候會new Handler();無參構造預設獲取當前執行緒的Looper,如果沒有prepare過,則丟擲題主描述的異常。上一句程式碼初始化過了,就不會出錯。
Looper.loop();//這句執行,Toast排隊show所依賴的Handler發出的訊息就有人處理了,Toast就可以吐出來了。但是,這個Thread也阻塞這裡了,因為loop()是個for (;;) ...
}
}.start();
參考:
https://www.zhihu.com/question/51099935
https://www.zhihu.com/question/34652589
11. 自定義View時有哪些重要的方法,它們的作用及執行順序是怎樣的?
按照順序:onMeasure() --> onLayout() --> onDraw().其他的自己擴充套件吧。
12. 如何單獨對ListView上的一個item進行更新?
- 更新對應view的內容
- 通過ViewHolder去設定值
- 呼叫一次getView()方法(Google IO 推薦)
參考文章 http://blog.csdn.net/linglongxin24/article/details/53020164
13. 簡析一下大圖片的載入處理。
對Bitmap的理解,然後就是壓縮圖片。
14. 設計師只給了一套1280*800的UI圖示註,如何進行其它解析度尺寸螢幕的適配?
名稱 |
畫素密度範圍 |
圖片大小 |
mdpi |
120dp~160dp |
48×48px |
hdpi |
160dp~240dp |
72×72px |
xhdpi |
240dp~320dp |
96×96px |
xxhdpi |
320dp~480dp |
144×144px |
xxxhdpi |
480dp~640dp |
192×192px |
以 720*1080 5英寸為例:
(720^2 + 1080^2)開方=260
放在xhdpi中。
本題中同理可以算得 293,還是xhdpi中。
15. 6.0系統新許可權機制的解決方案。
這個。。。沒什麼好說的,真正瞭解的很好說,不瞭解的話就有點繞。
?你們精通的開源框架,問題來了
寫各種精通其實是可以的,要麼真牛x,如果不是很牛x那就在最後加上一條精通----精通各種被打臉。
16. EventBus的機制是什麼?和Handler的區別怎樣?
EventBus是採用觀察者模式實現的事件訂閱匯流排,可以用在應用程式中,元件之間,執行緒之間的通訊,並且由於事件可以是任意型別的物件,所以使用起來更加的方便快捷。
Handler是 Android 的訊息機制,集中解決執行緒間通訊問題。
17. RxJava的機制是什麼?
RxJava是使用Java語言,以響應式程式設計思維來進行程式設計的Java類庫。參考ReactiveX。
18. Butterknife的機制是什麼?
Java Annotation Processing技術,在Java程式碼編譯成Java位元組碼的時候就已經處理了@Bind、@OnClick(ButterKnife還支援很多其他的註解)這些註解了。
Annotation
processing 是javac中用於編譯時掃描和解析Java註解的工具
Annotation processing是在編譯階段執行的,它的原理就是讀入Java原始碼,解析註解,然後生成新的Java程式碼。新生成的Java程式碼最後被編譯成Java位元組碼,註解解析器(Annotation Processor)不能改變讀入的Java
類,比如不能加入或刪除Java方法。
參考:ButterKnife框架原理
19. Okhttp是基於HTTP連線還是Socket連線?
基於Http的。
20. 例舉一種ORM框架,說說它的優缺點。
我熟悉的兩種GreenDao3和AndroidActive,GreenDao 比較常規,註解不多(我這裡都是指3.0版本後,之前的版本在生存實體的時候略顯麻煩。),AndroidActive 相對而言註解較多,最後的綜合效能上 GreenDao 排第一毫無爭議。硬要說缺點的話就是 GreenDao 體積稍大。