android夯實總結(設計、細節及思想)

1)Android App的生命週期是什麼;
>前臺 後臺 關閉 激活 未激活的狀態等

2)四大組件很熟悉了吧,ContentProvider的生命週期是什麼;
>ContentProvider通過工具ContentResolver激活,使用者自行管理cursor的生命週期.

3)Android設備開機的啓動過程; http://blog.jobbole.com/67931/
》Boot ROM ->Boot Loader ->Kernel ->init ->Daemon Zygote Runtime Dalvik Vm ->System Servers  Service Manager Managers
>>當電源按下,引導芯片代碼開始從預定義的地方(固化在ROM)開始執行。加載引導程序到RAM,然後執行。 >>引導程序是在Android操作系統開始運行前的一個小程序。引導程序是運行的第一個程序,因此它是針對特定的主板與芯片的。設備製造商要麼使用很受歡迎的引導程序比如redboot、uboot、qi bootloader或者開發自己的引導程序,它不是Android操作系統的一部分。引導程序是OEM廠商或者運營商加鎖和限制的地方。>>Android內核與桌面linux內核啓動的方式差不多。內核啓動時,設置緩存、被保護存儲器、計劃列表,加載驅動。當內核完成系統設置,它首先在系統文件中尋找”init”文件,然後啓動root進程或者系統的第一個進程。>>init是第一個進程,我們可以說它是root進程或者說有進程的父進程。init進程有兩個責任,一是掛載目錄,比如/sys、/dev、/proc,二是運行init.rc腳本。>>Zygote讓Dalvik虛擬機共享代碼、低內存佔用以及最小的啓動時間成爲可能。Zygote是一個虛擬器進程,正如我們在前一個步驟所說的在系統引導的時候啓動。Zygote預加載以及初始化核心庫類。通常,這些核心類一般是隻讀的,也是Android SDK或者核心框架的一部分。在Java虛擬機中,每一個實例都有它自己的核心庫類文件和堆對象的拷貝。>>Zygote創建新的進程去啓動系統服務。系統服務或服務.>>一旦系統服務在內存中跑起來了,Android就完成了引導過程。在這個時候“ACTION_BOOT_COMPLETED”開機啓動廣播就會發出去。
第一部分:Bootloader啓動
一、Bootloader的定義和種類
二、Arm特定平臺的Bootloader
三、U-boot啓動流程分析
       第二部分:Linux啓動
一、zImage是怎樣煉成的?
二、linux的c啓動階段
       第三部分:Android啓動
一、init進程
二、init啓動的各種服務
三、android啓動圖示

4)Activity的視圖層次是什麼?打開一個對話框的時候,這個對話框是如何加入到視圖上去的?
>每一個Activity組件的UI內容和佈局都是通過與其所關聯的一個Window對象的內部的一個View對象來實現的。
getWindow().getDecorView()就是根視圖了,當然用Activity.getWindow.getDecorView()
Activity的對話框管理機制。

5)Dialog、PopupWindow、WindowManager加載視圖的區別;
>如PhoneStatusBar,ActivityThread,PhoneWindow,PopupWindow,Activity,Toast,Dialog 等等。那這裏感覺就比較明顯了,這些熟悉的控件和類,就是通過windowmanager ,來把自己的view和界面加到系統中了。
應用層面的界面都是通過windowmanager 加入到framework 中的,ViewRootImpl 是framework對view 的抽象, 界面管理的根節點。
Window是一塊電子屏,PhoneWindow是一塊手機電子屏,DecorView就是電子屏要顯示的內容,Activity就是手機電子屏安裝位置。

6)Service與Thread的區別;
> Thread:Thread 是程序執行的最小單元,它是分配CPU的基本單位。可以用 Thread 來執行一些異步的操作。
 Service:Service 是android的一種機制,當它運行的時候如果是Local Service,那麼對應的  Service 是運行在主進程的 main 線程上的。如:onCreate,onStart 這些函數在被系統調用的時候都是在主進程的 main 線程上運行的。如果是Remote Service,那麼對應的 Service 則是運行在獨立進程的 main 線程上。
 Thread 的運行是獨立於 Activity 的,也就是說當一個 Activity 被 finish 之後,如果你沒有主動停止 Thread 或者 Thread 裏的 run 方法沒有執行完畢的話,Thread 也會一直執行。因此這裏會出現一個問題:當 Activity 被 finish 之後,你不再持有該 Thread 的引用,也就是你下次啓動的時候,無法控制之前創建的線程,而service則可以。另一方面,你沒有辦法在不同的 Activity 中對同一 Thread 進行控制。你也可以在 Service 裏註冊 BroadcastReceiver,在其他地方通過發送 broadcast 來控制它,這些是 Thread 做不到的。
  根據進程優先級,Thread在後臺運行(Activty stop)的優先級低於後臺運行的Service,如果執行系統資源緊張,會優先殺死前一種,後臺運行的Service一般情況下不會被殺死,如果被殺死,系統空閒時會重新啓動service.
一.在應用中,如果是長時間的在後臺運行,而且不需要交互的情況下,使用服務。
同樣是在後臺運行,不需要交互的情況下,如果只是完成某個任務,之後就不需要運行,而且可能是多個任務,需需要長時間運行的情況下使用線程。
二.如果任務佔用CPU時間多,資源大的情況下,要使用線程。

