天天看點

android面試題

1.    請描述下Activity的生命周期。2.    如果背景的Activity由于某原因被系統回收了,如何在被系統回收之前儲存目前狀态?3.    如何将一個Activity設定成視窗的樣式。(Edited by Sodino)4.    如何退出Activity?如何安全退出已調用多個Activity的Application?5.    請介紹下Android中常用的五種布局。6.    請介紹下Android的資料存儲方式。(Edited by Sodino)7.    請介紹下ContentProvider是如何實作資料共享的。(Edited by Sodino)8.    如何啟用Service,如何停用Service。(Edited by Sodino)9.    注冊廣播有幾種方式,這些方式有何優缺點?請談談Android引入廣播機制的用意。10.    請解釋下在單線程模型中Message、Handler、Message Queue、Looper之間的關系。11.    AIDL的全稱是什麼?如何工作?能處理哪些類型的資料?12.    請解釋下Android程式運作時權限與檔案系統權限的差別。(Edited by Sodino)13.    系統上安裝了多種浏覽器,能否指定某浏覽器通路指定頁面?請說明原由。14.    有一個一維整型數組int[]data儲存的是一張寬為width,高為height的圖檔像素值資訊。請寫一個算法,将該圖檔所有的白色不透明(0xffffffff)像素點的透明度調整為50%。15.    你如何評價Android系統?優缺點。

1.    請描述下Activity的生命周期

http://weizhulin.blog.51cto.com/1556324/311495

詳細介紹一下這幾個方法中系統在做什麼以及我們應該做什麼:

  onCreate:   在這裡建立界面 ,做一些資料的初始化工作

  onStart:   到這一步變成使用者可見不可互動 的

  onResume:   變成和使用者可互動 的,(在activity棧系統通過棧的方式管理這些個      

                     Activity的最上面,運作完彈出棧,則回到上一個Activity)

  onPause:    到這一步是可見但不可互動 的,系統會停止動畫 等消耗CPU 的事情

                   從上文的描述已經知道,應該在這裡儲存你的一些資料,因為這個時候

                   你的程式的優先級降低,有可能被系統收回。在這裡儲存的資料,應該在

                   onResume裡讀出來,注意:這個方法裡做的事情時間要短,因為下一

                   個activity不會等到這個方法完成才啟動

  onstop:    變得不可見 ,被下一個activity覆寫了

   onDestroy:這是activity被幹掉前最後一個被調用方法了,可能是外面類調用finish方

                    法或者是系統為了節省空間将它暫時性的幹掉,可以用isFinishing()來判

                    斷它,如果你有一個Progress Dialog線上程中轉動,請在onDestroy裡

                    把他cancel掉,不然等線程結束的時候,調用Dialog的cancel方法會抛

                    異常的。

onPause,onstop, onDestroy,三種狀态 下 activity都有可能被系統幹掉

為了保證程式的正确性,你要在onPause()裡寫上持久層操作的代碼,将使用者編輯的内容都儲存到存儲媒體上(一般都是資料庫)。實際工作中因為生命周期的變化而帶來的問題也很多,比如你的應用程式起了新的線程在跑,這時候中斷了,你還要去維護那個線程,是暫停還是殺掉還是資料復原,是吧?因為Activity可能被殺掉,是以線程中使用的變量和一些界面元素就千萬要注意了,一般我都是采用Android的消息機制[Handler,Message]來處理多線程和界面互動的問題。這個我後面會講一些,最近因為這些東西頭已經很大了,等我理清思緒再跟大家分享。

2.    如果背景的Activity由于某原因被系統回收了,如何在被系統回收之前儲存目前狀态?

當你的程式中某一個Activity A 在運作時中,主動或被動地運作另一個新的Activity B

這個時候A會執行Java代碼

  • public
  • void onSaveInstanceState(Bundle outState) {   
  • super.onSaveInstanceState(outState);   
  •     outState.putLong("id", 1234567890);   
  • }   
  • void onSaveInstanceState(Bundle outState) {    super.onSaveInstanceState(outState);    outState.putLong("id", 1234567890);}

