Android高新面試題2017彙總(帶答案)

原作者地址:https://www.jianshu.com/p/928dbf20d927

前言介紹

最近彙總了一些大公司的部分面試題,包括騰訊、華爲、阿里、網易等。

博客地址:

http://blog.csdn.net/androidstarjack/article

正文

 插件化、熱修復 、熱更新的理解

  • 插件化 – apk 分爲宿主和插件部分,插件在需要的時候才加載進來

  • 熱修復 – 更新的類或者插件粒度較小的時候,我們會稱之爲熱修復,一般用於修復bug

  • 熱更新 – 2016 Google 的 Android Studio 推出了Instant Run 功能 同時提出了3個名詞

    • “ 熱部署” – 方法內的簡單修改,無需重啓app和Activity。

    • “暖部署” – app無需重啓,但是activity需要重啓,比如資源的修改。

    • “冷部署” – app需要重啓,比如繼承關係的改變或方法的簽名變化等。

  • 站在app開發者角度的“熱”是指在不發版的情況來實現更新

  • 而Google提出的“熱”是指值是否需要重新啓動。 - 同時在開發插件化的時候也有兩種情景

  • 一種是插件與宿主apk沒有交互,只是在用戶使用到的時候進行一次吊起

  • 還有一種是與宿主有很多的交互

你認爲Android熱更新框架哪個好:

  • 1.阿里的熱更新框架已經開源 了。但已經很久沒有更新過新版本了。當前的版本只支持到了 Android 4.4。由於 5.0 起新的 ART 虛擬機、更嚴格的 SELinux 策略以及對 64 位的支持之類的事,使得 Xposed 都在開發上做了很多調整。我不知道 Dexposed 現在是否支持,但至少阿里沒有開源。

  • 2.在本地動態執行遠端下發的代碼是極度危險的行爲。利用此方法執行非法代碼等或用於繞過 Google Play 等市場的審查是違反相關協議的,也是對用戶極度不負責任的行爲。

  • 3.在一些訪問非常密集的地方使用熱更新可能會對效率產生相對比較大的影響,應該避免使用.

  • 4.我們可以對 Java 的 ScriptEngine 進行一些封裝成爲一個 HotPatch 類使得它更適合做熱更新的工作。

  • 5.首先,檢查熱更新補丁的管道一定要建立在 https 上,因爲下發代碼是極其危險的,如果被劫持,後果是無法想象的。其次,請求時最好自動帶上 Android 版本、手機型號、地區、版本號等信息,以方便更精確地下發,千萬不能下發錯。

  • 6.Java在運行時加載對應的類是通過ClassLoader來實現的,ClassLoader本身是一個抽象來,Android中使用PathClassLoader類作爲Android的默認的類加載器

  • 7.我們的如果想做hotpatch,一定要保證我們的hotpacth dex文件出現在dexElements列表的前面。

二.常用的熱更新技術框架:

  • 基於QQ空間的HotFix →→ 要使用到android dex分包方案→拆分dex的項目的話,可以參考一下谷歌的multidex方案實現.

  • 大衆點評的NuWa←項目補丁自動化做的很完整

  • alibaba/AndFix

  • 阿里巴巴的DexPosed

  • dalvik_patch實現multidex

  • 使用React-Native實現app熱部署的一次實踐

  • alibaba/AndFix

基礎

activity生命週期圖解

注意:

鎖定屏與解鎖屏幕 只會調用onPause(),而不會調用onStop方法,開屏後則調用onResume()。在實際操作中會有所出入,比如在三星手機測試的時候鎖定手機調用了onPause()和onStop()方法,解鎖時候調用的是:onRestart(),onStart()和 onResume()方法。

介紹不同場景下Activity生命週期的變化過程

  • 啓動Activity:

    onCreate()—>onStart()—>onResume(),Activity進入運行狀態。

  • Activity退居後臺:

    當前Activity轉到新的Activity界面或按Home鍵回到主屏: onPause()—>onStop(),進入停滯狀態。

  • Activity返回前臺: onRestart()—>onStart()—>onResume(),再次回到運行狀態。

  • Activity退居後臺,且系統內存不足,

    系統會殺死這個後臺狀態的Activity,若再次回到這個Activity,則會走onCreate()–>onStart()—>onResume()

  • 鎖定屏與解鎖屏幕

    只會調用onPause(),而不會調用onStop方法,開屏後則調用onResume()