7)ServiceManager、ActivityManager、XXXManager是幹什麼的?
》C/S框架及代理 框架IOC

8)爲什麼一定要在UI線程更新視圖,爲什麼要這麼設計;
>UI線程及Android的單線程模型原則當應用啓動,系統會創建一個主線程(main thread)。這個主線程負責向UI組件分發事件(包括繪製事件),也是在這個主線程裏,應用和Android的UI組件(components from the Android UI toolkit (components from the android.widget and android.view packages))發生交互。
google這樣設計的原因就在於讓UI線程做的事情更純粹一些,都是界面方面的事情,如果在ui線程執行耗時的操作,在做UI操作的時候會有卡頓的感覺。即從更新View的角度來說,最好是UI線程,非UI線程也不是不能更新UI。
 Android的單線程模型有兩條原則:
1.不要阻塞UI線程。
2.不要在UI線程之外訪問Android UI toolkit(主要是這兩個包中的組件:android.widget and android.view)。

9)能不能直接New一個Activity並啓動它;打包APK的過程幹了什麼;
》singleTop,singleTask啓動模式會調用onNewIntent(Intent intent)

10)安裝APK的過程幹了什麼;
>Android應用安裝有如下四種方式

11)啓動APK的過程幹了什麼;
>Java進程的啓動比較特殊,Java進程是zygote啓動的,zygote在folk進程之後,並沒有執行execve指令,因此是共享了zygote的代碼段和數據段。其它的java進程,可以看做都是zygote的克隆,克隆之後的進程,各自根再據自己的需求(java代碼),解釋java語言。

12)怎麼玩DexLoader(動態升級);
>Android 插件化 —— 指將一個程序劃分爲不同的部分,比如一般 App 的皮膚樣式就可以看成一個插件 
Android 組件化 —— 這個概念實際跟上面相差不那麼明顯,組件和插件較大的區別就是:組件是指通用及複用性較高的構件,比如圖片緩存就可以看成一個組件被多個 App 共用 
Android 動態加載 —— 這個實際是更高層次的概念,也有叫法是熱加載或 Android 動態部署,指容器(App)在運?狀態下動態加載某個模塊,從而新增功能或改變某?部分行爲  

13)MVP模式是啥;
> MVC (Model-View-Controller):M是指邏輯模型,V是指視圖模型,C則是控制器。一個邏輯模型可以對於多種視圖模型,比如一批統計數據你可以分別用柱狀圖、餅圖來表示。一種視圖模型也可以對於多種邏輯模型。使用MVC的目的是將M和V的實現代碼分離,從而使同一個程序可以使用不同的表現形式,而C存在的目的則是確保M和V的同步,一旦M改變,V應該同步更新,
1) 視圖層(View):一般採用XML文件進行界面的描述,使用的時候可以非常方便的引入。當然,如何你對Android瞭解的比較的多了話,就一定可以想到在Android中也可以使用JavaScript+HTML等的方式作爲View層,當然這裏需要進行Java和JavaScript之間的通信,幸運的是,Android提供了它們之間非常方便的通信實現。     
  2) 控制層(Controller):Android的控制層的重任通常落在了衆多的Acitvity的肩上,這句話也就暗含了不要在Acitivity中寫代碼,要通過Activity交割Model業務邏輯層處理,這樣做的另外一個原因是Android中的Acitivity的響應時間是5s,如果耗時的操作放在這裏,程序就很容易被回收掉。
  3) 模型層(Model):對數據庫的操作、對網絡等的操作都應該在Model裏面處理,當然對業務計算等操作也是必須放在的該層的。就是應用程序中二進制的數據。

14)View的生命週期是啥;
>android view有以下14個週期:
1、onFinishInflate() 當View中所有的子控件均被映射成xml後觸發 。
2、onMeasure( int , int ) 確定所有子元素的大小 。
3、onLayout( boolean , int , int , int , int ) 當View分配所有的子元素的大小和位置時觸發 。
4、onSizeChanged( int , int , int , int ) 當view的大小發生變化時觸發 。
5、onDraw(Canvas) view渲染內容的細節。 
6、onKeyDown( int , KeyEvent) 有按鍵按下後觸發 。
7、onKeyUp( int , KeyEvent) 有按鍵按下後彈起時觸發 。
8、onTrackballEvent(MotionEvent) 軌跡球事件 。 
9、onTouchEvent(MotionEvent) 觸屏事件 。
10、onFocusChanged( boolean , int , Rect) 當View獲取或失去焦點時觸發 。
11、onWindowFocusChanged( boolean ) 當窗口包含的view獲取或失去焦點時觸發 。
12、onAttachedToWindow() 當view被附着到一個窗口時觸發 。
13、onDetachedFromWindow() 當view離開附着的窗口時觸發,Android123提示該方法和 onAttachedToWindow() 是相反的。 
14、onWindowVisibilityChanged( int ) 當窗口中包含的可見的view發生變化時觸發。

