Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發-基本概念小整理(三)為了面試的小伙伴們所准備~~

Android開發-基本概念小整理(三)為了面試的小伙伴們所准備~~

編輯:關於Android編程

46.什麼是ANR 如何避免它?

NR:Application Not Responding,五秒在Android中,活動管理器和窗口管理器這兩個系統服務負責監視應用程序的響應。當出現下列情況時,Android就會顯示ANR對話框了:

對輸入事件(如按鍵、觸摸屏事件)的響應超過5秒。

意向接受器(intentReceiver)超過10秒鐘仍未執行完畢。

Android應用程序完全運行在一個獨立的線程中(例如main)。這就意味著,任何在主線程中運行的,需要消耗大量時間的操作都會引發ANR。因為此時,你的應用程序已經沒有機會去響應輸入事件和意向廣播(Intentbroadcast)。

因此,任何運行在主線程中的方法,都要盡可能的只做少量的工作。特別是活動生命周期中的重要方法如onCreate()和onResume()等更應如此。潛在的比較耗時的操作,如訪問網絡和數據庫;或者是開銷很大的計算,比如改變位圖的大小,需要在一個單獨的子線程中完成(或者是使用異步請求,如數據庫操作)。但這並不意味著你的主線程需要進入阻塞狀態已等待子線程結束-- 也不需要調用Therad.wait()或者Thread.sleep()方法。取而代之的是,主線程為子線程提供一個句柄(Handler),讓子線程在即將結束的時候調用它(xing:可以參看Snake的例子,這種方法與以前我們所接觸的有所不同)。使用這種方法涉及你的應用程序,能夠保證你的程序對輸入保持良好的響應,從而避免因為輸入事件超過5秒鐘不被處理而產生的ANR。這種實踐需要應用到所有顯示用戶界面的線程,因為他們都面臨著同樣的超時問題。

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

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

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

在Android中不能直接打開res aw目錄中的數據庫文件,而需要在程序第一次啟動時將該文件復制到手機內存或SD卡的某個目錄中,然後再打開該數據庫文件。復制的基本方法是使用getResources().openRawResource方法獲得resaw目錄中資源的InputStream對象,然後將該InputStream對象中的數據寫入其他的目錄中相應文件中。在Android SDK中可以使用SQLiteDatabase.openOrCreateDatabase方法來打開任意目錄中的SQLite數據庫文件。

49.Android引入廣播機制的用意?

a:從MVC的角度考慮(應用程序內)

其實回答這個問題的時候還可以這樣問,android為什麼要有那4大組件,現在的移動開發模型基本上也是照搬的web那一套MVC架構,只不過是改了點嫁妝而已。android的四大組件本質上就是為了實現移動或者說嵌入式設備上的MVC架構,它們之間有時候是一種相互依存的關系,有時候又是一種補充關系,引入廣播機制可以方便幾大組件的信息和數據交互。

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

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

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

50.如果後台的Activity由於某種原因被系統回收,如何在回收之前保存當前狀態。

這個知識點使用描述的方式來回答的,同樣問題,我們在基本概念小整理(一)的17題問過了,那邊是用代碼回答的。

onSaveInstanceState().

程序中的某一個ActivityA 在運行時,主動或被動的運行另一個新的Activity B,這個時候A會執行onSaveInstanceState()。B完成以後又回來找A,這個時候有兩種情況:一是A被回收,二是A沒有被回收,被回收的A就要重新調用onCreate()方法,不同於直接啟動的是這回onCreate()裡是帶上了參數savedInstanceState;而沒被回收的就直接執行onResume(),跳過onCreate()。

51.Android 事件分發機制原理。

1、 Android事件分發是先傳遞到ViewGroup,再由ViewGroup傳遞到View的。

2、 在ViewGroup中可以通過onInterceptTouchEvent方法對事件傳遞進行攔截,onInterceptTouchEvent方法返回true代表不允許事件繼續向子View傳遞,返回false代表不對事件進行攔截,默認返回false。

3、子View中如果將傳遞的事件消費掉,ViewGroup中將無法接收到任何事件。

52.Android 繪圖機制原理。

View樹的繪制是一個遞歸的過程,從ViewGroup一直向下遍歷,直到所有的子view都完成繪制,View樹的源頭是ViewRoot。

ViewRoot中包含了窗口的總容器DecorView,ViewRoot中的performTraversal()方法會依次調用decorView的measure、layout、draw方法,從而完成view樹的繪制。

invalidate()方法會導致View樹的重新繪制,而且view中的狀態標志mPrivateFlags中有一個關於當前視圖是否需要重繪的標志位DRAWN,也就是說只有標志位DRAWN置位的視圖才需要進行重繪。當視圖調用invalidate()方法時,首先會將當前視圖的DRAWN標志置位,之後有一個循環調用parent.invalidateChildinParent(),這樣會導致從當前視圖依次向上遍歷直到根視圖ViewRoot,這個過程會將需要重繪的視圖標記DRAWN置位,之後ViewRoot調用performTraversals()方法,完成視圖的繪制過程。

53.Android WindowManager。

WindowManager主要用來管理窗口的一些狀態、屬性、view增加、刪除、更新、窗口順序、消息收集和處理等。通過Context.getSystemService(Context.WINDOW_SERVICE)的方式可以獲得WindowManager的實例.WindowManager繼承自ViewManager,裡面涉及到窗口管理的三個重要方法,分別是:addView()、 updateViewLayout()、removeView()。

在WindowManager中還有一個重要的靜態類LayoutParams.通過它可以設置和獲得當前窗口的一些屬性。

