編輯:關於Android編程
26.如果後台的Activity由於某原因被系統回收了,如何在被系統回收之前保存當前狀態?
當你的程序中某一個Activity A 在運行時中,主動或被動地運行另一個新的Activity B
這個時候A會執行
Java代碼
public 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");
}
就像官方的Notepad教程 裡的情況,你正在編輯某一個note,突然被中斷,那麼就把這個note的id記住,再起來的時候就可以根據這個id去把那個note取出來,程序就完整 一些。這也是看你的應用需不需要保存什麼,比如你的界面就是讀取一個列表,那就不需要特殊記住什麼,哦, 沒准你需要記住滾動條的位置...
27.如何退出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基類,處理這些共通問題。
28.請解釋下在單線程模型中Message、Handler、Message Queue、Looper之間的關系。
答:簡單的說,Handler獲取當前線程中的looper對象,looper用來從存放Message的MessageQueue中取出Message,再有Handler進行Message的分發和處理.
Message Queue(消息隊列):用來存放通過Handler發布的消息,通常附屬於某一個創建它的線程,可以通過Looper.myQueue()得到當前線程的消息隊列
Handler:可以發布或者處理一個消息或者操作一個Runnable,通過Handler發布消息,消息將只會發送到與它關聯的消息隊列,然也只能處理該消息隊列中的消息
Looper:是Handler和消息隊列之間通訊橋梁,程序組件首先通過Handler把消息傳遞給Looper,Looper把消息放入隊列。Looper也把消息隊列裡的消息廣播給所有的
Handler:Handler接受到消息後調用handleMessage進行處理
Message:消息的類型,在Handler類中的handleMessage方法中得到單個的消息進行處理
在單線程模型下,為了線程通信問題,Android設計了一個Message Queue(消息隊列), 線程間可以通過該Message Queue並結合Handler和Looper組件進行信息交換。下面將對它們進行分別介紹:
1. Message
Message消息,理解為線程間交流的信息,處理數據後台線程需要更新UI,則發送Message內含一些數據給UI線程。
2. Handler
Handler處理者,是Message的主要處理者,負責Message的發送,Message內容的執行處理。後台線程就是通過傳進來的 Handler對象引用來sendMessage(Message)。而使用Handler,需要implement 該類的 handleMessage(Message)方法,它是處理這些Message的操作內容,例如Update UI。通常需要子類化Handler來實現handleMessage方法。
3. Message Queue
Message Queue消息隊列,用來存放通過Handler發布的消息,按照先進先出執行。
每個message queue都會有一個對應的Handler。Handler會向messagequeue通過兩種方法發送消息:sendMessage或post。這兩種消息都會插在message queue隊尾並按先進先出執行。但通過這兩種方法發送的消息執行的方式略有不同:通過sendMessage發送的是一個message對象,會被 Handler的handleMessage()函數處理;而通過post方法發送的是一個runnable對象,則會自己執行。
4. Looper
Looper是每條線程裡的Message Queue的管家。Android沒有Global的MessageQueue,而Android會自動替主線程(UI線程)建立Message Queue,但在子線程裡並沒有建立Message Queue。所以調用Looper.getMainLooper()得到的主線程的Looper不為NULL,但調用Looper.myLooper()得到當前線程的Looper就有可能為NULL。對於子線程使用Looper,API Doc提供了正確的使用方法:這個Message機制的大概流程:
1. 在Looper.loop()方法運行開始後,循環地按照接收順序取出Message Queue裡面的非NULL的Message。
2. 一開始Message Queue裡面的Message都是NULL的。當Handler.sendMessage(Message)到Message Queue,該函數裡面設置了那個Message對象的target屬性是當前的Handler對象。隨後Looper取出了那個Message,則調用 該Message的target指向的Hander的dispatchMessage函數對Message進行處理。在dispatchMessage方法裡,如何處理Message則由用戶指定,三個判斷,優先級從高到低:
1) Message裡面的Callback,一個實現了Runnable接口的對象,其中run函數做處理工作;
2) Handler裡面的mCallback指向的一個實現了Callback接口的對象,由其handleMessage進行處理;
3) 處理消息Handler對象對應的類繼承並實現了其中handleMessage函數,通過這個實現的handleMessage函數處理消息。
由此可見,我們實現的handleMessage方法是優先級最低的!
3. Handler處理完該Message (updateUI) 後,Looper則設置該Message為NULL,以便回收!
在網上有很多文章講述主線程和其他子線程如何交互,傳送信息,最終誰來執行處理信息之類的,個人理解是最簡單的方法——判斷Handler對象裡面的Looper對象是屬於哪條線程的,則由該線程來執行!
1. 當Handler對象的構造函數的參數為空,則為當前所在線程的Looper;
2. Looper.getMainLooper()得到的是主線程的Looper對象,Looper.myLooper()得到的是當前線程的Looper對象。
29.你如何評價Android系統?優缺點。
答:Android平台手機 5大優勢:
一、開放性
在優勢方面,Android平台首先就是其開發性,開發的平台允許任何移動終端廠商加入到Android聯盟中來。顯著的開放性可以使其擁有更多的開發者,隨著用戶和應用的日益豐富,一個嶄新的平台也將很快走向成熟。開放性對於Android的發展而言,有利於積累人氣,這裡的人氣包括消費者和廠商,而對於消費者來講,隨大的受益正是豐富的軟件資源。開放的平台也會帶來更大競爭,如此一來,消費者將可以用更低的價位購得心儀的手機。
二、掙脫運營商的束縛
在過去很長的一段時間,特別是在歐美地區,手機應用往往受到運營商制約,使用什麼功能接入什麼網絡,幾乎都受到運營商的控制。從去年iPhone 上市 ,用戶可以更加方便地連接網絡,運營商的制約減少。隨著EDGE、HSDPA這些2G至3G移動網絡的逐步過渡和提升,手機隨意接入網絡已不是運營商口中的笑談,當你可以通過手機IM軟件方便地進行即時聊天時,再回想不久前天價的彩信和圖鈴下載業務,是不是像噩夢一樣?互聯網巨頭Google推動的Android終端天生就有網絡特色,將讓用戶離互聯網更近。
三、豐富的硬件選擇
這一點還是與Android平台的開放性相關,由於Android的開放性,眾多的廠商會推出千奇百怪,功能特色各具的多種產品。功能上的差異和特色,卻不會影響到數據同步、甚至軟件的兼容,好比你從諾基亞 Symbian風格手機 一下改用蘋果 iPhone ,同時還可將Symbian中優秀的軟件帶到iPhone上使用、聯系人等資料更是可以方便地轉移,是不是非常方便呢?
四、不受任何限制的開發商
Android平台提供給第三方開發商一個十分寬泛、自由的環境,不會受到各種條條框框的阻擾,可想而知,會有多少新穎別致的軟件會誕生。但也有其兩面性,血腥、暴力、情色方面的程序和游戲如可控制正是留給Android難題之一。
五、無縫結合的Google應用
如今叱詫互聯網的Google已經走過10年度歷史,從搜索巨人到全面的互聯網滲透,Google服務如地圖、郵件、搜索等已經成為連接用戶和互聯網的重要紐帶,而Android平台手機將無縫結合這些優秀的Google服務。
再說Android的5大不足:
一、安全和隱私
由於手機 與互聯網的緊密聯系,個人隱私很難得到保守。除了上網過程中經意或不經意留下的個人足跡,Google這個巨人也時時站在你的身後,洞穿一切,因此,互聯網的深入將會帶來新一輪的隱私危機。
二、首先開賣Android手機的不是最大運營商
眾所周知,T-Mobile在23日,於美國紐約發布 了Android首款手機G1。但是在北美市場,最大的兩家運營商乃AT&T和Verizon,而目前所知取得Android手機銷售權的僅有 T-Mobile和Sprint,其中T-Mobile的3G網絡相對於其他三家也要遜色不少,因此,用戶可以買賬購買G1,能否體驗到最佳的3G網絡服務則要另當別論了!
三、運營商仍然能夠影響到Android手機
在國內市場,不少用戶對購得移動定制機不滿,感覺所購的手機被人塗畫了廣告一般。這樣的情況在國外市場同樣出現。Android手機的另一發售運營商Sprint就將在其機型中內置其手機商店程序。
四、同類機型用戶減少
在不少手機論壇都會有針對某一型號的子論壇,對一款手機的使用心得交流,並分享軟件資源。而對於Android平台手機,由於廠商豐富,產品類型多樣,這樣使用同一款機型的用戶越來越少,缺少統一機型的程序強化。舉個稍顯不當的例子,現在山寨機泛濫,品種各異,就很少有專門針對某個型號山寨機的討論和群組,除了哪些功能異常搶眼、頗受追捧的機型以外。
五、過分依賴開發商缺少標准配置
在使用PC端的Windows Xp系統的時候,都會內置微軟Windows Media Player這樣一個播放器程序,用戶可以選擇更多樣的播放器,如Realplay或暴風影音等。但入手開始使用默認的程序同樣可以應付多樣的需要。在Android平台中,由於其開放性,軟件更多依賴第三方廠商,比如Android系統的SDK中就沒有內置音樂 播放器,全部依賴第三方開發,缺少了產品的統一性。
30.談談android數據存儲方式。
Android提供了5種方式存儲數據:
(1)使用SharedPreferences存儲數據;它是Android提供的用來存儲一些簡單配置信息的一種機制,采用了XML格式將數據存儲到設備中。只能在同一個包內使用,不能在不同的包之間使用。
(2)文件存儲數據;文件存儲方式是一種較常用的方法,在Android中讀取/寫入文件的方法,與Java中實現I/O的程序是完全一樣的,提供了openFileInput()和openFileOutput()方法來讀取設備上的文件。
(3)SQLite數據庫存儲數據;SQLite是Android所帶的一個標准的數據庫,它支持SQL語句,它是一個輕量級的嵌入式數據庫。
(4)使用ContentProvider存儲數據;主要用於應用程序之間進行數據交換,從而能夠讓其他的應用保存或讀取此Content Provider的各種數據類型。
(5)網絡存儲數據;通過網絡上提供給我們的存儲空間來上傳(存儲)和下載(獲取)我們存儲在網絡空間中的數據信息。
31. Android中Activity, Intent, Content Provider, Service各有什麼區別。
Activity: 活動,是最基本的android應用程序組件。一個活動就是一個用戶可以操作的可視化用戶界面,每一個活動都被實現為一個獨立的類,並且從活動基類繼承而來。
Intent: 意圖,描述應用想干什麼。最重要的部分是動作和動作對應的數據。
Content Provider:內容提供器,android應用程序能夠將它們的數據保存到文件、SQLite數據庫中,甚至是任何有效的設備中。當你想將你的應用數據和其他應用共享時,內容提供器就可以發揮作用了。
Service:服務,具有一段較長生命周期且沒有用戶界面的程序組件。
32.View, surfaceView, GLSurfaceView有什麼區別。
view是最基礎的,必須在UI主線程內更新畫面,速度較慢。
SurfaceView 是view的子類,類似使用雙緩機制,在新的線程中更新畫面所以刷新界面速度比view快
GLSurfaceView 是SurfaceView的子類,opengl 專用的
33.Manifest.xml文件中主要包括哪些信息?
manifest:根節點,描述了package中所有的內容。
uses-permission:請求你的package正常運作所需賦予的安全許可。
permission: 聲明了安全許可來限制哪些程序能你package中的組件和功能。
instrumentation:聲明了用來測試此package或其他package指令組件的代碼。
application:包含package中application級別組件聲明的根節點。
activity:Activity是用來與用戶交互的主要工具。
receiver:IntentReceiver能使的application獲得數據的改變或者發生的操作,即使它當前不在運行。
service:Service是能在後台運行任意時間的組件。
provider:ContentProvider是用來管理持久化數據並發布給其他應用程序使用的組件。
34.根據自己的理解描述下Android數字簽名。
(1)所有的應用程序都必須有數字證書,Android系統不會安裝一個沒有數字證書的應用程序
(2)Android程序包使用的數字證書可以是自簽名的,不需要一個權威的數字證書機構簽名認證
(3)如果要正式發布一個Android程序,必須使用一個合適的私鑰生成的數字證書來給程序簽名,而不能使用adt插件或者ant工具生成的調試證書來發布。
(4)數字證書都是有有效期的,Android只是在應用程序安裝的時候才會檢查證書的有效期。如果程序已經安裝在系統中,即使證書過期也不會影響程序的正常功能。
35. AIDL的全稱是什麼?如何工作?能處理哪些類型的數據?
AIDL全稱Android Interface Definition Language(Android接口描述語言)是一種借口描述語言; 編譯器可以通過aidl文件生成一段代碼,通過預先定義的接口達到兩個進程內部通信進程跨界對象訪問的目的.AIDL的IPC的機制和COM或CORBA類似, 是基於接口的,但它是輕量級的。它使用代理類在客戶端和實現層間傳遞值. 如果要使用AIDL, 需要完成2件事情: 1. 引入AIDL的相關類.; 2. 調用aidl產生的class.理論上, 參數可以傳遞基本數據類型和String, 還有就是Bundle的派生類, 不過在Eclipse中,目前的ADT不支持Bundle做為參數,
具體實現步驟如下:
1、創建AIDL文件, 在這個文件裡面定義接口, 該接口定義了可供客戶端訪問的方法和屬性。
2、編譯AIDL文件, 用Ant的話, 可能需要手動, 使用Eclipse plugin的話,可以根據adil文件自動生產java文件並編譯, 不需要人為介入.
3、在Java文件中, 實現AIDL中定義的接口. 編譯器會根據AIDL接口, 產生一個JAVA接口。這個接口有一個名為Stub的內部抽象類,它繼承擴展了接口並實現了遠程調用需要的幾個方法。接下來就需要自己去實現自定義的幾個接口了.
4、向客戶端提供接口ITaskBinder, 如果寫的是service,擴展該Service並重載onBind ()方法來返回一個實現上述接口的類的實例。
5、在服務器端回調客戶端的函數. 前提是當客戶端獲取的IBinder接口的時候,要去注冊回調函數, 只有這樣, 服務器端才知道該調用那些函數
AIDL語法很簡單,可以用來聲明一個帶一個或多個方法的接口,也可以傳遞參數和返回值。 由於遠程調用的需要, 這些參數和返回值並不是任何類型.下面是些AIDL支持的數據類型:
1. 不需要import聲明的簡單Java編程語言類型(int,boolean等)
2. String, CharSequence不需要特殊聲明
3. List, Map和Parcelables類型, 這些類型內所包含的數據成員也只能是簡單數據類型, String等其他比支持的類型.
(另外: 我沒嘗試Parcelables, 在Eclipse+ADT下編譯不過, 或許以後會有所支持).
實現接口時有幾個原則:
.拋出的異常不要返回給調用者. 跨進程拋異常處理是不可取的.
.IPC調用是同步的。如果你知道一個IPC服務需要超過幾毫秒的時間才能完成地話,你應該避免在Activity的主線程中調用。也就是IPC調用會掛起應用程序導致界面失去響應. 這種情況應該考慮單起一個線程來處理.
.不能在AIDL接口中聲明靜態屬性。
IPC的調用步驟:
1. 聲明一個接口類型的變量,該接口類型在.aidl文件中定義。
2. 實現ServiceConnection。
3. 調用ApplicationContext.bindService(),並在ServiceConnection實現中進行傳遞.
4. 在ServiceConnection.onServiceConnected()實現中,你會接收一個IBinder實例(被調用的Service). 調用
YourInterfaceName.Stub.asInterface((IBinder)service)將參數轉換為YourInterface類型。
5. 調用接口中定義的方法。你總要檢測到DeadObjectException異常,該異常在連接斷開時被拋出。它只會被遠程方法拋出。
6. 斷開連接,調用接口實例中的ApplicationContext.unbindService()
參考:http://buaadallas.blog.51cto.com/399160/372090
36.android:gravity與android:layout_gravity的區別
LinearLayout有兩個非常相似的屬性:android:gravity與android:layout_gravity。他們的區別在 於:android:gravity用於設置View組件的對齊方式,而android:layout_gravity用於設置Container組件的 對齊方式。
舉個例子,我們可以通過設置android:gravity="center"來讓EditText中的文字在EditText組件中居中顯示;同 時我們設置EditText的android:layout_gravity="right"來讓EditText組件在LinearLayout中居右 顯示。來實踐以下:
正如我們所看到的,在EditText中,其中的文字已經居中顯示了,而EditText組件自己也對齊到了LinearLayout的右側。
[html]
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<EditText
android:layout_width="wrap_content"
android:gravity="center"
android:layout_height="wrap_content"
android:text="one"
android:layout_gravity="right"/>
</LinearLayout>
38. 注冊廣播接收者兩種方式的區別,及優缺點
答:首先寫一個類要繼承BroadcastReceiver
第一種:在清單文件中聲明,添加
<receiveandroid:name=".IncomingSMSReceiver " >
<intent-filter>
<actionandroid:name="android.provider.Telephony.SMS_RECEIVED")
<intent-filter>
<receiver>
第二種使用代碼進行注冊如:
IntentFilterfilter = newIntentFilter("android.provider.Telephony.SMS_RECEIVED");
IncomingSMSReceiverreceiver = new IncomgSMSReceiver();
registerReceiver(receiver.filter);
兩種注冊類型的區別是:
1)第一種是常駐型(靜態注冊),也就是說當應用程序關閉後,如果有信息廣播來,程序也會被系統調用自動運行。
2)第二種不是常駐型廣播(動態注冊),也就是說廣播跟隨程序的生命周期。
注冊的方法有兩種,一種是靜態注冊,一種是動態注冊。
動態注冊優點:在 Android 的廣播機制中,動態注冊的優先級是要高於靜態注冊優先級的,因此在必要的情況下,我們是需要動態注冊廣播接收器的。
靜態注冊優點:動態注冊廣播接收器還有一個特點,就是當用來注冊的 Activity 關掉後,廣播也就失效了。同時反映了靜態注冊的一個優勢,就是無需擔憂廣播接收器是否被關閉,只要設備是開啟狀態,廣播接收器就是打開著的。
39.Dalvik基於JVM的改進
1.幾個class變為一個dex,constant pool,省內存
2.Zygote,copy-on-write shared,省內存,省cpu,省電
3.基於寄存器的bytecode,省指令,省cpu,省電
4.Trace-based JIT,省cpu,省電,省內存
40.android中有哪幾種解析xml的類,官方推薦哪種?以及它們的原理和區別.
Ø DOM解析
優點:
1.XML樹在內存中完整存儲,因此可以直接修改其數據和結構.
2.可以通過該解析器隨時訪問XML樹中的任何一個節點.
3.DOM解析器的API在使用上也相對比較簡單.
缺點:如果XML文檔體積比較大時,將文檔讀入內存是非常消耗系統資源的.
使用場景:DOM 是用與平台和語言無關的方式表示 XML 文檔的官方 W3C 標准.DOM 是以層次結構組織的節點的集合.這個層次結構允許開發人員在樹中尋找特定信息.分析該結構通常需要加載整個文檔和構造層次結構,然後才能進行任何工作.DOM是基於對象層次結構的.
Ø SAX解析
優點:
SAX 對內存的要求比較低,因為它讓開發人員自己來決定所要處理的標簽.特別是當開發人員只需要處理文檔中所包含的部分數據時,SAX 這種擴展能力得到了更好的體現.
缺點:
用SAX方式進行XML解析時,需要順序執行,所以很難訪問到同一文檔中的不同數據.此外,在基於該方式的解析編碼過程也相對復雜.
使用場景:
對於含有數據量十分巨大,而又不用對文檔的所有數據進行遍歷或者分析的時候,使用該方法十分有效.該方法不用將整個文檔讀入內存,而只需讀取到程序所需的文檔標簽處即可.
Ø Xmlpull解析
android SDK提供了xmlpull api,xmlpull和sax類似,是基於流(stream)操作文件,然後根據節點事件回調開發者編寫的處理程序.因為是基於流的處理,因此xmlpull和sax都比較節約內存資源,不會象dom那樣要把所有節點以對橡樹的形式展現在內存中.xmlpull比sax更簡明,而且不需要掃描完整個流.
41.Android系統中GC什麼情況下會出現內存洩露呢?
出現情況:
1. 數據庫的cursor沒有關閉
2.構造adapter時,沒有使用緩存contentview
衍生listview的優化問題-----減少創建view的對象,充分使用contentview,可以使用一靜態類來優化處理getview的過程
3.Bitmap對象不使用時采用recycle()釋放內存
4.activity中的對象的生命周期大於activity
調試方法: DDMS==> HEAPSZIE==>dataobject==>[Total Size]
42.談談對Android NDK的理解
NDK全稱:Native Development Kit。
1、NDK是一系列工具的集合。
* NDK提供了一系列的工具,幫助開發者快速開發C(或C++)的動態庫,並能自動將so和java應用一起打包成apk。這些工具對開發者的幫助是巨大的。
* NDK集成了交叉編譯器,並提供了相應的mk文件隔離CPU、平台、ABI等差異,開發人員只需要簡單修改mk文件(指出“哪些文件需要編譯”、“編譯特性要求”等),就可以創建出so。
* NDK可以自動地將so和Java應用一起打包,極大地減輕了開發人員的打包工作。
2、NDK提供了一份穩定、功能有限的API頭文件聲明。
Google明確聲明該API是穩定的,在後續所有版本中都穩定支持當前發布的API。從該版本的NDK中看出,這些API支持的功能非常有限,包含有:C標准庫(libc)、標准數學庫(libm)、壓縮庫(libz)、Log庫(liblog)。
在編程中經常會遇到數據庫的操作,而Android系統內置了SQLite,它是一款輕型數據庫,遵守事務ACID的關系型數據庫管理系統,它占用的資源非常低,能夠支持Windo
上一篇說到了通知欄Notification,提起通知欄,不得讓人想到Service以及BroadcastReceive,作為android的4大組建的2個重要成員,我們沒
RecyclerView 已經出來很久了,但是在項目中之前都使用的是ListView,最近新的項目上了都大量的使用了RecycleView.尤其是瀑布流的下拉刷新,網上吧
Android的UI和交互是很重要的一部分,直接影響到用戶對軟件的體驗。隨著項目經驗的積累,發現Android中動畫的運用越來越重要。本篇文章抽出了項目登錄界面中實現的第