15)TWEEN動畫跟熟悉動畫在View的繪製過程是怎麼作用的;
> 視圖動畫注意事項:特別特別注意:補間動畫執行之後並未改變View的真實佈局屬性值。切記這一點,譬如我們在Activity中有一個Button在屏幕上方,我們設置了平移動畫移動到屏幕下方然後保持動畫最後執行狀態呆在屏幕下方,這時如果點擊屏幕下方動畫執行之後的Button是沒有任何反應的,而點擊原來屏幕上方沒有Button的地方卻響應的是點擊Button的事件。

16)自定義動畫玩過嗎,裏面的Matrix怎麼控制。res裏面的XML資源最終都要轉化成JavaCode,怎麼完全脫離   res,用純代碼的方式實現res資源的功能,怎麼縮放一張點九圖;
> Matrix類:Translate—平移變換;Scale—縮放變換;Rotate—旋轉變換;Skew————錯切變換
Matrix提供了一些方法來控制圖片變換:
setTranslate(float dx,float dy):控制Matrix進行位移。
setSkew(float kx,float ky):控制Matrix進行傾斜,kx、ky爲X、Y方向上的比例。
setSkew(float kx,float ky,float px,float py):控制Matrix以px、py爲軸心進行傾斜,kx、ky爲X、Y方向上的傾斜比例。
setRotate(float degrees):控制Matrix進行depress角度的旋轉,軸心爲(0,0)。
setRotate(float degrees,float px,float py):控制Matrix進行depress角度的旋轉,軸心爲(px,py)。
setScale(float sx,float sy):設置Matrix進行縮放,sx、sy爲X、Y方向上的縮放比例。
setScale(float sx,float sy,float px,float py):設置Matrix以(px,py)爲軸心進行縮放,sx、sy爲X、Y方向上的縮放比例。


17)Binder原理是什麼,除了Binder之外,還能怎麼跟Service交互;
> Binder是Android系統進程間通信(IPC)方式之一。Linux已經擁有的進程間通信IPC手段包括(Internet Process Connection): 管道(Pipe)、信號(Signal)和跟蹤(Trace)、插口(Socket)、報文隊列(Message)、共享內存(Share Memory)和信號量(Semaphore)
Binder使用Client-Server通信方式.
Binder框架定義了四個角色:Server,Client,ServiceManager(以後簡稱SMgr)以及Binder驅動。其中Server,Client,SMgr運行於用戶空間,驅動運行於內核空間。這四個角色的關係和互聯網類似:Server是服務器,Client是客戶終端,SMgr是域名服務器(DNS),驅動是路由器。
Binder使用Client-Server通信方式,接收緩存管理和線程池管理方式.
> AIDL

18)Touch事件的分發機制;
> 傳遞——dispatchTouchEvent()函數、攔截——onInterceptTouchEvent()函數、消費——onTouchEvent()函數和OnTouchListener(事件分發與消費)


19)能不能用代碼模擬一組TOUCH事件(比如自動點擊廣告,自動滾動);TOUCH事件傳遞及分發
》final long downTime = SystemClock.uptimeMillis();
final MotionEvent downEvent = MotionEvent.obtain(
        downTime, downTime, MotionEvent.ACTION_DOWN, x, y, 0);
final MotionEvent upEvent = MotionEvent.obtain(
        downTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, x, y, 0);
mSeekBar.onTouchEvent(downEvent);
mSeekBar.onTouchEvent(upEvent);
downEvent.recycle();
upEvent.recycle();
。重點是需要知道兩個點:一是你模擬點擊的座標,在這裏就是x和y,二就是你需要設置響應這個點擊事件的View,這裏是一個SeekBar,

20)ROOT的原理是什麼,系統是怎麼管理APP的權限的;
》Android的內核就是Linux,在Linux下獲取root權限的時候就是執行sudo或者su。

Linux下su以後輸入密碼就可以root了,但Android裏的su和Linux裏的su是不一樣的,Android裏的su不是靠驗證密碼的,而是看你原來的權限是什麼。意思就是如果你是root,那你可以通過su切換到別的用戶,比如說shell,wifi,audio什麼的。

需要把一個所有者是root的su拷貝到Android手機上,並且把su的權限標誌位置成-rwsr-xr-x。能把這個事情搞定你就成功root了一個手機。大概意思就是兩行代碼cp /data/tmp/su /system/bin/                   #copy su 到/system/分區chown root:root su                                 #su的所有者置成rootchmod 4775 /system/bin/su                   #把su置成-rwsr-xr-x
。已經有root權限的進程都是出廠時候就裝到手機上的,代碼寫死了,你沒法控制它執行你自己的代碼啊。這個時候就需要你找漏洞了,比如用來破解Android2.3 root權限的zergRush漏洞就是利用一個擁有root權限的進程棧溢出漏洞。