Activity銷燬但Task如果沒有銷燬掉,當Activity重啓時這個AsyncTask該如何解決?

比如屏幕旋轉這個例子,在重建Activity的時候,會回調

Activity.onRetainNonConfigurationInstance()

重新傳遞一個新的對象給AsyncTask,完成引用的更新

若Activity已經銷燬,此時AsynTask執行完並返回結果,會報異常麼?

  • 當一個App旋轉時,整個Activity會被銷燬和重建。

  • 當Activity重啓時,AsyncTask中對該Activity的引用是無效的,因此onPostExecute()就不會起作用

  • 若AsynTask正在執行,折會報 view not attached to window manager 異常

  • 同樣也是生命週期的問題,在 Activity 的onDestory()方法中調用Asyntask.cancal方法,讓二者的生命週期同步

內存不足時,系統會殺死後臺的Activity,如果需要進行一些臨時狀態的保存,在哪個方法進行

  • Activity的 onSaveInstanceState() 和 onRestoreInstanceState()並不是生命週期方法,不同於 onCreate()、onPause()等生命週期方法,它們並不一定會被觸發。

  • 當應用遇到意外情況(如:內存不足、用戶直接按Home鍵)由系統銷燬一個Activity,onSaveInstanceState() 會被調用。

  • 但是當用戶主動去銷燬一個Activity時,例如在應用中按返回鍵,onSaveInstanceState()就不會被調用。除非該activity是被用戶主動銷燬的

  • 通常onSaveInstanceState()只適合用於保存一些臨時性的狀態,而onPause()適合用於數據的持久化保存。

介紹Activity 四中launchMode:

我們可以在AndroidManifest.xml配置的android:launchMode屬性爲以下四種之一。

  • 1、standard

    standard模式是默認的啓動模式,不用爲配置android:launchMode屬性即可,當然也可以指定值爲standard。standard啓動模式,不管有沒有已存在的實例,都生成新的實例。

  • 2、 singleTop

    我們在上面的基礎上爲指定屬性android:launchMode=”singleTop”,系統就會按照singleTop啓動模式處理跳轉行爲。跳轉時系統會先在棧結構中尋找是否有一個Activity實例正位於棧頂,如果有則不再生成新的,而是直接使用。如果系統發現存在有Activity實例,但不是位於棧頂,重新生成一個實例。 這就是singleTop啓動模式,如果發現有對應的Activity實例正位於棧頂,則重複利用,不再生成新的實例。

  • 3、 singleTask

    如果發現有對應的Activity實例,則使此Activity實例之上的其他Activity實例統統出棧,使此Activity實例成爲棧頂對象,顯示到幕前。

  • 4、singleInstance

    這種啓動模式比較特殊,因爲它會啓用一個新的棧結構,將Acitvity放置於這個新的棧結構中,並保證不再有其他Activity實例進入。

LaunchMode使用場景

  • singleTop適合接收通知啓動的內容顯示頁面。

    例如,某個新聞客戶端的新聞內容頁面,如果收到10個新聞推送,每次都打開一個新聞內容頁面是很煩人的。

  • singleTask適合作爲程序入口點。

    例如瀏覽器的主界面。不管從多少個應用啓動瀏覽器,只會啓動主界面一次,其餘情況都會走onNewIntent,並且會清空主界面上面的其他頁面。

  • singleInstance應用場景:

    鬧鈴的響鈴界面。 你以前設置了一個鬧鈴:上午6點。在上午5點58分,你啓動了鬧鈴設置界面,並按 Home 鍵回桌面;在上午5點59分時,你在微信和朋友聊天;在6點時,鬧鈴響了,並且彈出了一個對話框形式的 Activity(名爲 AlarmAlertActivity) 提示你到6點了(這個 Activity 就是以

  • SingleInstance

    加載模式打開的),你按返回鍵,回到的是微信的聊天界面,這是因爲 AlarmAlertActivity 所在的 Task 的棧只有他一個元素, 因此退出之後這個 Task 的棧空了。如果是以 SingleTask 打開 AlarmAlertActivity,那麼當鬧鈴響了的時候,按返回鍵應該進入鬧鈴設置界面。