B 完成以後又會來找A, 這個時候就有兩種情況,一種是A被回收,一種是沒有被回收,被回

收的A就要重新調用onCreate()方法,不同于直接啟動的是這回onCreate()裡是帶上參數

savedInstanceState,沒被收回的就還是onResume就好了。

savedInstanceState是一個Bundle對象,你基本上可以把他了解為系統幫你維護的一個Map對象。在onCreate()裡你可能會用到它,如果正常啟動onCreate就不會有它,是以用的時候要判斷一下是否為空。

Java代碼

if(savedInstanceState !=null){  

    long id =savedInstanceState.getLong("id");  

}  

if(savedInstanceState !=null){    long id = savedInstanceState.getLong("id");}

就像官方的Notepad教程裡的情況,你正在編輯某一個note,突然被中斷,那麼就把這個note的id記住,再起來的時候就可以根據這個id去把那個note取出來,程式就完整一些。這也是看你的應用需不需要儲存什麼,比如你的界面就是讀取一個清單,那就不需要特殊記住什麼,哦,沒準你需要記住滾動條的位置...

3.    如何将一個Activity設定成視窗的樣式簡單你隻需要設定 一下Activity的主題就可以了在AndroidManifest.xml 中定義 Activity的

地方一句話:

Xml代碼

  • android :theme="@android:style/Theme.Dialog"
  • android:theme="@android:style/Theme.Dialog"
這就使你的應用程式變成對話框的形式彈出來了,或者
  • android:theme="@android:style/Theme.Translucent"

就變成半透明的,[友情提示-.-]類似的這種activity的屬性可以在android.R.styleable類的AndroidManifestActivity方法中看到,AndroidManifest.xml中所有元素的屬性的介紹都可以參考這個類android.R.styleable

上面說的是屬性名稱,具體有什麼值是在android.R.style中可以看到,比如這個"@android:style/Theme.Dialog"就對應于android.R.style.Theme_Dialog ,('_'換成'.'<--注意:這個是文章内容不是笑臉)就可以用在描述檔案中了,找找類定義和描述檔案中的對應關系就都明白了。

4.    如何退出Activity

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

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

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

1、抛異常強制退出:

該方法通過抛異常,使程式Force Close。

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

2、記錄打開的Activity:

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

3、發送特定廣播:

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

4、遞歸退出

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

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

但是這樣做同樣不完美。

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

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

為了程式設計友善,最好定義一個Activity基類,處理這些共通問題。

5.請介紹下Android中常用的五種布局

Android布局是應用界面開發的重要一環,在Android中,共有五種布局方式,分别是:FrameLayout(架構布局),LinearLayout (線性布局),AbsoluteLayout(絕對布局),RelativeLayout(相對布局),TableLayout(表格布局)。

    一、FrameLayout

    這個布局可以看成是牆腳堆東西,有一個四方的矩形的左上角牆腳,我們放了第一個東西,要再放一個,那就在放在原來放的位置的上面,這樣依次的放,會蓋住原來的東西。這個布局比較簡單,也隻能放一點比較簡單的東西。

    二、LinearLayout

    線性布局,這個東西,從外框上可以了解為一個div,他首先是一個一個從上往下羅列在螢幕上。每一個LinearLayout裡面又可分為垂直布局(android:orientation="vertical")和水準布局(android:orientation="horizontal" )。當垂直布局時,每一行就隻有一個元素,多個元素依次垂直往下;水準布局時,隻有一行,每一個元素依次向右排列。

    linearLayout中有一個重要的屬性 android:layout_weight="1",這個weight在垂直布局時,代表行距;水準的時候代表列寬;weight值越大就越大。

    三、AbsoluteLayout

    絕對布局猶如div指定了absolute屬性,用X,Y坐标來指定元素的位置android:layout_x="20px" android:layout_y="12px" 這種布局方式也比較簡單,但是在垂直随便切換時,往往會出問題,而且多個元素的時候,計算比較麻煩。

    四、RelativeLayout

    相對布局可以了解為某一個元素為參照物,來定位的布局方式。主要屬性有:

    相對于某一個元素

    android:layout_below="@id/aaa" 該元素在 id為aaa的下面

    android:layout_toLeftOf="@id/bbb" 改元素的左邊是bbb

    相對于父元素的地方

    android:layout_alignParentLeft="true"  在父元素左對齊

    android:layout_alignParentRight="true" 在父元素右對齊

    還可以指定邊距等,具體詳見API

    五。TableLayout

    表格布局類似Html裡面的Table。每一個TableLayout裡面有表格行TableRow,TableRow裡面可以具體定義每一個元素,設定他的對齊方式 android:gravity="" 。

    每一個布局都有自己适合的方式,另外,這五個布局元素可以互相嵌套應用,做出美觀的界面。