》iphone的越獄其實和Android的root是一回事兒,都是越權操作。所以越獄的方式也都差不多,也是找IOS自帶程序的漏洞,只不過IOS安全性強一點,所以也比較難找。如果你發現你的iphone的某個自帶程序經過一些特定操作會出現系統崩潰重啓的現象,並且是可以復現的,那就很有可能可以用來越獄了。
關於sudoandroid的工程裏沒有sudo這個東西。sudo是爲了給普通用戶臨時分配root權限的,Android裏建立了很多用戶,比如wifi,shell等等,這些用戶可以訪問那個文件,不可以訪問那個文件,代碼裏已經寫死了,權限也分配的很分明。它們在運行的過程中不需要臨時獲得root權限。所以Android不需要sudo這個程序。Android系統裏面沒有su這個可執行的文件,提權就是利用Android系統漏洞把su裝入系統。
其實就是linux系統裏面的su命令,切換root用戶,等於window系統的超級管理員。
安卓基於linux,su命令的效果一樣。
root就是在你的安卓系統裏面添加一個su二進制文件,當app需要使用root權限時(一般都是涉及系統文件),就通過執行su文件獲取一個root的權限。
而我們需要一個管理app獲取root權限的管理軟件,這個就是平時用到的超級用戶等app。只有安裝了這個管理軟件之後,我們纔可以限制app的root權限,不然的話,如果系統本身不識別你安裝的su文件,app就可以直接使用root權限。
1,Root 是什麼?
2,Android 手機Root 的原理?
3,什麼是SuperUser ?
4,su.c 的作用?
5,setUid() 和setGid() 的左右?
su 源代碼 下載地址:http://download.csdn.net/detail/jinzhu117/4821630
SuperUser 源代碼下載地址:http://download.csdn.net/detail/jinzhu117/4821569

21)Material Desgin這麼好看,爲什麼不出兼容包,讓5.0以下的系統也能要動畫效果
>使用support library或者使用開源控件。google官方,以及一些大牛,給我們提供了一些程序,讓我們在低版本上面可以實現Material風格的程序,V4、V7、V13等。

22)ART模式與Dalvik有什麼不同;
》Dalvik 經過優化,允許在有限的內存中同時運行多個虛擬機的實例,並且每一個Dalvik 應用作爲一個獨立的Linux 進程執行。獨立的進程可以防止在虛擬機崩潰的時候所有程序都被關閉。
》安卓4.4的升級顛覆了手機運行速度和運行方式,安卓4.2以前的系統使用的是傳統Dalvik模式,
測試了電量,分別對Nexus 5的兩種模式進行了續航測試,在4小時的中等強度測試下發現ART模式下要略比Dalvik模式省電一些,打開省電%5到%8左右的。
ART模式與Dalvik究竟有什麼本質的不同?比如Dalvik模式像一臺摺疊自行車,每次騎之前都要組裝後才能上路,ART(Android runtime)模式就是一個已經裝好的自行車,直接就能騎走了。
所以說適配ART模式,是目前最新的一種系統體驗!也是安卓系統解決吃硬件的最好解決方法!
Android4.4採用ART取代Dalvik,簡單理解就是Android程序運行的根本機制改變了,程序會啓動地更快,而且會更省資源。表現在用戶體驗上,就是Android更流暢了,同時續航能力顯著增加。
ART模式與Dalvik模式最大的不同在於,在啓用ART模式後,系統在安裝應用的時候會進行一次預編譯,在安裝應用程序時會先將代碼轉換爲機器語言存儲在本地,這樣在運行程序時就不會每次都進行一次編譯了,執行效率也大大提升。
》ART模式和Dalvik模式,相比較而言ART模式就很好的解決了這個問題,通過在安裝應用程序時,自動對程序進行代碼預讀取編譯,讓程序直接編譯成機器語言,免去了Dalvik模式要時時轉換代碼,實現高效率、省電、佔用更低的系統內存、手機運行流暢。但凡事總有正反兩面,ART在解決了該問題的同時,同時也有如:會佔用略高一些的存儲空間、安裝程序時要相比普通Dalvik模式要長一些時間來實現預編譯
》Android操作系統已經成熟,Google的Android團隊開始將注意力轉向一些底層組件,其中之一是負責應用程序運行的Dalvik運行時。Google開發者已經花了兩年時間開發更快執行效率更高更省電的替代ART運行時。 ART代表Android Runtime,其處理應用程序執行的方式完全不同於Dalvik,Dalvik是依靠一個Just-In-Time (JIT)編譯器去解釋字節碼。開發者編譯後的應用代碼需要通過一個解釋器在用戶的設備上運行,這一機制並不高效,但讓應用能更容易在不同硬件和架構上運 行。ART則完全改變了這套做法,在應用安裝時就預編譯字節碼到機器語言,這一機制叫Ahead-Of-Time (AOT)編譯。在移除解釋代碼這一過程後,應用程序執行將更有效率,啓動更快。

ART優點:
1、系統性能的顯著提升。
2、應用啓動更快、運行更快、體驗更流暢、觸感反饋更及時。
3、更長的電池續航能力。
4、支持更低的硬件。

ART缺點:
1、更大的存儲空間佔用,可能會增加10%-20%。
2、更長的應用安裝時間。