如何把一個應用設置爲系統應用

  • Android設置是Debug版本,且root,直接將該apk用adb工具push到system/app或system/priv-app

  • 如果是非root設備,需要編譯後燒寫鏡像

  • 有些權限(如WRITE_SECURE_SETTINGS)不開放給第三方應用,只能在對應設備源碼總編譯然後作爲系統app使用

Activity,Window,View三者的聯繫和區別?

  • Activity像一個工匠(控制單元)

  • Window像窗戶(承載模型)

  • View像窗花(顯示視圖)

  • LayoutInflater像剪刀

  • Xml配置像窗花圖紙。

Activity啓動Service的兩種方式

  • startService:生命週期和調用者不同.啓動後若調用者未調用stopService而直接退出,Service仍會運行

  • bindService:生命週期與調用者綁定,調用者一旦退出,Service就會調用unBind->onDestory

Android兩個應用能在同一個任務棧嗎?

棧一般以包名命名,兩個應用的簽名和udid要相同

Fragment是什麼?你曾經遇到哪些有關Fragment的問題?

  • Fragment可以作爲Activity界面的一部分組成出現

    • 其作用是:

      碎片整理,局部刷新。

  • 一個Activity中可以同時出現多個Fragment,並一個Fragment也可以在多個Activity中使用.

  • 在Activity中可以添加,刪除,替換Fragment.Fragment可以響應自己的輸入時間,並且有自己的生命週期,但其生命週期收Activity影響.

Fragment生命週期

如何實現Activity窗口快速變暗

利用只讀屬性動畫+WindowManager

/*  *@param from\>=0&&from\<=1.0f  * @param to\>=0&&to\<=1.0f  *  * */ private void dimBackground(final float from, final float to) { final Window window = getWindow(); ValueAnimator valueAnimator = ValueAnimator.ofFloat(from, to); valueAnimator.setDuration(500); valueAnimator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) {  WindowManager.LayoutParams
 params = window.getAttributes();
 params.alpha = (Float) animation.getAnimatedValue();  window.setAttributes(params); } }); valueAnimator.start(); }

是否使用過本地廣播,和全局廣播有什麼區別?

本地廣播在本應用範圍內傳播,不用擔心隱私數據泄露,不用擔心別的應用僞造廣播.相比全局廣播,本地廣播更高效.

註冊廣播的幾種方法?

  • 1.靜態註冊:在清單文件中註冊, 常見的有監聽設備啓動,常駐註冊不會隨程序生命週期改變

  • 2.動態註冊:在代碼中註冊,隨着程序的結束,也就停止接受廣播了

    補充一點:有些廣播只能通過動態方式註冊,比如時間變化事件、屏幕亮滅事件、電量變更事件,因爲這些事件觸發頻率通常很高,如果允許後臺監聽,會導致進程頻繁創建和銷燬,從而影響系統整體性能

爲什麼Android引入廣播機制?
  • a:從MVC的角度考慮(應用程序內) 其實回答這個問題的時候還可以這樣問,android爲什麼要有那4大組件,現在的移動開發模型基本上也是照搬的web那一套MVC架構,只不過是改了點嫁妝而已。

    • android的四大組件本質上就是爲了實現移動或者說嵌入式設備上的MVC架構

    • 它們之間有時候是一種相互依存的關係,有時候又是一種補充關係,引入廣播機制可以方便幾大組件的信息和數據交互。

  • b:程序間互通消息(例如在自己的應用程序內監聽系統來電)

  • c:效率上(參考UDP的廣播協議在局域網的方便性)

  • d:設計模式上(反轉控制的一種應用,類似監聽者模式)

瞭解IntentServices嗎?

  • IntentService是Service的子類,是一個異步的,會自動停止的服務,很好解決了傳統的Service中處理完耗時操作忘記停止並銷燬Service的問題

  • 生成一個默認的且與線程相互獨立的工作線程執行所有發送到onStartCommand()方法的Intent,可以在onHandleIntent()中處理.

  • 串行隊列,每次只運行一個任務,不存在線程安全問題,所有任務執行完後自動停止服務,不需要自己手動調用stopSelf()來停止.

如何提升Service進程優先級

在AndroidManifest.xml文件中對於intent-filter可以通過android:priority = “1000”這個屬性設置最高優先級,1000是最高值,如果數字越小則優先級越低,同時適用於廣播。

ContentProvider和sql的區別

ContentProvider的主要還是用於數據共享,其可以對Sqlite,SharePreferences,File等進行數據操作用來共享數據。而sql的可以理解爲數據庫的一門語言,可以使用它完成CRUD等一系列的操作

數據存儲相關
  • 文件存儲:

    通過Java.io.FileInputStream和java.io.FileOutputStream這兩個類來實現對文件的讀寫,java.io.File類則用來構造一個具體指向某個文件或者文件夾的對象。

  • SharedPreferences:

    SharedPreferences是一種輕量級的數據存儲機制,他將一些簡單的數據類型的數據,包括boolean類型,int類型,float類型,long類型以及String類型的數據,以鍵值對的形式存儲在應用程序的私有Preferences目錄(/data/data/<包名>/shared_prefs/)中,這種Preferences機制廣泛應用於存儲應用程序中的配置信息。

  • SQLite數據庫:

    當應用程序需要處理的數據量比較大時,爲了更加合理地存儲、管理、查詢數據,我們往往使用關係數據庫來存儲數據。Android系統的很多用戶數據,如聯繫人信息,通話記錄,短信息等,都是存儲在SQLite數據庫當中的,所以利用操作SQLite數據庫的API可以同樣方便的訪問和修改這些數據。

  • ContentProvider:

    主要用於在不同的應用程序之間實現數據共享的功能,不同於sharepreference和文件存儲中的兩種全局可讀寫操作模式,內容提供其可以選擇只對哪一部分數據進行共享,從而保證我們程序中的隱私數據不會有泄漏的風險

如何將打開res aw目錄中的數據庫文件?

  • 在Android中不能直接打開res aw目錄中的數據庫文件,而需要在程序第一次啓動時將該文件複製到手機內存或SD卡的某個目錄中,然後再打開該數據庫文件。

  • 複製的基本方法是使用getResources().openRawResource方法獲得res aw目錄中資源的 InputStream對象,然後將該InputStream對象中的數據寫入其他的目錄中相應文件中。

  • 在Android SDK中可以使用SQLiteDatabase.openOrCreateDatabase方法來打開任意目錄中的SQLite數據庫文件。

什麼是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可以。

SQLite支持事務嗎?添加刪除如何提高性能?

SQLite作爲輕量級的數據庫,比MySQL還小,但支持SQL語句查詢,提高性能可以考慮通過原始經過優化的SQL查詢語句方式處理

如何將SQLite數據庫(dictionary.db文件)與apk文件一起發佈?

可以將dictionary.db文件複製到Eclipse Android工程中的res aw目錄中。所有在res aw目錄中的文件不會被壓縮,這樣可以直接提取該目錄中的文件。可以將dictionary.db文件複製到res aw目錄中

如何保證Service在後臺不被kill

  • Service設置成START_STICKY kill 後會被重啓(等待5秒左右),重傳Intent,保持與重啓前一樣

  • 通過 startForeground將進程設置爲前臺進程, 做前臺服務,優先級和前臺應用一個級別,除非在系統內存非常缺,否則此進程不會被 kill

  • 雙進程Service: 讓2個進程互相保護**,其中一個Service被清理後,另外沒被清理的進程可以立即重啓進程

  • QQ黑科技: 在應用退到後臺後,另起一個只有 1 像素的頁面停留在桌面上,讓自己保持前臺狀態,保護自己不被後臺清理工具殺死

  • 在已經root的設備下,修改相應的權限文件,將App僞裝成系統級的應用 Android4.0系列的一個漏洞,已經確認可行

  • 用C編寫守護進程(即子進程) : Android系統中當前進程(Process)fork出來的子進程,被系統認爲是兩個不同的進程。當父進程被殺死的時候,子進程仍然可以存活,並不受影響。鑑於目前提到的在Android->- Service層做雙守護都會失敗,我們可以fork出c進程,多進程守護。死循環在那檢查是否還存在,具體的思路如下(Android5.0以上的版本不可行)

  • 用C編寫守護進程(即子進程),守護進程做的事情就是循環檢查目標進程是否存在,不存在則啓動它。 在NDK環境中將1中編寫的C代碼編譯打包成可執行文件(BUILD_EXECUTABLE)。主進程啓動時將守護進程放入私有目錄下,賦予可執行權限,啓動它即可。

  • 聯繫廠商,加入白名單