6.    請介紹下Android的資料存儲方式

Android提供了5種方式存儲資料:

--使用SharedPreferences存儲資料;

--檔案存儲資料;

--SQLite資料庫存儲資料;

--使用ContentProvider存儲資料;

--網絡存儲資料;[url=]先 說下,Preference,File,DataBase這三種方式分别對應的目錄是/data/data/Package Name/Shared_Pref,/data/data/Package Name/files, /data/data/Package Name/database。[/url]在Android中通常使用File存儲方式是用Context.openFileOutput(StringfileName, int mode)和Context.openFileInput(String fileName)。

Context.openFileOutput(String fileName, intmode)生成的檔案自動存儲在/data/data/PackageName/files目錄下,其全路徑是/data/data/Package Name/files/fileName。注意下,這裡的參數fileName不可以包含路徑分割符(如"/")。

通常來說,這種方式生成的檔案隻能在這個apk内通路。但這個結論是指使用Context.openFileInput(StringfileName)的方式。使用這種方式,每個apk隻可以通路自己的/data/data/PackageName/files目錄下的檔案,原因很簡單,參數fileName中不可以包含路徑分割符,Android會自動在/data/data/PackageName/files目錄下尋找檔案名為fileName的檔案。一:使用SharedPreferences存儲資料

首先說明SharedPreferences存儲方式,它是Android提供的用來存儲一些簡單配置資訊的一種機制,例如:登入使用者的使用者名與密碼。其采用了Map資料結構來存儲資料,以鍵值的方式存儲,可以簡單的讀取與寫入,具體執行個體如下:

void ReadSharedPreferences(){

String strName,strPassword;

SharedPreferences   user =getSharedPreferences(“user_info”,0);

strName = user.getString(“NAME”,””);

strPassword = user getString(“PASSWORD”,””);

}