23)Render Thread是怎麼工作的;以及視圖繪製
》在硬件加速渲染環境中,Android應用程序窗口的UI渲染是分兩步進行的。第一步是構建Display List,發生在應用程序進程的Main Thread中;第二步是渲染Display List,發生在應用程序進程的Render Thread中。Display List的渲染不是簡單地執行繪製命令,而是包含了一系列優化操作,例如繪製命令的合併執行。
Android系統--視圖繪製主要由以下幾部分組成:
     1) Canvas(畫布)
         提供畫圖所需要的所有工具,即各種draw函數;當前可用的畫布對象有:具有硬件加速的GLES20Canvas和GLES20RecordingCanvas,不使用硬件加速的CompatibleCanvas)。
     2) View(視圖)
         在具體畫布對象上完成各種繪製圖形的操作,可根據需要選擇以上三種畫布中的一種。
     3)  Gl20Renderer(把圖直接繪製到屏幕上)
   它是硬件加速視圖繪製的引擎,負責整個與硬件加速相關的視圖繪製過程,具體功能如下:
           (1) 創建以下實例對象
             ? GLES20Canvas           (Canvas)
             ? GLES20DisplayList      (DisplayList)
             ? GLES20TextureLayer  (HardwareLayer)
             ? GLES20RenderLayer  (HardwareLayer)
             ? SurfaceTexture
             ? Gl20Renderer              (HardwareRenderer)
           (2) 在GlRenderer.draw中調用View.getDisplayList()完成DisplayList命令的錄製,並返回DisplayList
                 注:只有View被attach到硬件加速,才能創建DisplayList;
            真正的命令錄製工作在View.getDisplayList(DisplayList displayList, boolean isLayer)中完成。
          (3) 在GlRenderer.draw中調用GLES20Canvas.drawDisplayList,把DisplayList中錄製的命令回放在畫布上。
           (4) Gl20Renderer對象對應的畫布爲GLES20Canvas,Gl20Renderer對象在畫布上的繪製實際上是繪製在OPENGL繪製上下文對應的主緩衝區。
     4) GLES20DisplayList(把錄製命令錄製到Native的DiplayList中)
         GLES20DisplayList對象創建具體的DisplayList對象及繪製用的畫布(GLES20RecordingCanvas畫布),完成視圖繪製操作的DisplayList命令錄製等工作。
     5) GLES20RenderLayer(繪製到FOB Layer中,當作紋理)
         負責創建硬件Layer層(GLES20Canvas.nCreateLayer)和繪製用到的畫布(GLES20Canvas,使用Layer實例化GLES20Canvas(layer, trans))等工作。
         爲了有效支持視圖的多層繪製,視圖對象可以創建一個HardwareLayer層完成視圖的圖形在硬件紋理上的繪製操作或者其它特效操作,這就是GLES20RenderLayer對象的作用,創建獨立的層並返回相應的畫布供視圖繪製使用。
  1.1 View.draw(Canvas canvas)六步曲
    此函數將把View自身及其所有的子子孫孫繪製到給定的畫布上。其畫圖過程主要分爲以下六步:
      1) 畫背景
      2) 如果需要,保存畫布的層爲未來的淡入淡出做好準備
      3) 畫View本身的內容
      4) 畫它的孩子
      5) 如果需要,畫淡入淡出的邊緣並恢復層
      6) 畫裝飾部分(如:滾動條)

24)不把功能都用H5實現然後把需求都扔給前段的人去做;
》用h5開發出的web app體驗上並不比原生app差太多,但其跨平臺的特性大大減低了開發成本,而且可以快速迭代。

25)ServiceManager、ActivityManager、packageManager 、*****Manager 都弄懂了?
  >在Android系統中用到最多的通信機制就是Binder,Binder主要由Client、Server、ServiceManager和Binder驅動程序組成。其中Client、Service和ServiceManager運行在用戶空間,而Binder驅動程序運行在內核空間。核心組件就是Binder驅動程序了,而ServiceManager提供輔助管理的功能,無論是Client還是Service進行通信前首先要和ServiceManager取得聯繫。而ServiceManager是一個守護進程,負責管理Server並向Client提供查詢Server的功能。
  >Service Manager存在的意義
1.Service Manager能集中管理系統內的所有服務,它能被施加權限控制,並不是任何進程都能註冊服務的。
2.Service Manager支持通過字符串名稱來查找對應的Service。
3.由於各種原因的影響,Server進程可能生死無常。如果有了Service Manager做統一的管理,那麼Client只要向Service Manager做查詢,就能得到Server的最新信息。
  >Service Manager進程的主要工作如下:
    1.初始化binder,打開/dev/binder設備;在內存中爲binder映射128K字節空間;
    2.指定SM對應的代理binder的handle爲0,當client嘗試與SM通信時,需要創建一個handle爲0的代理binder,這裏的代理binder其實就是第一節中描述的那個代理接口;
3.通知binder driver(BD)使SM成爲BD的context manager;
4.維護一個死循環,在這個死循環中,不停地去讀內核中binder driver,查看是否有可讀的內容;即是否有對service的操作要求, 如果有,則調用svcmgr_handler回調來處理請求的操作。
5.SM維護了一個svclist列表來存儲service的信息。

26)Binder 也搞清楚了?
  >Android系統進程間通信機制Binder的總體架構由Client、Server、ServiceManager和驅動程序Binder四個組件構成.
 >binder通信是一種client-server的通信結構,
    1.從表面上來看,是client通過獲得一個server的代理接口,對server進行直接調用;
    2.實際上,代理接口中定義的方法與server中定義的方法是一一對應的;
    3.client調用某個代理接口中的方法時,代理接口的方法會將client傳遞的參數打包成爲Parcel對象;
    4.代理接口將該Parcel發送給內核中的binder driver.
    5.server會讀取binder driver中的請求數據,如果是發送給自己的,解包Parcel對象,處理並將結果返回;
    6.整個的調用過程是一個同步過程,在server處理的時候,client會block住。

27)IPC 也弄明白了?
> 第一種方式就是Intent,Intent可以非常方便的通訊,但是它是非實時的,無法進行實時的像函數調用那樣的實時的通訊。
  但是IPC的根本目的還是爲了實現函數的調用,即使是傳遞數據也是要通過函數調用的方式,爲什麼呢?因爲程序運行總是要知道狀態,要有邏輯上的行爲,因此必須通訊函數才能體現出行爲
  IPC的機制除了進程,或者說不同的應用程序之間進行通訊,同時也能夠讓不同的組件之間進行像普通對象那樣進行實時的調用。因爲Android的組件都是由系統框架統一的進行構建和銷燬,所以你就無法創建對象,因此,就沒有辦法像普通的對象那樣進行組合或者聚合,從而也就沒有辦法進行直接調用。但是IPC的方式就可以讓Activity/Service獲取另外一個Service對象的引用,從而直接調用其上的方法。
  還有,就是這些IPC方法總是產生客戶/服務端模式的調用,也即是客戶端組件(Activity/Service)持有服務端Service的組件,只能是客戶端主動調用服務端的方法,服務端無法反過來調用客戶端的方法,因爲IPC的另一端Service無法獲取客戶端的對象。
  >有三種方式可以進行IPC通訊:
1. 直接使用Binder對象,
  缺點是這種方式不能進行跨進程,跨應用程序的函數調用。只能實現在同一個進程之中,同一個應用程序之中的不同的組件之間通訊。優點就是這種方式使用起來特別簡單,對於公開出來的方法沒有任何的限制,可以傳遞任何的對象,甚至是回調等等。總體上來講如果不需要跨進程,這是最好的實現方式,可以完全實現像普通對象之間的組合和聚合。但是這裏,最好不要像Android文檔中的示例那樣,直接返回Service對象,因爲Service對象會有很多Public的方法,如果直接返回【Service】對象會導致公開很多不必須的方法,一旦Client端調用這些方法,將導致奇怪的現象和Bug,一個方法就是用Proxy對Service對象進行封裝,只公開需要的接口。
2. 使用Messenger對象,
  這是利用了消息循環隊列來進行通訊的,也就是說服務端封裝成了一個Handler,客戶端向這個Handler發送Message,服務端再處理這個Message從而實現通訊。優點,最突出的優點就是它可以保證線程上的安全,或者說時序上的安全。因爲客戶端是向Handler發送消息,而不是直接的函數調用,所以呢?Message都是按先後的順序放到服務端的消息隊列當中,然後再由服務端Service決定如何處理這些Message。因爲直接的函數調用會導致被調用的函數也會出現在調用者的線程之中,也就是說被調用到的函數也會繼續存在於調用者的調用棧中,因此有可能產生線程的問題。而Messenger方式,並不是直接的函數調用,而是僅向Service的Handler發送一個Message,然後調用者就此返回,其調用棧也就此停止,Service可以選擇如何處理這一個Message。Messenger方式即可以在同一個進程之中,也可以跨進程實現真正的IPC。但是它的缺點也是相當的明顯的,就是它是發送一個Message對象,而不是直接的函數調用,所以非常的不直觀,另外,Message對象也無法方便的攜帶過多的參數,如果超過一個對象,只能封裝打包成一個對象然後再放到Message.obj中。需要注意的是,如果是在同一個進程之中,Message可以攜帶任何對象,但如果是跨進程,則Message.obj中存放的必須是實現了Parcelable接口的對象,否則無法實現IPC,會有Exception。還有一個缺點,就是Message對象的標識(Message.what)必須是Client端和Service端都定義一致,否則就無法通訊,這在調試的時候必須注意,因爲這不會有編譯或者運行時錯誤,但就是無法正常工作,是比較隱蔽的Bug。
3. 使用AIDL進程通訊
  這是最正統的IPC方式,實際上Messenger的跨進程通訊的底層也是通過AIDL來實現的。它的優點就是完全是爲跨進程而設計的,接口由AIDL文件指定,Client端和Service端都通過AIDL所描述的接口來進行調用和實現,不容易出錯。需要注意的是接口中的所有的對象都必須實現了Parcelable接口,即使僅僅是在同一個進程之中。它的缺點就是必須要在每一個想要通訊的地方定義一個完全一樣的AIDL文件,否則IPC不會成功,而且它是嚴格的按照IPC的機制來的,所以即使是在同一進程之內,所有的接口的參數和返回值的對象必須是實現了Parcelable接口的,但Binder對象和Messenger就無此限制。需要一點:定義AIDL會嚴格按照IPC的方式進程即使是在同一個進程之中。所以,除非是真的要跨進程通訊,否則不要使用AIDL。

