- Android游戲開發技術實戰詳解
- 褚尚軍 張加春編著
- 190字
- 2018-12-30 05:33:17
3.3 五種數據存儲方式
Android操作系統提供的是一種公共文件系統,任何應用軟件都可以使用它來存儲和讀取文件,該文件也可以被其他的應用軟件所讀取(會有一些權限控制設定)。在Android中,所有的應用軟件數據(包括文件)為該應用軟件私有。然而,Android同樣也提供了一種標準方式供應用軟件將私有數據開放給其他應用軟件。具體來說,在Android中提供了如下5種數據存儲方式。
· 文件存儲
· SQLite數據庫方式
· 內容提供器(ContentProvider)
· SharedPreferences
· 網絡
3.3.1 最容易掌握的SharedPreferences存儲
SharedPreferences是Android提供的用來存儲一些簡單的配置信息的一種機制。SharedPre-ferences以鍵值對方式存儲,這樣開發人員可以很方便地實現讀取和存入。SharedPreferences經常用于存儲常見的歡迎語、登錄用戶名和密碼等信息。
1. SharedPreferences簡介
SharedPreferences是Android平臺上一個輕量級的存儲類,主要是保存一些常用的配置信息。通過使用SharedPreferences,可以保存Android平臺中的Long長整型、Int整型、String字符串型數據。在SharedPreferences中可以將數據設置為多種權限,最常用的是設置為全局共享訪問。最終會以XML方式來保存數據,在處理這些XML數據時,Dalvik會通過自帶底層的本地XML Parser進行解析,如XMLpull方式,這種方式會節約內存資源。
在兩個Activity之間,除了可以通過Intent來傳遞數據,還可以用SharedPreferences共享數據的方式實現數據傳遞。使用SharedPreferences的方法很簡單,例如,可以先在A中設置如下代碼:
Editor sharedata = getSharedPreferences("data", 0).edit(); sharedata.putString("item","getSharedPreferences"); sharedata.commit();
然后可以在B中編寫如下獲取代碼:
SharedPreferences sharedata = getSharedPreferences("data", 0); String data = sharedata.getString("item", null); Log.v("cola","data="+data);
最后,可以通過以下Java代碼將數據顯示出來:
<SPAN class=hilite1>SharedPreferences </SPAN> sharedata = getSharedPreferences("data", 0); String data = sharedata.getString("item", null); Log.v("cola","data="+data);
SharedPreferences的用法基本上和J2SE(java.util.prefs.Preferences)中的用法一樣,最終目的是用一種簡單的、透明的方式,來保存一些用戶個性化設置的字體、顏色等參數信息。一般的應用程序都會提供“設置”或者“首選項”之類的界面,那么這些設置就可以通過SharedPre-ferences來保存。程序員不需要知道信息到底以什么形式保存的,保存在什么地方。
2. 練習SharedPreferences
為了使讀者掌握SharedPreferences存儲的知識,接下來將通過一個具體實例講解使用SharedPreferences存儲數據的基本流程。
實例3-1 練習使用SharedPreferences來存儲數據(daima\3\SharedPreferences)。
step 1 編寫文件SharedPreferencesHelper.java,主要代碼如下所示。
public class SharedPreferencesHelper { SharedPreferences sp; SharedPreferences.Editor editor; Context context; public SharedPreferencesHelper(Context c,String name){ context = c; sp = context.getSharedPreferences(name, 0); editor = sp.edit(); } public void putValue(String key, String value){ editor = sp.edit(); editor.putString(key, value); editor.commit(); } public String getValue(String key){ return sp.getString(key, null); } }
step 2 編寫文件SharedPreferencesUsage.java,主要代碼如下所示。
public class SharedPreferencesUsage extends Activity { public final static String COLUMN_NAME ="name"; public final static String COLUMN_MOBILE ="mobile"; SharedPreferencesHelper sp; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //setContentView(R.layout.main); sp = new SharedPreferencesHelper(this, "contacts"); //1. to store some value sp.putValue(COLUMN_NAME, "那一劍的風情"); sp.putValue(COLUMN_MOBILE, "00000000000"); String name = sp.getValue(COLUMN_NAME); String mobile = sp.getValue(COLUMN_MOBILE); TextView tv = new TextView(this); tv.setText("NAME:"+ name + "\n" + "MOBILE:" + mobile); setContentView(tv); } }
執行后的效果如圖3-2所示。

圖3-2 執行效果
在上述實例代碼中,“NAME”和“MOBILE”兩者的數據是在SharedPreferences中存儲的。因為上面例子中的pack_name為:
package com.android.SharedPreferences;
所以存放數據的路徑為:
data/data/com.android.SharedPreferences/share_prefs/contacts.xml
其中文件contacts.xml中的內容如下所示。
<?xml version='1.0' encoding='utf-8' standalone='yes' ?> <map> <string name="mobile">11111111111</string> <string name="name">那一劍的風情</string> </map>
3.3.2 文件存儲
前面介紹的SharedPreferences存儲方式雖然非常方便,但是有一個致命的缺點——只適用于存儲比較簡單的數據。在Android中如果要存儲更多的數據,可供選擇的解決方案有幾種,如接下來將要講解的文件存儲方式就是一種很好的選擇。和傳統的在Java中實現I/O的程序類似,在Android中,可以使用方法openFileInput()和openFileOuput()來讀取設備上的文件,如下面的代碼所示。
String FILE_NAME = "tempfile.tmp"; //確定要操作文件的文件名 //初始化 FileOutputStream fos = openFileOutput(FILE_NAME, Context.MODE_PRIVATE); FileInputStream fis = openFileInput(FILE_NAME); //創建寫入流代碼解釋
在上述代碼中,方法openFileInput()和openFileOuput()只能讀取該應用目錄下的文件。如果要讀取非自身目錄下的文件,則會很不幸地拋出異常。如果在調用FileOutputStream時指定的文件不存在,Android會自動創建它,并且在默認情況下,寫入的時候會覆蓋原文件內容。如果想把新寫入的內容附加到原文件內容后,則可以指定其模式為Context.MODE_APPEND。在默認情況下,使用openFileOutput()方法創建的文件只能被調用其的應用程序使用,其他應用程序無法讀取這個文件。如果需要在不同的應用中共享數據,可以使用ContentProvider實現。
如果應用程序需要使用一些額外的資源文件,例如,用來測試音樂播放器是否可以正常工作的MP3文件,則可以將這些測試文件放在應用程序的“/res/raw/”目錄下,如文件mydatafile. mp3。此時就可以在應用程序中使用getResources獲取資源,然后用openRawResource()方法(不帶后綴的資源文件名)打開這個文件,具體實現代碼如下所示。
Resources myResources = getResources(); InputStream myFile = myResources.openRawResource(R.raw.myfilename);
除了方法openFileInput()和openFileOuput()可以讀寫文件外,在Android中還提供了方法deleteFile()和fileList()等來操作文件。
3.3.3 最常用的SQLite存儲
在Android中最常用的存儲方式是SQLite存儲,它是一個輕量級的嵌入式數據庫。SQLite是Android自帶的一個標準的數據庫,支持統一的SQL語句。
1. SQLite基礎
SQLite是一款輕型的數據庫,遵守ACID關聯式數據庫管理系統。SQLite是為嵌入式系統所設計的產品,而且目前已經在很多嵌入式產品中使用。SQLite的突出優點是占用非常少的資源。在嵌入式設備中,可能只需幾百KB的內存就夠了。SQLite能夠支持Windows、Linux、UNIX等主流的操作系統,同時能夠與很多程序語言相結合,如C#、PHP、Java等,并且還支持ODBC接口。另外,與MySQL、PostgreSQL這兩款開源數據庫管理系統相比,SQLite的處理速度更快。
注意:ACID是數據庫事務正確執行的4個基本要素的縮寫,具體包含:原子性(Atomicity)、一致性(Consistency)、隔離性(Isolation)、持久性(Durability)。一個支持事務(Transaction)的數據庫系統,必須具有這4種特性,否則在事務過程(Transaction processing)中無法保證數據的正確性,交易過程極可能達不到交易方的要求。
2. 使用SQLite
為了使讀者掌握SQLite存儲的基本知識,接下來將通過一個具體實例的實現過程,詳細介紹在Android中使用SQLite存儲的基本流程。
實例3-2 練習使用SQLite來存儲數據(daima\3\SQLite)。
編寫實現文件UserSQLite.java,具體實現流程如下所示。
step 1 定義類DatabaseHelper繼承于SQLiteOpenHelper,具體代碼如下所示。
private static class DatabaseHelper extends SQLiteOpenHelper { DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { String sql = "CREATE TABLE " + TABLE_NAME + " (" + TITLE + " text not null, " + BODY + " text not null " + ");"; Log.i("haiyang:createDB=", sql); db.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
在上述代碼中,首先分別重寫了方法onCreate()和onUpgrade(),然后在onCreate()方法中構造了一條SQL語句,并且通過db.execSQL(sql)執行了這條SQL語句。這條SQL語句的功能是生成了一張數據庫表。
類SQLiteOpenHelper是一個輔助類,目的是生成一個數據庫,并對數據庫的版本進行管理。當在程序當中調用這個類的方法getWritableDatabase()或者getReadableDatabase()時,若當時沒有數據,那么Android系統就會自動生成一個數據庫。
類SQLiteOpenHelper是一個抽象類,在Android項目中通常需要繼承這個類。在類SQLiteOpenHelper的實現中包含了3個方法,各方法的具體說明如下所示。
· 方法onCreate(SQLiteDatabase):在數據庫第一次生成的時候會調用這個方法,一般在這個方法中生成數據庫表。
· 方法onUpgrade(SQLiteDatabase, int, int):當數據庫需要升級的時候,Android系統會主動調用這個方法。一般在這個方法里刪除數據表,并建立新的數據表,當然是否還需要做其他的操作,完全取決于應用的需求。
· 方法onOpen(SQLiteDatabase):當打開數據庫時的回調方法,一般不會用到。
step 2 編寫按鈕處理事件,如果單擊“添加兩條數據”按鈕,若數據成功插入到數據庫中的diary表中,那么在界面的title區域就會顯示成功提示,如圖3-3所示。

圖3-3 插入成功
當單擊“添加兩條數據”按鈕后,執行監聽器里的onClick方法,并最終執行了程序中的insertItem()方法,具體代碼如下所示。
/*插入兩條數據*/ private void insertItem() { /*得到一個可寫的SQLite數據庫,如果這個數據庫還沒有建立*/ /*那么mOpenHelper輔助類負責建立這個數據庫。*/ /*如果數據庫已經建立,那么直接返回一個可寫的數據庫。*/ SQLiteDatabase db = mOpenHelper.getWritableDatabase(); String sql1 = "insert into " + TABLE_NAME + " (" + TITLE + ", " + BODY + ") values('AA', 'android好');"; String sql2 = "insert into " + TABLE_NAME + " (" + TITLE + ", " + BODY + ") values('BB', 'android好');"; try { Log.i("haiyang:sql1=", sql1); Log.i("haiyang:sql2=", sql2); db.execSQL(sql1); db.execSQL(sql2); setTitle("插入成功"); } catch (SQLException e) { setTitle("插入失敗"); } }
對上述代碼有如下幾點說明。
· sql1和sql2:是構造的標準的插入SQL語句,如果對SQL語句不是很熟悉,可以參考相關的書籍。鑒于本書的重點是Android,所以對SQL語句的知識不進行詳細介紹。
· Log.i():能夠將參數內容打印到日志當中,并且打印級別是Info級別。
· db.execSQL(sql1):執行SQL語句。
Android支持5種打印輸出級別,分別是Verbose、Debug、Info、Warning、Error,在程序中最常用的是Info級別,即將一些自己需要知道的信息打印出來,如圖3-4所示。

圖3-4 打印輸出級別
step 3 單擊“查詢數據庫”按鈕,在屏幕界面的title區域會顯示當前數據表中數據的條數。剛才插入了兩條,那么現在單擊后應顯示為兩條,如圖3-5所示。

圖3-5 查詢數據
單擊“查詢數據庫”按鈕后,程序會執行監聽器里的onClick方法,并最終執行了程序中的方法showItems(),具體代碼如下所示。
/*在屏幕的title區域顯示當前數據表當中的數據的條數*/ private void showItems() { /*得到一個可寫的數據庫*/ SQLiteDatabase db = mOpenHelper.getReadableDatabase(); String col[] = { TITLE, BODY }; Cursor cur = db.query(TABLE_NAME, col, null, null, null, null, null); /*通過getCount()方法,可以得到Cursor當中數據的個數。*/ Integer num = cur.getCount(); setTitle(Integer.toString(num) + " 條記錄"); } }
在上述代碼中,語句“Cursor cur = db.query(TABLE_NAME, col, null, null, null, null, null)”比較難以理解,此語句的功能是將查詢到的數據放到一個Cursor當中。在這個Cursor里邊封裝了數據表TABLE_NAME中的所有數據列。
方法query()的功能是查詢數據,包含如下7個參數。
· 第1個參數是數據庫中表的名字,比如在這個例子中,表的名字就是TABLE_NAME,也就是“diary”。
· 第2個字段是我們想要返回數據包含的列的信息。在這個例子中想要得到的列有title、body,把這兩個列的名字放到字符串數組里邊來。
· 第3個參數為selection,相當于SQL語句的where部分,如果想返回所有的數據,那么就直接置為null。
· 第4個參數為selectionArgs。在selection部分,你有可能用到“?”,那么selectionArgs定義的字符串會代替selection中的“?”。
· 第5個參數為groupBy。定義查詢出的數據是否分組,如果為null則說明不用分組。
· 第6個參數為having,相當于SQL語句當中的having部分。
· 第7個參數為orderBy,描述期望的返回值是否需要排序,如果設置為null則說明不需要排序。
注意:Cursor在Android中是一個非常有用的接口,通過Cursor可以對從數據庫查詢出來的結果集進行隨機的讀寫訪問。
step 4 單擊“刪除一條數據”按鈕后,如果成功刪除會在屏幕的標題(title)區域看到文字提示,如圖3-6所示。

圖3-6 刪除一條數據
現在再次單擊“查詢數據庫”按鈕,會發現數據庫中的記錄少了一條,如圖3-7所示。

圖3-7 查詢數據
當單擊“刪除一條數據”按鈕,程序會執行監聽器中的onClick方法,并最終執行程序中的deleteItem()方法,其實現代碼如下所示。
/*刪除其中的一條數據*/ private void deleteItem() { try { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); db.delete(TABLE_NAME, " title = 'AA'", null); setTitle("刪除了一條title為AA的記錄"); } catch (SQLException e) { } }
在上述代碼中,通過“db.delete(TABLE_NAME, " title = 'haiyang'", null)”語句刪除了一條title為“AA”的數據。如果有很多條title為“AA”的數據,則會全部刪除。方法delete()中各參數的具體說明如下。
· 第1個參數:表示數據庫表名,在這里是TABLE_NAME,也就是diary。
· 第2個參數:相當于SQL語句當中的where部分,描述了刪除的條件。
如果在第二個參數中有“?”,那么第三個參數中的字符串會依次替換在第二個參數中出現的“?”。
step 5 單擊“刪除數據表”按鈕后,可以刪除表diary,如圖3-8所示。

圖3-8 刪除表
單擊“刪除數據表”按鈕后會執行方法dropTable(),具體代碼如下所示。
/*刪除數據表*/ private void dropTable() { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); String sql = "drop table " + TABLE_NAME; try { db.execSQL(sql); setTitle("刪除成功:" + sql); } catch (SQLException e) { setTitle("刪除錯誤"); } }
在上述代碼中,構造了一個標準的刪除數據表的SQL語句,然后執行語句db.execSQL(sql)。
step 6 此時如果單擊其他按鈕,可能會出現運行異常,如果單擊“新建數據表”按鈕,執行效果如圖3-9所示。

