Android 面試題


1請描述下Activity的生命週期

在屏幕的前臺(Activity棧頂),叫做活動狀態或者運行狀態(active or running

v 如果一個Activity失去焦點,但是依然可見(一個新的非全屏的Activity 或者一個透明的Activity 被放置在棧頂),叫做暫停狀態(Paused)。一個暫停狀態的Activity依然保持活力(保持所有的狀態,成員信息,和窗口管理器保持連接),但是在系統內存極端低下的時候將被殺掉。

v 如果一個Activity被另外的Activity完全覆蓋掉,叫做停止狀態(Stopped)。它依然保持所有狀態和成員信息,但是它不再可見,所以它的窗口被隱藏,當系統內存需要被用在其他地方的時候,StoppedActivity將被殺掉。

v 如果一個ActivityPaused或者Stopped狀態,系統可以將該Activity從內存中刪除,Android系統採用兩種方式進行刪除,要麼要求該Activity結束,要麼直接殺掉它的進程。當該Activity再次顯示給用戶時,它必須重新開始和重置前面的狀態。

 下面的圖顯示了Activity的重要狀態轉換,矩形框表明Activity在狀態轉換之間的回調接口,開發人員可以重載實現以便執行相關代碼,帶有顏色的橢圓形表明Activity所處的狀態。



在上圖中,Activity有三個關鍵的循環: 

v 整個的生命週期,從onCreate(Bundle)開始到onDestroy()結束。ActivityonCreate()設置所有的全局狀態,在onDestory()釋放所有的資源。例如:某個Activity有一個在後臺運行的線程,用於從網絡下載數據,則該Activity可以在onCreate()中創建線程,onDestory()中停止線程。

v 可見的生命週期,從onStart()開始到onStop()結束。在這段時間,可以看到Activity在屏幕上,儘管有可能不在前臺,不能和用戶交互。在這兩個接口之間,需要保持顯示給用戶的UI數據和資源等,例如:可以在onStart中註冊一個IntentReceiver來監聽數據變化導致UI的變動,當不再需要顯示時候,可以在onStop()中註銷它。onStart()onStop()都可以被多次調用,因爲Activity隨時可以在可見和隱藏之間轉換。

v 前臺的生命週期,從onResume()開始到onPause()結束。在這段時間裏,該Activity處於所有 Activity的最前面,和用戶進行交互。Activity可以經常性地在resumedpaused狀態之間切換,例如:當設備準備休眠時,當一個 Activity處理結果被分發時,當一個新的Intent被分發時。所以在這些接口方法中的代碼應該屬於非常輕量級的。

2. 如果後臺的Activity由於某原因被系統回收了,如何在被系統回收之前保存當前狀態?

    當一個Activitypause或者stop的時候,這個Activity的對象實際上還是保存在內存中,因此這個Activity中的信息(成員和狀態信息)還可以重新獲取到

    如果系統爲了整理內存而銷燬了整合各Activity對象時,系統沒法簡單的原封不動地恢復先前的Activity對象及其狀態信息

    從android手冊上來看,Activity中提供了一個方法:onSavedInstanceState(Bundle obj).當系統銷燬一個Activity,會將Activity的狀態信息已鍵值對形式存放在bundle對象中

    第一次啓動Activity,這個bundle對象是空的,null.如果Activity被系統銷燬了,然後用戶要回退回去看的話,系統會調用這個ActivityonCreate方法,並把bundle對象傳遞過去

    這個函數有默認的行爲,因此就算你不覆蓋它,它在Activity中也有實現

    這回我總算明白了爲什麼onCreate方法的定義是"protected void onCreate (Bundle savedInstanceState)"這個樣子的了

    另外,剛纔查看了一下Activity的源碼,發現Activity還有個onRestoreInstanceState(Bundle outState)方法.這個方法的描述中也寫到在Activity回覆先前保存的狀態時會被調用.

3、 如何將一個Activity設置成窗口的樣式。

在你的styles.xml文件中可以新建一如下的style:

    <style name="Theme.FloatActivity" parent="android:style/Theme.Dialog">

        <!-- float_box爲我們定義的窗口背景 ,這個不是必須的-->

        <item name="android:windowBackground">@drawable/float_box</item>

    </style>

4、 如何退出Activity?如何安全退出已調用多個ActivityApplication

對於單一Activity的應用來說,退出很簡單,直接finish()即可。

當然,也可以用killProcess()System.exit()這樣的方法。

但是,對於多Activity的應用來說,在打開多個Activity後,如果想在最後打開的Activity直接退出,上邊的方法都是沒有用的,因爲上邊的方法都是結束一個Activity而已。

當然,網上也有人說可以。

就好像有人問,在應用裏如何捕獲Home鍵,有人就會說用keyCode比較KEYCODE_HOME即可,而事實上如果不修改framework,根本不可能做到這一點一樣。

所以,最好還是自己親自試一下。

那麼,有沒有辦法直接退出整個應用呢?

2.1之前,可以使用ActivityManagerrestartPackage方法。

它可以直接結束整個應用。在使用時需要權限android.permission.RESTART_PACKAGES

注意不要被它的名字迷惑。

可是,在2.2,這個方法失效了。

2.2添加了一個新的方法,killBackgroundProcesses(),需要權限 android.permission.KILL_BACKGROUND_PROCESSES

可惜的是,它和2.2restartPackage一樣,根本起不到應有的效果。

另外還有一個方法,就是系統自帶的應用程序管理裏,強制結束程序的方法,forceStopPackage()

它需要權限android.permission.FORCE_STOP_PACKAGES

並且需要添加android:sharedUserId="android.uid.system"屬性

同樣可惜的是,該方法是非公開的,他只能運行在系統進程,第三方程序無法調用。

因爲需要在Android.mk中添加LOCAL_CERTIFICATE := platform

Android.mk是用於在Android源碼下編譯程序用的。

從以上可以看出,在2.2,沒有辦法直接結束一個應用,而只能用自己的辦法間接辦到。

現提供幾個方法,供參考:

1、拋異常強制退出:

該方法通過拋異常,使程序Force Close

驗證可以,但是,需要解決的問題是,如何使程序結束掉,而不彈出Force Close的窗口。

2、記錄打開的Activity

每打開一個Activity,就記錄下來。在需要退出時,關閉每一個Activity即可。

3、發送特定廣播:

在需要結束應用時,發送一個特定的廣播,每個Activity收到廣播後,關閉即可。

4、遞歸退出

在打開新的Activity時使用startActivityForResult,然後自己加標誌,在onActivityResult中處理,遞歸關閉。

除了第一個,都是想辦法把每一個Activity都結束掉,間接達到目的。

但是這樣做同樣不完美。

你會發現,如果自己的應用程序對每一個Activity都設置了nosensor,在兩個Activity結束的間隙,sensor可能有效了。

但至少,我們的目的達到了,而且沒有影響用戶使用。

5、請介紹下Android中常用的五種佈局

FrameLayout(框架佈局),LinearLayout (線性佈局),AbsoluteLayout(絕對佈局),RelativeLayout(相對佈局),TableLayout(表格佈局)


6、請介紹下Android的數據存儲方式。

.SharedPreferences方式

.文件存儲方式

.SQLite數據庫方式

.內容提供器(Content provider)方式

網絡存儲方式

7、 如何啓用Service,如何停用Service

一.步驟

第一步:繼承Service

public class SMSService extends Service { }

第二步:在AndroidManifest.xml文件中的<application>節點裏對服務進行配置:

<service android:name=".DemoService" />

二.Context.startService()Context.bindService

服務不能自己運行,需要通過調用Context.startService()Context.bindService()方法啓動服務。這兩個方法都可

以啓動Service,但是它們的使用場合有所不同。

1.使用startService()方法啓用服務,調用者與服務之間沒有關連,即使調用者退出了,服務仍然運行。

使用bindService()方法啓用服務,調用者與服務綁定在了一起,調用者一旦退出,服務也就終止。

2.採用Context.startService()方法啓動服務,在服務未被創建時,系統會先調用服務的onCreate()方法,

接着調用onStart()方法。如果調用startService()方法前服務已經被創建,多次調用startService()方法並不會導致多次創建服務,但會導致多次調用onStart()方法。

採用startService()方法啓動的服務,只能調用Context.stopService()方法結束服務,服務結束時會調用onDestroy()方法。 


3.採用Context.bindService()方法啓動服務,在服務未被創建時,系統會先調用服務的onCreate()方法,

接着調用onBind()方法。這個時候調用者和服務綁定在一起,調用者退出了,系統就會先調用服務的onUnbind()方法,接着調用onDestroy()方法。如果調用bindService()方法前服務已經被綁定,多次調用bindService()方法並不會導致多次創建服務及綁定(也就是說onCreate()onBind()方法並不會被多次調用)。如果調用者希望與正在綁定的服務解除綁定,可以調用unbindService()方法,調用該方法也會導致系統調用服務的onUnbind()-->onDestroy()方法。

1.Service常用生命週期回調方法如下:


onCreate() 該方法在服務被創建時調用,該方法只會被調用一次,無論調用多少次startService()bindService()方法,

服務也只被創建一次。 onDestroy()該方法在服務被終止時調用。 


2. Context.startService()啓動Service有關的生命週期方法

onStart() 只有採用Context.startService()方法啓動服務時纔會回調該方法。該方法在服務開始運行時被調用。

多次調用startService()方法儘管不會多次創建服務,但onStart() 方法會被多次調用。


3. Context.bindService()啓動Service有關的生命週期方法

onBind()只有採用Context.bindService()方法啓動服務時纔會回調該方法。該方法在調用者與服務綁定時被調用,

當調用者與服務已經綁定,多次調用Context.bindService()方法並不會導致該方法被多次調用。

onUnbind()只有採用Context.bindService()方法啓動服務時纔會回調該方法。該方法在調用者與服務解除綁定時被調用。

備註:

1. 採用startService()啓動服務

     Intent intent = new Intent(DemoActivity.this, DemoService.class);

     startService(intent);

複製代碼

2.Context.bindService()啓動

Intent intent = new Intent(DemoActivity.this, DemoService.class);

    bindService(intent, conn, Context.BIND_AUTO_CREATE);

   //unbindService(conn);//解除綁定

複製代碼



 8、註冊廣播有幾種方式,這些方式有何優缺點?請談談Android引入廣播機制的用意。

兩種:一種是XML,一種是代碼註冊

           Xml註冊的優點是:方便,易讀

           缺點是當手機處於關機狀態時,仍然可以監聽到廣播,不靈活

          代碼註冊的優點:靈活,手機處於關機狀態時,不在監聽廣播

          缺點:不方便,不容易讀

9請解釋下Android程序運行時權限與文件系統權限的區別 

運行時 Dalvik( android授權

文件系統 linux 內核授權

10.橫豎屏切換時候activity的生命週期  

總結:

1、不設置Activityandroid:configChanges時,切屏會重新調用各個生命週期,切橫屏時會執行一次,切豎屏時會執行兩次

2、設置Activityandroid:configChanges="orientation"時,切屏還是會重新調用各個生命週期,切橫、豎屏時只會執行一次

3、設置Activityandroid:configChanges="orientation|keyboardHidden"時,切屏不會重新調用各個生命週期,只會執行onConfigurationChanged方法 



 


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