28)FrameWork 層的每個類都折騰了?
> 在寫android代碼時,我們基本不會出現new MyActivity(), new MyService()等等這樣的代碼,要知道android app的編寫語言是java,java的特點是什麼:“一切皆對象”。那麼問題來了,我們寫的activity,service等什麼時候被new出來了的呢,它們是怎樣被new出來的,帶着這個問題我們繼續看下去。
  android framework層架構採用了ioc方式,程序員實現的activity,service等式在android的框架層new出來的,程序猿在完成一個activity後都需要在mainfest註冊。然後android framework層利用反射的方式動態的創建其對象。所以android採用這樣的方式將控制權全部掌握在框架層,客戶端程序員只需要按照其方式實現就行。
  但是緊接着新的問題又會出現,既然我們客戶端程序員不需要new 組件對象,也就是說我們的各個組件間是相互獨立的。然後新的問題產生各組件之間的交互該如何處理呢,android framework爲我們想到了這個問題,所以Intent信使產生了,android設計者通過Intent信使實現各個組件間的交互,不得不說框架的設計確實很好,這裏膜拜大神。
  android的框架層牢牢掌控住客戶端的,包括對象的創建調用等。其中運用的很多好的設計模式以及方法值得我們學習。
  關於framework,更多是做的應用層之下的系統層面的東西。比如電源管理、消息隊列、包管理等等,還包括對硬件的支持及系統提供給上層的硬件功能調用接口。framework的學習必然離不開不斷編譯rom和刷機。這就要求有耐心有時間有興趣。而且由於framework層多數模塊都是以JNI方式被調用的,因此你需要有比較紮實的C語言基礎,之少能看懂程序結構。除此之外,對你想要詳細研讀的模塊在應用層的應用需要有必要的理解。我剛開始看源碼的時候是從電源管理模塊開始看的,就是因爲當時對android系統自帶的電源提醒方式以及電量通知不太滿意,想重新定義更多層級的提醒。剛開始也是一頭霧水,但還是硬着頭皮一點點啃。這個過程中,爲了防止忘記之前看過什麼,所以又不斷對看過的源碼做註釋並做閱讀筆記。大概兩三個月,雖然瞭解的也比較淺顯,但是我的目的達到了。源碼之路漫漫,看個三五年都不一定敢說能夠整體吃透。雖如此,但只要有鑽研的方向和基本的能力,相信工作中遇到的framework層的改動應當還是能夠負擔得住的。

29)Hook 會玩了?
  >如果要攔截惡意軟件對電話、短信等API的調用,在Java或者Dalvik層面是不好進行的,因爲這些層面都沒有提供Hook的手段,而在Native層面,我認爲可行的方案是對電話、短信的運行庫so進行Hook(比如系統運行庫\system\lib\libreference-ril.so或\system\lib\libril.so),如果注入自己的so到上述進程後,並通過dlopen()和dlsym()獲取原有API地址,替換原有API地址爲自己so中的API地址就可以達到Hook的目的。Hook的前提是進程注入,而Linux下最便捷的進程注入手段——ptrace.一種方案:代碼主要功能是注入子進程的地址空間,Hook住子進程執行系統調用時的參數,並反轉其參數,從而逆序輸出ls命令的結果。
  Intel官網上下載了Intel處理器開發手冊《64-ia-32-architectures-software-developer-vol-1-manual.pdf》方纔解答我的問題,尋址方式涉及兩個寄存器,DS和RSI,參考手冊的說法,DS表示數據段的selector,其實這個selector就是index索引的意思,由於x64下字長64bit,即8個字節,索引乘以8即得數據段在內存中的基址,RSI表示數據段內偏移地址,與基址相加即可得出數據的絕對地址,使用此地址直接訪問內存就可以取出數據。

30)各種 SystemService 也知道怎麼運行的了?

31)View 的渲染你明白是怎麼回事了?
》父View與子View
》》消息隊列有如下幾個好處,這大都是由其系統解耦和消息緩存兩點擴展而來的:
提升系統可靠性:
冗餘:Process_B崩潰之後,數據並不會丟失,因爲MQ多采用put-get-delete模式,即,僅當確認message被完成處理之後,才從MQ中移除message;
可恢復:MQ實現解耦,部分進程崩潰,不會拖累整個系統癱瘓,例,Process_B崩潰之後,Process_A仍可向MQ中添加message,並等待Process_B恢復;
可伸縮:有較強的峯值處理能力,通常應用會有突發的訪問流量上升情況,使用足夠的硬件資源時刻待命,空閒時刻較長,資源浪費,而消息隊列卻能夠平滑峯值流量,緩解系統組件的峯值壓力;
提升系統可擴展性:
調整模塊:由於實現解耦,可以很容易調整,消息入隊速率、消息處理速率、增加新的Process;
其他:
單次送達:保證MQ中一個message被處理一次,並且只被處理一次。本質:get獲取一個message後,這一message即被預定,同一進程不會再次獲取這一message;當且僅當進程處理完這一message後,MQ中會delete這個message。否則,過一段時間後,這一message自動解除被預訂狀態,進程能夠重新預定這個message;
排序保證:即,滿足隊列的FIFO,先入先出策略;
異步通信:很多場景下,不會立即處理消息,這是,可以在MQ中存儲message,並在某一時刻再進行處理;
數據流的階段性能定位:獲取用戶某一操作的各個階段(通過message來標識),捕獲不同階段的耗時,可用於定位系統瓶頸。

32)Intent 是如何實現 Activity、Service等之間的解耦合的?
》Intent與Android組件之間的關係