圖3-9 新建表
此時再單擊“查詢數據庫”按鈕,可以查看里邊是否有數據,如圖3-10所示。

圖3-10 顯示0條記錄
單擊“新建數據表”按鈕后會執行方法CreateTable(),具體實現代碼如下所示。
/*重新建立數據表*/ private void CreateTable() { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); String sql = "CREATE TABLE " + TABLE_NAME + " (" + TITLE + " text not null, " + BODY + " text not null " + ");"; Log.i("haiyang:createDB=", sql); try { db.execSQL("DROP TABLE IF EXISTS diary"); db.execSQL(sql); setTitle("重建數據表成功"); } catch (SQLException e) { setTitle("重建數據表錯誤"); } }
在上述代碼中,sql變量表示的語句為標準的SQL語句,負責按要求建立一張新表;“db.execSQL("DROP TABLE IF EXISTS diary")”表示如果存在表diary則先將其刪除,因為在同一個數據庫中不能出現兩張同樣名字的表;“db.execSQL(sql)”語句用于執行SQL語句,這條SQL語句的功能是建立一個新表。
3.3.4 重要的ContentProvider存儲
在Android系統中,數據是私有的,當然這些數據包括文件數據和數據庫數據以及一些其他類型的數據。在Android中的兩個程序之間可以進行數據交換,此功能是通過ContentProvider實現的。
1. ContentProvider基礎
類ContentProvider實現了一組標準的方法接口,從而能夠讓其他的應用保存或讀取此ContentProvider的各種數據類型。在程序中可以通過實現ContentProvider抽象接口的方式將自己的數據顯示出來。從外界不會看到這個顯示數據在應用中是如何存儲的,無須關心是用數據庫存儲還是用文件存儲的,需要關注的是,外界可以通過這套標準的、統一的接口在程序中實現數據交互,既可以讀取程序里的數據,也可以刪除程序里的數據。
(1)ContentResolver接口
在類ContentProvider中,外部程序可以通過其ContentResolver接口訪問ContentProvider提供的數據。在Activity中,可以通過方法getContentResolver()獲取當前應用的ContentResolver實例。ContentResolver提供的接口需要和ContentProvider中需要實現的接口相對應。ContentResolver接口中的常用方法如下所示。
· query(Uri uri, String[] projection, String selection, String[] selectionArgs,String sortOrder):通過Uri進行查詢,返回一個Cursor;
· insert(Uri url, ContentValues values):將一組數據插入Uri指定的地方;
· update(Uri uri, ContentValues values, String where, String[] selectionArgs):更新Uri指定位置的數據;
· delete(Uri url, String where, String[] selectionArgs):刪除指定Uri并且符合一定條件的數據。
(2)ContentProvider和ContentResolver中的URI
在ContentProvider和ContentResolver中,通常有兩種使用URI的形式,一種是指定所有的數據,另一種是只指定某個ID的數據。例如:
content://contacts/people/ //此Uri指定的就是全部的聯系人數據 content://contacts/people/1 //此Uri指定的是ID為1的聯系人的數據
上面用到的URI一般由如下3部分組成。
· 第1部分是“content://”;
· 第2部分是要獲得數據的一個字符串片段;
· 第3部分是ID(如果沒有指定ID,那么表示返回全部)。
因為URI通常比較長,而且有時候容易出錯,并且難以理解。所以在Android中定義了一些輔助類和常量來代替這些長字符串的使用,如下所示。
Contacts.People.CONTENT_URI (聯系人的URI)
2. 使用ContentProvider
為了使讀者掌握ContentProvider存儲的用法,接下來將通過一個具體的實例,詳細講解在Android中使用ContentProvider存儲數據的基本流程。
實例3-3 練習使用ContentProvider來存儲數據(daima\3\ContentProvider)。
編寫主程序文件ActivityMain.java,具體代碼如下所示。
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Cursor c = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null); startManagingCursor(c); ListAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, c, new String[] { Phones.NAME, Phones.NUMBER }, new int[] { android.R.id.text1, android.R.id.text2 }); setListAdapter(adapter); }
對上述代碼的具體說明如下所示。
(1)方法getContentResolver():得到應用的ContentResolver實例。
(2)query(Phones.CONTENT_URI, null, null, null, null):ContentResolver中的方法,用于查詢所有聯系人,并返回一個Cursor。此方法中各參數的具體含義如下。
· 第1個參數為Uri,在此例中的Uri是聯系人的Uri;
· 第2個參數是一個字符串的數組,數組里的每一個字符串都是數據表中某一列的名字,它指定返回數據表中哪些列的值;
· 第3個參數相當于SQL語句的where部分,描述哪些值是需要的;
· 第4個參數是一個字符串數組,里邊的值依次代替在第3個參數中出現的“?”;
· 第5個參數指定了排序的方式。
(3)startManagingCursor(c)語句:讓系統來管理生成的Cursor。
(4)ListAdapter adapter = new SimpleCursorAdapter(this,Android.R.layout.simple_list_item_2, c, new String[] { Phones.NAME, Phones.NUMBER }, new int[] { Android.R.id.text1, Android.R.id.text2 }):用于生成一個Simple- CursorAdapter。
(5)setListAdapter(adapter):將ListView和SimpleCu-rsorAdapter進行綁定。
運行后的效果如圖3-11所示。