Android中如何獲得手機的唯一標示.

  • 1 首先嚐試讀取IMEI、Mac地址、CPU號等物理信息(有不少工具可以修改IMEI);

  • 2 如果均失敗,可以自己生成UUID然後保存到文件(文件也可能被篡改或刪除)

參考:[http://blog.csdn.net/xushuaic/article/details/25077179]

mipmap文件夾和drawable文件夾的區別

它只是用來放啓動圖標的,好處就是,你只用放一個mipmap圖標,它就會給你各種版本(比如平板,手機)的apk自動生成相應分辨率的圖標,以節約空間。

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。

ViewHolder爲什麼要被聲明成靜態內部類

  • 這個是考靜態內部類和非靜態內部類的主要區別之一。非靜態內部類會隱式持有外部類的引用,就像大家經常將自定義的adapter在Activity類裏,然後在adapter類裏面是可以隨意調用外部activity的方法的。

  • 當你將內部類定義爲static時,你就調用不了外部類的實例方法了,因爲這時候靜態內部類是不持有外部類的引用的。聲明ViewHolder靜態內部類,可以將ViewHolder和外部類解引用。

  • 大家會說一般ViewHolder都很簡單,不定義爲static也沒事吧。確實如此,但是如果你將它定義爲static的,說明你懂這些含義。萬一有一天你在這個ViewHolder加入一些複雜邏輯,做了一些耗時工作,那麼如果ViewHolder是非靜態內部類的話,就很容易出現內存泄露。

  • 如果是靜態的話,你就不能直接引用外部類,迫使你關注如何避免相互引用。 所以將 ViewHolder內部類 定義爲靜態的,是一種好習慣

動畫相關

Android中的動畫有哪些?

  • 逐幀動畫(Drawable Animation):

    加載一系列Drawable資源來創建動畫,簡單來說就是播放一系列的圖片來實現動畫效果,可以自定義每張圖片的持續時間

  • 補間動畫(Tween Animation):

    Tween可以對View對象實現一系列簡單的動畫效果,比如位移,縮放,旋轉,透明度等等。但是它並不會改變View屬性的值,只是改變了View的繪製的位置,比如,一個按鈕在動畫過後,不在原來的位置,但是觸發點擊事件的仍然是原來的座標。

  • 屬性動畫(Property Animation):

    動畫的對象除了傳統的View對象,還可以是Object對象,動畫結束後,Object對象的屬性值被實實在在的改變了

Android動畫原理

  • Animation框架定義了透明度,旋轉,縮放和位移幾種常見的動畫,而且控制的是整個View

  • 實現原理是每次繪製視圖時View所在的ViewGroup中的drawChild函數獲取該View的Animation的Transformation值

  • 然後調用canvas.concat(transformToApply.getMatrix()),通過矩陣運算完成動畫幀,如果動畫沒有完成,繼續調用invalidate()函數,啓動下次繪製來驅動動畫

  • 動畫過程中的幀之間間隙時間是繪製函數所消耗的時間,可能會導致動畫消耗比較多的CPU資源,最重要的是,動畫改變的只是顯示,並不能相應事件

View繪製相關

SurfaceView和View的區別

  • SurfaceView中採用了雙緩存技術,在單獨的線程中更新界面

  • View在UI線程中更新界面

介紹下自定義view的基本流程

  • 1、 明確需求,確定你想實現的效果

  • 2、確定是使用組合控件的形式還是全新自定義的形式,組合控件即使用多個系統控件來合成一個新控件,你比如titilebar,這種形式相對簡單,參考

  • 3、如果是完全自定義一個view的話,你首先需要考慮繼承哪個類,是View呢,還是ImageView等子類。

  • 4、根據需要去複寫View#onDraw、View#onMeasure、View#onLayout方法

  • 5.根據需要去複寫dispatchTouchEvent、onTouchEvent方法

  • 6、根據需要爲你的自定義view提供自定義屬性,即編寫attr.xml,然後在代碼中通過TypedArray等類獲取到自定義屬性值

  • 7、需要處理滑動衝突、像素轉換等問題 談談View的繪製流程

談談View的繪製流程

measure()方法,layout(),draw()三個方法主要存放了一些標識符,來判斷每個View是否需要再重新測量,佈局或者繪製,主要的繪製過程還是在onMeasure,onLayout,onDraw這個三個方法中

  • 1.onMesarue() 爲整個View樹計算實際的大小,即設置實際的高(對應屬性:mMeasuredHeight)和寬(對應屬性: mMeasureWidth),每個View的控件的實際寬高都是由父視圖和本身視圖決定的。

  • 2.onLayout() 爲將整個根據子視圖的大小以及佈局參數將View樹放到合適的位置上。

  • 3.onDraw() 開始繪製圖像,繪製的流程如下

    • 首先繪製該View的背景

    • 調用onDraw()方法繪製視圖本身 (每個View都需要重載該方法,ViewGroup不需要實現該方法)

    • 如果該View是ViewGroup,調用dispatchDraw ()方法繪製子視圖 繪製滾動條

自定義View執行invalidate()方法,爲什麼有時候不會回調onDraw()

  • 自定義一個view時,重寫onDraw。調用view.invalidate(),會觸發onDraw和computeScroll()。前提是該view被附加在當前窗口. view.postInvalidate(); //是在非UI線程上調用的

  • 自定義一個ViewGroup,重寫onDraw。onDraw可能不會被調用,原因是需要先設置一個背景(顏色或圖)。表示這個group有東西需要繪製了,纔會觸發draw,之後是onDraw。因此,一般直接重寫dispatchDraw來繪製viewGroup.自定義一個ViewGroup,dispatchDraw會調用drawChild.

事件傳遞機制

談談touch事件的傳遞流程

  • 所有Touch事件都被封裝成了MotionEvent對象,包括Touch的位置、時間、歷史記錄以及第幾個手指(多指觸摸)等。

  • 事件類型分爲ACTION_DOWN, ACTION_UP, ACTION_MOVE, ACTION_POINTER_DOWN, ACTION_POINTER_UP, ACTION_CANCEL,每個事件都是以ACTION_DOWN開始ACTION_UP結束。

  • 對事件的處理包括三類,分別爲傳遞——dispatchTouchEvent()函數、攔截——onInterceptTouchEvent()函數、消費——onTouchEvent()函數和OnTouchListener()

簡單來說:

  • 事件從Activity.dispatchTouchEvent()開始傳遞,只要沒有被停止或攔截,從最上層的View(ViewGroup)開始一直往下(子View)傳遞。子View可以通過onTouchEvent()對事件進行處理。

  • 事件由父View(ViewGroup)傳遞給子View,ViewGroup可以通過onInterceptTouchEvent()對事件做攔截,停止其往下傳遞。

  • 如果事件從上往下傳遞過程中一直沒有被停止,且最底層子View沒有消費事件,事件會反向往上傳遞,這時父View(ViewGroup)可以進行消費,如果還是沒有被消費的話,最後會到Activity的onTouchEvent()函數。

  • 如果View沒有對ACTION_DOWN進行消費,之後的其他事件不會傳遞過來。

= OnTouchListener優先於onTouchEvent()對事件進行消費。 上面的消費即表示相應函數返回值爲true。

View中setOnTouchListener中的onTouch,onTouchEvent,onClick的執行順序

onTouch優於onTouchEvent,onTouchEvent優於onClick

觸摸事件的分發機制詳見:

Android觸摸事件分發機制完全解析《一》

什麼是Dalvik虛擬機

  • Dalvik虛擬機是Android平臺的核心。

  • 它可以支持.dex格式的程序的運行

  • .dex格式是專爲Dalvik設計的一種壓縮格式

  • 可以減少整體文件尺寸

  • 提高I/O操作的速度

  • 適合內存和處理器速度有限的系統

Dalvik虛擬機和JVM有什麼區別

  • Dalvik 基於寄存器,而 JVM 基於棧。基於寄存器的虛擬機對於更大的程序來說,在它們編譯的時候,花費的時間更短。

  • Dalvik執行.dex格式的字節碼,而JVM執行.class格式的字節碼

Android爲每個應用程序分配的內存大小是多少

  • 一般是16m或者24m,但是可以通過android:largeHeap申請更多內存

具體參考:

[https://liuzhichao.com/2016/use-android_largeHeap.html]

[http://www.cnblogs.com/mythou/p/3203536.html]

如何解決方法數65k問題?

使用Android Studio 的gradle 可以構建MutilDex

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章