我們先來看看addView()方法,在addView中,會利用LayoutParams獲得window的View屬性,並為每個window創建ViewRoot,ViewRoot是View和WindowManager之間的橋梁,真正把View傳遞給WindowManager的是通過ViewRoot的setView()方法,ViewRoot實現了View和WindowManager之間的消息傳遞。在將主窗口添加到WindowManger時,它首先會建立一個代理對象:

wm=(WindowManagerImpl)context.getSystemService(Context.WINDOW_SERVICE)並且打開會話(IWindowSession),之後Window將通過該會話與WindowManager建立聯系。br />ViewRoot通過IWindowSession把窗口添加到WindowManager中。ViewRoot繼承了Handler,實際上它的本質就是一個Handler,窗口中View的事件處理、消息發送、回調等將通過ViewRoot來處理。

這樣就完成了把窗口添加到WindowManager中,並交由WindowManager來管理窗口的view、事件、消息收集處理等。

54.Android 進程間通信方式。

進程:在 Android 裡面,進程是一組組件的集合。默認下,同一個應用的所有組件都運行在同一個進程中並且大多數程序不必改變這一狀況.然而,如果你非要與眾不同,也可以通過修改 AndroidManifest.xml 文件中修改四大組件(activity,service,receiver和provider)的process 屬性來指定該組件運行在哪一個進程裡。

由於 Android 本身設計的原因,進程間的數據是無法直接共享的,如果我們需要知道不同進程間的一些數據,就需要進行進程間通信操作。下面總結了以下進程間通信的一些方法。

1、Intent數據共享

Activity:

Intent intent = new Intent();

intent.setClassName("otherpackage","OtherActivity");

intent.putExtra("key","value");

startActivity(intent);

OtherActivity:

String value = getIntent().getStringExtra("key");

2、Broadcast廣播跨進程通信

Intent broadcast = new Intent("my.broadcast.action");

broadcast.putExtra("key","value");

sendBroadcast(broadcast);

3、Content Provider

比如獲取一個聯系人的詳情。聯系人的詳情時存在系統裡面的,我們的應用一定不會和系統程序在一個進程,Content Provider 很明顯就是一個跨進程通信的方法。

4、AIDL

AIDL(Android Interface Definition Language)Android接口定義語言,用於生成可以在Android設備上兩個進程之間進行進程間通信(interprocess communication, IPC)的代碼。

5、Messnger

們可以在客戶端發送一個Message給服務端,在服務端的handler中會接收到客戶端的消息,然後進行對應的處理,處理完成後,再將結果等數據封裝成Message,發送給客戶端,客戶端的handler中會接收到處理的結果。

6、文件

通過讀寫同一個文件的確是可以做到進程間通信的。

55.你是怎麼設計項目架構的?

經典架構有MVC,MVP,MVVM,CLEAN等。

MVC全名是Model View Controller,是模型(model)-視圖(view)-控制器(controller)的縮寫。

MVP全名是Model View Presenter,是模型(model)-視圖(view)-表示器(presenter)的縮寫。

所有架構,都是為了解耦,提高維護性。

解耦可在生產中實際效果是,把一個大工程,拆分成多個小工程,每個工程之間功能相互獨立,可單獨測試。把單線程變成多線程,一個人一年的工作量,拆成12個人,一個月就能做完。每個人只專注於自己那部分,對於大項目,或者工期緊的項目是非常重要的。要掌握好度,簡單的功能無需再分。

56.BaseActivity、BaseFragment怎麼設計?

如果是只有一個Activity的App就沒有必要寫BaseActivity,大於一個一般可以寫BaseActivity。

每個Activity通常都是綁定視圖,綁定控件,監聽控件,獲取Bundle,跳轉Activity還有一些很有些煩人的小功能如:Toast,findViewById,我們都可以封裝一層簡化他們的使用。

不僅是Activity要搞一個基類,Fragment也要搞一個基類,這樣可以大大減少重復代碼,而且管理起來還比較容易,保持了樣式的一致,也要預留個性化相應的方法。

57.你項目中的package劃分,是按照層次劃分的呢,還是按照功能劃分的呢?

如果涉及團隊協作開發,建議按模塊劃分。因為業務模塊之間的耦合性相對於層級的耦合性要低,這樣程序員在開發模塊時,基本上要開發action、service、orm,這樣開發的接觸面比較全,而且基本上不需要與其它模塊進行交互,減少溝通交流時間,能提高開發效率。如果按照層級劃分,那麼多人開發時,會存在action依賴service,而service由別人開發,會涉及到交流、溝通(如:action需要的業務方法,需要先告訴service開發人員……等等若干情況)

58.Android OOP AOP。

OOP,即Object Oriented Programming,面向對象編程。

AOP,即Aspect Oriented Programming,面向切向編程。

OOP,問題或者功能都被劃分到一個一個的模塊裡邊。每個模塊專心干自己的事情,模塊之間通過設計好的接口交互。OOP的精髓是把功能或問題模塊化,每個模塊處理自己的家務事。但在現實世界中,並不是所有問題都能完美得劃分到模塊中。有些功能是橫跨並嵌入眾多模塊裡的,比如打印日志,比如統計某個模塊中某些函數的執行時間等。這些功能在各個模塊裡分散得很厲害,可能到處都能見到。

AOP的目標是把這些功能集中起來,放到一個統一的地方來控制和管理。如果說,OOP如果是把問題劃分到單個模塊的話,那麼AOP就是把涉及到眾多模塊的某一類問題進行統一管理。比如我們可以設計兩個Aspects,一個是管理某個軟件中所有模塊的日志輸出的功能,另外一個是管理該軟件中一些特殊函數調用的權限檢查。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved