編輯:關於Android編程
41如何退出Activity?如何安全退出已調用多個Activity的Application
對於單一Activity的應用來說,退出很簡單,直接finish()即可。當然,也可以用killProcess()和System.exit()這樣的方法。
對於多個activity:
1)記錄打開的Activity:每打開一個Activity,就記錄下來。在需要退出時,關閉每一個Activity即可
2)發送特定廣播:在需要結束應用時,發送一個特定的廣播,每個Activity收到廣播後,關閉即可。
3)遞歸退出:在打開新的Activity時使用startActivityForResult,然後自己加標志,在onActivityResult中處理,遞歸關閉。為了編程方便,最好定義一個Activity基類,處理這些共通問題。
在2.1之前,可以使用ActivityManager的restartPackage方法。
它可以直接結束整個應用。在使用時需要權限android.permission.RESTART_PACKAGES。注意不要被它的名字迷惑。
可是,在2.2,這個方法失效了。在2.2添加了一個新的方法,killBackgroundProcesses(),需要權限android.permission.KILL_BACKGROUND_PROCESSES。可惜的是,它和2.2的restartPackage一樣,根本起不到應有的效果。
另外還有一個方法,就是系統自帶的應用程序管理裡,強制結束程序的方法,forceStopPackage()。它需要權限android.permission.FORCE_STOP_PACKAGES。並且需要添加android:sharedUserId="android.uid.system"屬性。同樣可惜的是,該方法是非公開的,他只能運行在系統進程,第三方程序無法調用。
因為需要在Android.mk中添加LOCAL_CERTIFICATE:=platform。
而Android.mk是用於在Android源碼下編譯程序用的。
從以上可以看出,在2.2,沒有辦法直接結束一個應用,而只能用自己的辦法間接辦到。
現提供幾個方法,供參考:
1)拋異常強制退出:
該方法通過拋異常,使程序ForceClose。
驗證可以,但是,需要解決的問題是,如何使程序結束掉,而不彈出ForceClose的窗口。
2)記錄打開的Activity:
每打開一個Activity,就記錄下來。在需要退出時,關閉每一個Activity即可。
3)發送特定廣播:
在需要結束應用時,發送一個特定的廣播,每個Activity收到廣播後,關閉即可。
4)遞歸退出
在打開新的Activity時使用startActivityForResult,然後自己加標志,在onActivityResult中處理,遞歸關閉。
除了第一個,都是想辦法把每一個Activity都結束掉,間接達到目的。但是這樣做同樣不完美。你會發現,如果自己的應用程序對每一個Activity都設置了nosensor,在兩個Activity結束的間隙,sensor可能有效了。但至少,我們的目的達到了,而且沒有影響用戶使用。為了編程方便,最好定義一個Activity基類,處理這些共通問題。
42.ListView切換奇偶行背景色
ListView中有時候有這樣的需求,當選中某項listView的時候,需求是改變listiew的背景顏色,如果用resource文件會有緩存問題,背景顯示錯誤,那麼直接用16進制表示顏色即可。如0xFF7AACC6. 注意表示透明度的需要寫上,否則顯示不正確
ListView源碼中兩個設置背景方法的不同點:
1.@RemotableViewMethod
2.public void setBackgroundResource(int resid) {
3.if (resid != 0 && resid == mBackgroundResource) {
4.return;
5.}
6.Drawable d= null;
7.if (resid != 0) {
8.d = mResources.getDrawable(resid);
9.}
10.setBackground(d);
11.mBackgroundResource = resid;
12.}
上面使用資源文件設置背景顏色
14.@RemotableViewMethod
15.public void setBackgroundColor(int color) {
16.if (mBackground instanceof ColorDrawable) {
17.((ColorDrawable) mBackground).setColor(color);
18.} else {
19.setBackground(new ColorDrawable(color));
20.}
21.}
上面是使用16進制數設置背景顏色,
42, 談談你對BroadCastRceiver的理解?
廣播接收者,android四大組件之一,也是唯一一個能動態注冊的組件。
1)廣播接收者是一個專注於接收廣播通知信息,並做出對應處理的組件。很多廣播是源自於系統──比如,通知時區改變、電池電量低、拍攝了一張照片或者用戶改變了語言選項。應用程序也可以進行廣播──比如說,通知其它應用程序一些數據下載完成並處於可用狀態。
2)應用程序可以擁有任意數量的廣播接收者以對所有它感興趣的通知信息予以響應。所有的接收器均繼承自BroadcastReceiver基類。
3)廣播接收者沒有用戶界面。然而,它們可以啟動一個activity來響應它們收到的信息,或者用NotificationManager來通知用戶。通知可以用很多種方式來吸引用戶的注意力──閃動背燈、震動、播放聲音等等。一般來說是在狀態欄上放一個持久的圖標,用戶可以打開它並獲取消息。
43, 廣播的生命周期?
廣播的生命周期是非常短的,當發送之後intent會到AndroidManifest.xml文件中找是不是有匹配的action,如果有就會調用Receiver ,然後獲得Receiver 對象,再執行onReceive方法,這時候Receiver對象就沒有用了,當我們再次點擊按鈕的時候就會重新獲得對象,這就是BroadcastReceiver的生命周期.
在BroadcastReceiver裡不能做一些比較耗時的操作,否側會彈出ANR(Application No
Response)的對話框.
如果需要完成一項比較耗時的工作,應該通過發送Intent給Service,由Service來完成.這裡不能使用子線程來解決,因為BroadcastReceiver的生命周期很短,子線程可能還沒有結束,BroadcastReceiver就先結束了.BroadcastReceiver一旦結束,此時BroadcastReceiver的所在進程很容易在系統需要內存時被優先殺死,因為它屬於空進程(沒有任何活動組件的進程).如果它的宿主進程被殺死,那麼正在工作的子線程也會被殺死.所以采用子線程來解決是不可靠的.
44. 注冊廣播有幾種方式,這些方式有什麼特點和區別?
兩種方式,首先這兩種方式都要先寫繼承自broadcastreceive的類
答: 第一種:在清單文件中聲明,添加
第二種使用代碼進行注冊如:
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
IncomingSMSReceiver receiver = new IncomgSMSReceiver();
registerReceiver(receiver,filter);
兩種注冊類型的區別是:
1)第二種不是常駐型廣播,也就是說廣播跟隨程序的生命周期。
2)第一種是常駐型,也就是說當應用程序關閉後,如果有信息廣播來,程序也會被系統調用自動運行。
45.廣播的發送方式有哪些
sendBroadcast(),sendOrderedBroadcast()和sendStickyBroadcast()三種
sendBroadcast()這個方法的廣播是能夠發送給所有廣播接收者,按照注冊的先後順序,如果你這個時候設置了廣播接收者的優先級,優先級如果恰好與注冊順序相同,則不會有任何問題,如果順序不一樣,會出leaked IntentReceiver 這樣的異常,並且在前面的廣播接收者不能調用abortBroadcast()方法將其終止,如果調用會出BroadcastReceiver trying to return result during a non-ordered broadcast的異常,當然,先接收到廣播的receiver可以修改廣播數據。
sendOrderedBroadcast()方法顧名思義就是priority的屬性能起作用,並且在隊列前面的receiver可以隨時終止廣播的發送。還有這個api能指定final的receiver,這個receiver是最後一個接收廣播時間的receiver,並且一定會接收到廣播事件,是不能被前面的receiver攔截的。實際做實驗的情況是這樣的,假設我有3個receiver依序排列,並且sendOrderedBroadcast()方法指定了一個finalReceiver,那麼intent傳遞給這4個Receiver的順序為Receiver1-->finalReceiver-->Receiver2-->finalReceiver-->Receiver3-->finalReceiver。這個特性可以用來統計系統中能監聽某種廣播的Receiver的數目。
sendStickyBroadcast()字面意思是發送粘性的廣播,使用這個api需要權限android.Manifest.permission.BROADCAST_STICKY,粘性廣播的特點是Intent會一直保留到廣播事件結束,而這種廣播也沒有所謂的10秒限制,10秒限制是指普通的廣播如果onReceive方法執行時間太長,超過10秒的時候系統會將這個廣播置為可以干掉的candidate,一旦系統資源不夠的時候,就會干掉這個廣播而讓它不執行。
注: (下面是廣播接收者的生命周期以及一些細節部分:
1.廣播接收者的生命周期是非常短暫的,在接收到廣播的時候創建,onReceive()方法結束之後銷毀
2.廣播接收者中不要做一些耗時的工作,否則會彈出Application No Response錯誤對話框
3.最好也不要在廣播接收者中創建子線程做耗時的工作,因為廣播接收者被銷毀後進程就成為了空進程,很容易被系統殺掉
4.耗時的較長的工作最好放在服務中完成)
46, 廣播分幾種?他們有什麼區別?
廣播被分為兩種不同的類型:“普通廣播(Normal broadcasts)”和“有序廣播(Ordered broadcasts)”。普通廣播是完全異步的,可以在同一時刻(邏輯上)被所有接收者接收到,消息傳遞的效率比較高,但缺點是:接收者不能將處理結果傳遞給下一個接收者,並且無法終止廣播Intent的傳播。
然而有序廣播是按照接收者聲明的優先級別,被接收者依次接收廣播。如:A的級別高於B,B的級別高於C,那麼,廣播先傳給A,再傳給B,最後傳給C 。優先級別聲明在 intent-filter 元素的 android:priority 屬性中,數越大優先級別越高,取值范圍:-1000到1000,優先級別也可以調用IntentFilter對象的setPriority()進行設置 。有序廣播的接收者可以終止廣播Intent的傳播,廣播Intent的傳播一旦終止,後面的接收者就無法接收到廣播。
另外,有序廣播的接收者可以將數據傳遞給下一個接收者,如:A得到廣播後,可以往它的結果對象中存入數據,當廣播傳給B時,B可以從A的結果對象中得到A存入的數據。
47、如何使用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,String strPassword){ SharedPreferences user = getSharedPreferences(“user_info”,0); uer.edit(); user.putString(“NAME”, strName); user.putString(“PASSWORD” ,strPassword); user.commit(); } 數據讀取與寫入的方法都非常簡單,只是在寫入的時候有些區別:先調用edit()使其處於編輯狀態,然後才能修改數據,最後使用commit()提交修改的數據。實際上SharedPreferences是采用了XML格式將數據存儲到設備中,在DDMS中的File Explorer中的/data/data/
1.內部存儲:
注意內部存儲不是內存。內部存儲位於系統中很特殊的一個位置,如果你想將文件存儲於內部存儲中,那麼文件默認只能被你的應用訪問到,且一個應用所創建的所有文件都在和應用包名相同的目錄下。也就是說應用創建於內部存儲的文件,與這個應用是關聯起來的。當一個應用卸載之後,內部存儲中的這些文件也被刪除。從技術上來講如果你在創建內部存儲文件的時候將文件屬性設置成可讀,其他app能夠訪問自己應用的數據,前提是他知道你這個應用的包名,如果一個文件的屬性是私有(private),那麼即使知道包名其他應用也無法訪問。內部存儲空間十分有限,因而顯得可貴,另外,它也是系統本身和系統應用程序主要的數據存儲所在地,一旦內部存儲空間耗盡,手機也就無法使用了。所以對於內部存儲空間,我們要盡量避免使用。Shared Preferences和SQLite數據庫都是存儲在內部存儲空間上的。內部存儲一般用Context來獲取和操作。
getFilesDir()獲取你app的內部存儲空間,相當於你的應用在內部存儲上的根目錄。
如果是要創建一個文件,如下
1File file = newFile(context.getFilesDir(), filename);
2.外部存儲
最容易混淆的是外部存儲,如果說pc上也要區分出外部存儲和內部存儲的話,那麼自帶的硬盤算是內部存儲,U盤或者移動硬盤算是外部存儲,因此我們很容易帶著這樣的理解去看待安卓手機,認為機身固有存儲是內部存儲,而擴展的T卡是外部存儲。比如我們任務16GB版本的Nexus 4有16G的內部存儲,普通消費者可以這樣理解,但是安卓的編程中不能,這16GB仍然是外部存儲。
所有的安卓設備都有外部存儲和內部存儲,這兩個名稱來源於安卓的早期設備,那個時候的設備內部存儲確實是固定的,而外部存儲確實是可以像U盤一樣移動的。但是在後來的設備中,很多中高端機器都將自己的機身存儲擴展到了8G以上,他們將存儲在概念上分成了"內部internal" 和"外部external" 兩部分,但其實都在手機內部。所以不管安卓手機是否有可移動的sdcard,他們總是有外部存儲和內部存儲。最關鍵的是,我們都是通過相同的api來訪問可移動的sdcard或者手機自帶的存儲(外部存儲)。
外部存儲雖然概念上有點復雜,但也很好區分,你把手機連接電腦,能被電腦識別的部分就一定是外部存儲。
內部:寫入到/data/data/com.xxx.xxx/files目錄下,com.xxx.xxx為應用程序包名外部:/mnt/sdcard/Android/data/包名/filescom.xxx.xxx為應用程序包名
1、sqlite的用處及用法, 哪裡用過?以及怎麼提高sqlite的效率 輕量級嵌入型數據庫,經常用於嵌入型操作系統,如android中,可以用戶對對象性數據的描述並存儲。事務。一致性、原子性、隔離性、持續性 2、如何建一個“aaa.db”數據庫,如何建一個user表;寫出增刪改查語句 ①.建立一個類繼承SQLiteHelper,重寫SQLiteHelp方法,創建庫: public SQLiteHelp(Context context) { super(context, "user.db", null, 1); // TODO Auto-generated constructor stub } ②.重寫onCreate方法 @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub db.execSQL("create table user(id integer primary key autoincrement,name varchar(20),age varchar(20))"); } ③增刪改查:。。。 3、請介紹下ContentProvider是如何實現數據共享的。 一個程序可以通過實現一個Content provider的抽象接口將自己的數據完全暴露出去,而且Content providers是以類似數據庫中表的方式將數據暴露。Content providers存儲和檢索數據,通過它可以讓所有的應用程序訪問到,這也是應用程序之間唯一共享數據的方法。 要想使應用程序的數據公開化,可通過2種方法:創建一個屬於你自己的Content provider或者將你的數據添加到一個已經存在的Content provider中,前提是有相同數據類型並且有寫入Content provider的權限。 如何通過一套標准及統一的接口獲取其他應用程序暴露的數據 Android提供了ContentResolver,外界的程序可以通過ContentResolver接口訪問ContentProvider提供的數據。 4. 如何將SQLite數據庫(dictionary.db文件)與apk文件一起發布 解答:可以將dictionary.db文件復制到Eclipse Android工程中的res aw目錄中。所有在res raw目錄中的文件不會被壓縮,這樣可以直接提取該目錄中的文件。可以將dictionary.db文件復制到res aw目錄中 5. 如何將打開res raw目錄中的數據庫文件 解答:在Android中不能直接打開res raw目錄中的數據庫文件,而需要在程序第一次啟動時將該文件復制到手機內存或SD卡的某個目錄中,然後再打開該數據庫文件。 復制的基本方法是使用getResources().openRawResource方法獲得res raw目錄中資源的 InputStream對象,然後將該InputStream對象中的數據寫入其他的目錄中相應文件中。在Android SDK中可以使用SQLiteDatabase.openOrCreateDatabase方法來打開任意目錄中的SQLite數據庫文件。 1. 說說HttpClient的通信過程 1)生成請求對象(HttpGet get,HttpPost post) 2)生成客戶端對象 HttpClient client 3)執行請求接收相應 HttpResponse response = client.execute(post) HttpEntity entity = response.getEntity() 2.(Json(有數據類型)與xml(沒有)的區別?) 移動互聯數據交互格式有XML和JSON 1)JSON和XML的數據可讀性基本相同 2)JSON和XML同樣擁有豐富的解析手段 3)JSON相對於XML來講,數據的體積小 4)JSON與JavaScript的交互更加方便 5)JSON對數據的描述性比XML較差 3. XML解析有哪幾種?各自優缺點,官方推薦使用哪種 基本的解析方式有三種: DOM,SAX,Pull 1)dom解析解析器讀入整個文檔,然後構建一個駐留內存的樹結構,然後代碼就可以使用 DOM 接口來操作這個樹結構的優點是對文檔增刪改查比較方便,缺點占用內存比較大。 2)sax解析基於事件驅動型,優點占用內存少,解析速度快,缺點是只適合做文檔的讀取,不適合做文檔的增刪改查。 3)pull解析同樣基於事件驅動型,android 官方API提供,可隨時終止,調用next() 方法提取它們(主動提取事件) 4. sax解析代碼 首先SAXParserFactory來創建一個SAXParserFactory實例 SAXParserFactory factory = SAXParserFactory.newInstance(); 根據SAXParserFactory實例來創建SAXParser SAXParser產生SAXReader XMLReader reader = factory.newSAXParser().getXMLReader(); XMLReader 加載XML,然後解析XML,在解析的過程中觸發相對於接口中的事件處理程序 5. Android緩存機制(sharePrefrence、Sd卡、數據庫SQLite) 答: 客戶端緩存機制是android應用開發中非常重要的一項工作,使用緩存機制不僅僅可以為用戶節省3G流量,同時在用戶體驗方面也是非常好的選擇,比如有些新聞客戶端支持離線模式,也是通過緩存機制實現的.緩存機制分為兩部分,一部分是文字緩存,另一部分是多媒體文件緩存. 文字緩存有兩種實現: 1)可以將與服務器交互得到的json數據或者xml數據存入sd卡中,並在數據庫添加該數據的記錄.添加數據庫記錄時,提供兩個關鍵字段,一個是請求的URL,另一個則是本地保存後的文件地址,每次加載數據之前都會根據URL在數據庫中檢索 2)將JSON數據解析後裝入List 多媒體文件緩存:主要指圖片緩存 圖片的緩存可以根據當前日期,時間為名字緩存到SD卡中的指定圖片緩存目錄,同時數據庫中做相應記錄,記錄辦法可以采用兩個關鍵字段控制,一個字段是該圖片的URL地址,另一個字段是該圖片的本機地址.取圖片時根據URL在數據中檢索,如果沒有則連接服務器下載,下載之後再服務器中作出相應記錄 緩存文件刪除策略: 1) 每一個模塊在每次客戶端自動或者用戶手動更新的時候刪除相應模塊的緩存文件,並重新下載新的緩存文件. 2)在設置界面中提供刪除緩存的功能,點擊後刪除本機所有緩存.
主要講解Android Studio中生成aar文件以及本地方式使用aar文件的方法。 在Android Studio中對一個自己庫進行生成操作時將會同時生成*.jar與
1.簡單說明淘寶詳情頁就不用我一一介紹了,昨天逛淘寶看到這個效果時,讓我想起了去年剛學習Android只會使用現成的時候,當時在網上找了一個這種效果的使用了,並不懂怎麼實
1、初始化一個消息請求隊列以及網絡請求工具類對象/** * Created by androidlongs on 16/7/1. * 網絡請求訪問框架
SwipeRefreshLayout感覺是Google在吸收了PullToRefresh-ListView,ActionBarPullToRefresh之後實現的goog