圖3-11 初始效果
另外,還可以添加幾條數據到聯系人列表中,具體流程如下所示。
step 1 單擊模擬器的鍵,在彈出的界面中單擊“Contacts”圖標,如圖3-12所示。

圖3-12 出現的界面
step 2 單擊“Create New contact”按鈕,如圖3-13所示。

圖3-13 單擊“Create New contact”按鈕
step 3 添加聯系人姓名和電話號碼信息,如圖3-14所示。

圖3-14 添加聯系人姓名和電話號碼
step 4 單擊“Done”按鈕完成添加聯系人信息,如圖3-15所示。

圖3-15 單擊“Save”按鈕保存
通過上述操作步驟后,即可添加一條聯系人的信息,如圖3-16所示。

圖3-16 添加后的數據
3.3.5 網絡存儲
除了本章前面介紹的存儲方法外,在Android中還可以通過網絡實現數據存儲工作。在Android的早期版本中,曾經支持用XMPP Service和Web Service進行遠程訪問。Android SDK 1.0以后不再支持XMPP Service,而且訪問Web Service的API全部變更。
網絡存儲在及時更新項目中比較常用,例如,可以在網絡中通過郵政編碼來查詢該地區的天氣預報。實現原理是以POST發送的方式發送請求到webservicex.net站點,訪問WebService.webservicex.net站點上提供查詢天氣預報的服務,具體信息請參考其WSDL文檔,其網址如下:
http://www.webservicex.net/WeatherForecast.asmx?WSDL
· 輸入:美國某個城市的郵政編碼。
· 輸出:該郵政編碼對應城市的天氣預報。
要想實現上述通過郵政編碼來查詢地區天氣預報的功能,可通過如下過程進行。
step 1 如果需要訪問外部網絡,則需要在文件AndroidManifest.xml中加入如下代碼,申請權限許可。
<!--權限 --> <uses-permission Android:name="Android.permission.INTERNET" />
step 2 以HttpPost的方式發送,SERVER_URL并不是指WSDL的URL,而是服務本身的URL,具體實現的代碼如下所示。
private static final String SERVER_URL = "http://www.webservicex.net/WeatherForecast. asmx/GetWeatherByZipCode"; //定義需要獲取的內容來源地址 HttpPost request = new HttpPost(SERVER_URL); //根據內容來源地址創建一個Http請求 //添加一個變量 List <NameValuePair> params = new ArrayList <NameValuePair>(); //設置一個華盛頓區號 params.add(new BasicNameValuePair("ZipCode", "200120")); //添加必須的參數 request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); //設置參數的編碼 try { HttpResponse httpResponse = new DefaultHttpClient().execute(request); //發送請求并獲取反饋 // 解析返回的內容 if(httpResponse.getStatusLine().getStatusCode() != 404) { String result = EntityUtils.toString(httpResponse.getEntity()); Log.d(LOG_TAG, result); } } catch (Exception e) { Log.e(LOG_TAG, e.getMessage()); }
通過上述代碼,使用Http從webservicex獲取ZipCode為“200120”的內容,其返回的內容如下所示。
<WeatherForecasts xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http: //www.w3.org/2001/XMLSchema-instance" xmlns="http://www.webservicex.net"> <Latitude>38.97571</Latitude> <Longitude>77.02825</Longitude> <AllocationFactor>0.024849</AllocationFactor> <FipsCode>11</FipsCode> <PlaceName>WASHINGTON</PlaceName> <StateCode>DC</StateCode> <Details> <WeatherData> <Day>Saturday, April 25, 2009</Day> <WeatherImage>http://forecast.weather.gov/images/wtf/sct.jpg</WeatherImage> <MaxTemperatureF>88</MaxTemperatureF> <MinTemperatureF>57</MinTemperatureF> <MaxTemperatureC>31</MaxTemperatureC> <MinTemperatureC>14</MinTemperatureC> </WeatherData> <WeatherData> <Day>Sunday, April 26, 2009</Day> <WeatherImage>http://forecast.weather.gov/images/wtf/few.jpg</WeatherImage> <MaxTemperatureF>89</MaxTemperatureF> <MinTemperatureF>60</MinTemperatureF> <MaxTemperatureC>32</MaxTemperatureC> <MinTemperatureC>16</MinTemperatureC> </WeatherData> … </Details> </WeatherForecasts>
上述實現過程演示了如何在Android中通過網絡獲取數據。要掌握這方面的內容,開發者需要熟悉java.net.*和Android.net.*這兩個包的內容,具體信息請讀者參閱相關文檔。