void WriteSharedPreferences(String strName,StringstrPassword){

uer.edit();

user.putString(“NAME”, strName);

user.putString(“PASSWORD” ,strPassword);

user.commit();

資料讀取與寫入的方法都非常簡單,隻是在寫入的時候有些差別:先調用edit()使其處于編輯狀态,然後才能修改資料,最後使用commit()送出修改的資料。實際上SharedPreferences是采用了XML格式将資料存儲到裝置中,在DDMS中的FileExplorer中的/data/data/<packagename>/shares_prefs下。以上面的資料存儲結果為例,打開後可以看到一個user_info.xml的檔案,打開後可以看到:

<?xml version=”1.0″encoding=”UTF-8″?>

<map>

<stringname=”NAME”>moandroid</string>

<string name=”PASSWORD”>SharedPreferences</string>

</map>

使用SharedPreferences是有些限制的:隻能在同一個包内使用,不能在不同的包之間使用。二:檔案存儲資料

檔案存儲方式是一種較常用的方法,在Android中讀取/寫入檔案的方法,與Java中實作I/O的程式是完全一樣的,提供了openFileInput()和openFileOutput()方法來讀取裝置上的檔案。FilterInputStream, FilterOutputStream等可以到Java iopackage說明中去詳細學習,不再此詳細說明,具體執行個體如下:

String fn = “moandroid.log”;

FileInputStream fis = openFileInput(fn);

FileOutputStream fos =openFileOutput(fn,Context.MODE_PRIVATE);

除此之外,Android還提供了其他函數來操作檔案,詳細說明請閱讀Android SDK。

三:網絡存儲資料

網絡存儲方式,需要與Android網絡資料包打交道,關于Android 網絡資料包的詳細說明,請閱讀Android SDK引用了JavaSDK的哪些package?。四:ContentProvider

1、ContentProvider簡介

當應用繼承ContentProvider類,并重寫該類用于提供資料和存儲資料的方法,就可以向其他應用共享其資料。雖然使用其他方法也可以對外共享資料,但資料通路方式會因資料存儲的方式而不同,如:采用檔案方式對外共享資料,需要進行檔案操作讀寫資料;采用sharedpreferences共享資料,需要使用sharedpreferencesAPI讀寫資料。而使用ContentProvider共享資料的好處是統一了資料通路方式。?

2、Uri類簡介

Uri代表了要操作的資料,Uri主要包含了兩部分資訊:1.需要操作的ContentProvider,2.對ContentProvider中的什麼資料進行操作,一個Uri由以下幾部分組成:

1.scheme:ContentProvider(内容提供者)的scheme已經由Android所規定為:content://。

2.主機名(或Authority):用于唯一辨別這個ContentProvider,外部調用者可以根據這個辨別來找到它。

3.路徑(path):可以用來表示我們要操作的資料,路徑的建構應根據業務而定,如下:

? 要操作contact表中id為10的記錄,可以建構這樣的路徑:/contact/10

? 要操作contact表中id為10的記錄的name字段, contact/10/name

? 要操作contact表中的所有記錄,可以建構這樣的路徑:/contact?

要操作的資料不一定來自資料庫,也可以是檔案等他存儲方式,如下:

要操作xml檔案中contact節點下的name節點,可以建構這樣的路徑:/contact/name

如果要把一個字元串轉換成Uri,可以使用Uri類中的parse()方法,如下:

Uri uri =Uri.parse("content://com.changcheng.provider.contactprovider/contact")

3、UriMatcher、ContentUrist和ContentResolver簡介

因為Uri代表了要操作的資料,是以我們很經常需要解析Uri,并從Uri中擷取資料。Android系統提供了兩個用于操作Uri的工具類,分别為UriMatcher和ContentUris 。掌握它們的使用,會便于我們的開發工作。

? UriMatcher:用于比對Uri,它的用法如下:

1.首先把你需要比對Uri路徑全部給注冊上,如下:

//常量UriMatcher.NO_MATCH表示不比對任何路徑的傳回碼(-1)。

UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

//如果match()方法比對content://com.changcheng.sqlite.provider.contactprovider/contact路徑,傳回比對碼為1

uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider”,“contact”, 1);//添加需要比對uri,如果比對就會傳回比對碼

//如果match()方法比對content://com.changcheng.sqlite.provider.contactprovider/contact/230路徑,傳回比對碼為2

uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider”,“contact/#”, 2);//#号為通配符

2.注冊完需要比對的Uri後,就可以使用uriMatcher.match(uri)方法對輸入的Uri進行比對,如果比對就傳回比對碼,比對碼是調用addURI()方法傳入的第三個參數,假設比對content://com.changcheng.sqlite.provider.contactprovider/contact路徑,傳回的比對碼為1。

?

ContentUris:用于擷取Uri路徑後面的ID部分,它有兩個比較實用的方法:

? withAppendedId(uri, id)用于為路徑加上ID部分

? parseId(uri)方法用于從路徑中擷取ID部分

? ContentResolver:當外部應用需要對ContentProvider中的資料進行添加、删除、修改和查詢操作時,可以使用ContentResolver 類來完成,要擷取ContentResolver對象,可以使用Activity提供的getContentResolver()方法。ContentResolver使用insert、delete、update、query方法,來操作資料。五:總結說明

以上5中存儲方式,在以後的開發過程中,根據設計目标、性能需求、空間需求等找到合适的資料存儲方式。Android中的資料存儲都是私有的,其他應用程式都是無法通路的,除非通過ContentResolver擷取其他程式共享的資料。采用檔案方式對外共享資料,需要進行檔案操作讀寫資料;采用sharedpreferences共享資料,需要使用sharedpreferencesAPI讀寫資料。而使用ContentProvider共享資料的好處是統一了資料通路方式。8.如何啟用Service,