33)單元測試會寫了?
》Eclipse與Android Studio的環境配置。

34)Monkey 能跑多長時間?

35)性能測試通過了?

36)ClassLoader 和 DexLoader 會玩了?

40)Android翻頁效果原理實現之引來折線??

37)Context 是個啥你也知道了?
>Context字面意思上下文,或者叫做場景,也就是用戶與操作系統操作的一個過程,比如你打電話,場景包括電話程序對應的界面,以及隱藏在背後的數據.Activity、Service、Application都是Context的子類;Android系統的角度來理解:Context是一個場景,代表與操作系統的交互的一種過程。從程序的角度上來理解:Context是個抽象類,而Activity、Service、Application等都是該類的一個實現。在其內部引用了一個Activity作爲Context,也就是說,我們的這個Activity只要我們的項目活着,就沒有辦法進行內存回收。而我們的Activity的生命週期肯定沒這麼長,所以造成了內存泄漏。
>因此應用程序App共有的Context數目公式爲:
總Context實例個數 = Service個數 + Activity個數 + 1(Application對應的Context實例)
>避免context相關的內存泄露,記住以下幾點:
1. 不要讓生命週期長的對象引用activity context,即保證引用activity的對象要與activity本身生命週期是一樣的
2. 對於生命週期長的對象,可以使用application context
3. 避免非靜態的內部類,儘量使用靜態類,避免生命週期問題,注意內部類對外部對象引用導致的生命週期變化

38)權限機制也弄清楚了?
>Android 是一個權限分離的系統 。 這是利用 Linux 已有的權限管理機制,通過爲每一個 Application 分配不同的 uid 和 gid , 從而使得不同的 Application 之間的私有數據和訪問( native 以及 java 層通過這種 sandbox 機制,都可以)達到隔離的目的 。 與此 同時, Android 還 在此基礎上進行擴展,提供了 permission 機制,它主要是用來對 Application 可以執行的某些具體操作進行權限細分和訪問控制,同時提供了 per-URI permission 機制,用來提供對某些特定的數據塊進行 ad-hoc 方式的訪問。
>Android 的權限分離的基礎是建立在 Linux 已有的 uid 、 gid 、 gids 基礎上的 。
UID 。 Android 在 安裝一個應用程序,就會爲 它 分配一個 uid (參考 PackageManagerService 中的 newUserLP 實現)。其中普通 A ndroid 應用程序的 uid 是從 10000 開始分配 (參見 Process.FIRST_APPLICATION_UID ), 10000 以下是系統進程的 uid 。
GID 。對 於普通應用程序來說, gid 等於 uid 。由於每個應用程序的 uid 和 gid 都不相同, 因此不管是 native 層還是 java 層都能夠達到保護私有數據的作用 。
GIDS 。 gids 是由框架在 Application 安裝過程中生成,與 Application 申請的具體權限相關。 如果 Application 申請的相應的 permission 被 granted ,而且 中有對應的 gid s , 那麼 這個 Application 的 gids 中將 包含這個 gid s 。
>一個權限主要包含三個方面的信息:權限的名稱;屬於的權限組;保護級別。一個權限組是指把權限按照功能分成的不同的集合。每一個權限組包含若干具體 權限,例如在 COST_MONEY 組中包含 android.permission.SEND_SMS , android.permission.CALL_PHONE 等和費用相關的權限。
每個權限通過 protectionLevel 來標識保護級別: normal , dangerous , signature , signatureorsystem 。不同的保護級別代表了程序要使用此權限時的認證方式。 normal 的權限只要申請了就可以使用; dangerous 的權限在安裝時需要用戶確認纔可以使用; signature 和 signatureorsystem 的權限需要使用者的 app 和系統使用同一個數字證書。
Package 的權限信息主要 通過在 AndroidManifest.xml 中通過一些標籤來指定。如 <permission> 標籤, <permission-group> 標籤 <permission-tree> 等標籤。如果 package 需要申請使用某個權限,那麼需要使用 <use-permission> 標籤來指定。

39)觸屏事件的分發呢?Handler 、Message 和 Looper 是怎麼跑起來的?
>一個事件由down move up 三個動作組成,其中move動作可以有多個或者0個,但down 和up動作有且只有一個。這個三個動作中down是最先響應的,它是先驅,由它來決定move和up動作響應路線。
>Touch事件分發中只有兩個主角:ViewGroup和View。Activity的Touch事件事實上是調用它內部的ViewGroup的Touch事件,可以直接當成ViewGroup處理。
View在ViewGroup內,ViewGroup也可以在其他ViewGroup內,這時候把內部的ViewGroup當成View來分析。
ViewGroup的相關事件有三個:onInterceptTouchEvent、dispatchTouchEvent、onTouchEvent。View的相關事件只有兩個:dispatchTouchEvent、onTouchEvent。
先分析ViewGroup的處理流程:首先得有個結構模型概念:ViewGroup和View組成了一棵樹形結構,最頂層爲Activity的ViewGroup,下面有若干的ViewGroup節點,每個節點之下又有若干的ViewGroup節點或者View節點
總:在Android方面,自己擅長什麼?->業務邏輯控制稍微多點,有自己的一些模塊的積累,對UI繪製稍微少點
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章