一.四大組件:java
Android四大組件分別爲activity、service、content provider、broadcast receiver。android
1、Android四大組件詳解git
一、activityweb
(1)一個Activity一般就是一個單獨的屏幕(窗口)。sql
(2)Activity之間經過Intent進行通訊。數據庫
(3)android應用中每個Activity都必需要在AndroidManifest.xml配置文件中聲明,不然系統將不識別也不執行該Activity。數組
二、service性能優化
(1)service用於在後臺完成用戶指定的操做。service分爲兩種:網絡
(a)started(啓動):當應用程序組件(如activity)調用startService()方法啓動服務時,服務處於started狀態。
(b)bound(綁定):當應用程序組件調用bindService()方法綁定到服務時,服務處於bound狀態。
(2)startService()與bindService()區別:
(a)started service(啓動服務)是由其餘組件調用startService()方法啓動的,這致使服務的onStartCommand()方法被調用。當服務是started狀態時,其生命週期與啓動它的組件無關,而且能夠在後臺無限期運行,即便啓動服務的組件已經被銷燬。所以,服務須要在完成任務後調用stopSelf()方法中止,或者由其餘組件調用stopService()方法中止。
(b)使用bindService()方法啓用服務,調用者與服務綁定在了一塊兒,調用者一旦退出,服務也就終止,大有「不求同時生,必須同時死」的特色。
(3)開發人員須要在應用程序配置文件中聲明所有的service,使用<service></service>標籤。
(4)Service一般位於後臺運行,它通常不須要與用戶交互,所以Service組件沒有圖形用戶界面。Service組件須要繼承Service基類。Service組件一般用於爲其餘組件提供後臺服務或監控其餘組件的運行狀態。
三、content provider
(1)android平臺提供了Content Provider使一個應用程序的指定數據集提供給其餘應用程序。其餘應用能夠經過ContentResolver類從該內容提供者中獲取或存入數據。
(2)只有須要在多個應用程序間共享數據是才須要內容提供者。例如,通信錄數據被多個應用程序使用,且必須存儲在一個內容提供者中。它的好處是統一數據訪問方式。
(3)ContentProvider實現數據共享。ContentProvider用於保存和獲取數據,並使其對全部應用程序可見。這是不一樣應用程序間共享數據的惟一方式,由於android沒有提供全部應用共同訪問的公共存儲區。
(4)開發人員不會直接使用ContentProvider類的對象,大多數是經過ContentResolver對象實現對ContentProvider的操做。
(5)ContentProvider使用URI來惟一標識其數據集,這裏的URI以content://做爲前綴,表示該數據由ContentProvider來管理。
四、broadcast receiver
(1)你的應用可使用它對外部事件進行過濾,只對感興趣的外部事件(如當電話呼入時,或者數據網絡可用時)進行接收並作出響應。廣播接收器沒有用戶界面。然而,它們能夠啓動一個activity或serice來響應它們收到的信息,或者用NotificationManager來通知用戶。通知能夠用不少種方式來吸引用戶的注意力,例如閃動背燈、震動、播放聲音等。通常來講是在狀態欄上放一個持久的圖標,用戶能夠打開它並獲取消息。
(2)廣播接收者的註冊有兩種方法,分別是程序動態註冊和AndroidManifest文件中進行靜態註冊。
(3)動態註冊廣播接收器特色是當用來註冊的Activity關掉後,廣播也就失效了。靜態註冊無需擔心廣播接收器是否被關閉,只要設備是開啓狀態,廣播接收器也是打開着的。也就是說哪怕app自己未啓動,該app訂閱的廣播在觸發時也會對它起做用。
2、android四大組件總結:
(1)4大組件的註冊
4大基本組件都須要註冊才能使用,每一個Activity、service、Content Provider都須要在AndroidManifest文件中進行配置。AndroidManifest文件中未進行聲明的activity、服務以及內容提供者將不爲系統所見,從而也就不可用。而broadcast receiver廣播接收者的註冊分靜態註冊(在AndroidManifest文件中進行配置)和經過代碼動態建立並以調用Context.registerReceiver()的方式註冊至系統。須要注意的是在AndroidManifest文件中進行配置的廣播接收者會隨系統的啓動而一直處於活躍狀態,只要接收到感興趣的廣播就會觸發(即便程序未運行)。
(2)4大組件的激活
內容提供者的激活:當接收到ContentResolver發出的請求後,內容提供者被激活。而其它三種組件activity、服務和廣播接收器被一種叫作intent的異步消息所激活。
(3)4大組件的關閉
內容提供者僅在響應ContentResolver提出請求的時候激活。而一個廣播接收器僅在響應廣播信息的時候激活。因此,沒有必要去顯式的關閉這些組件。Activity關閉:能夠經過調用它的finish()方法來關閉一個activity。服務關閉:對於經過startService()方法啓動的服務要調用Context.stopService()方法關閉服務,使用bindService()方法啓動的服務要調用Contex.unbindService()方法關閉服務。
(4)android中的任務(activity棧)
(a)任務其實就是activity的棧,它由一個或多個Activity組成,共同完成一個完整的用戶體驗。棧底的是啓動整個任務的Activity,棧頂的是當前運行的用戶能夠交互的Activity,當一個activity啓動另一個的時候,新的activity就被壓入棧,併成爲當前運行的activity。而前一個activity仍保持在棧之中。當用戶按下BACK鍵的時候,當前activity出棧,而前一個恢復爲當前運行的activity。棧中保存的實際上是對象,棧中的Activity永遠不會重排,只會壓入或彈出。
(b)任務中的全部activity是做爲一個總體進行移動的。整個的任務(即activity棧)能夠移到前臺,或退至後臺。
(c)Android系統是一個多任務(Multi-Task)的操做系統,能夠在用手機聽音樂的同時,也執行其餘多個程序。每多執行一個應用程序,就會多耗費一些系統內存,當同時執行的程序過多,或是關閉的程序沒有正確釋放掉內存,系統就會以爲愈來愈慢,甚至不穩定。爲了解決這個問題,Android引入了一個新的機制,即生命週期(Life Cycle)。
二.六大布局:
Android六大界面佈局方式:
聲明Android程序佈局有兩種方式:
1) 使用XML文件描述界面佈局;
2) 在Java代碼中經過調用方法進行控制。
咱們既可使用任何一種聲明界面佈局的方式,也能夠同時使用兩種方式。
使用XML文件聲明有如下3個特色:
- 1) 將程序的表現層和控制層分離;
- 2) 在後期修改用戶界面時,無須更改程序的源程序;
- 3) 可經過WYSIWYG可視化工具直接看到所設計的用戶界面,有利於加快界面設計的過程。
建議儘可能採用XML文件聲明界面元素佈局。在程序運行時動態添加界面佈局會大大下降應用響應速度,但依然能夠在必要時動態改變屏幕內容。
六大界面佈局方式包括: 線性佈局(LinearLayout)、框架佈局(FrameLayout)、表格佈局(TableLayout)、相對佈局(RelativeLayout)、絕對佈局(AbsoluteLayout)和網格佈局(GridLayout) 。
1. LinearLayout線性佈局
LinearLayout容器中的組件一個挨一個排列,經過控制android:orientation屬性,可控制各組件是橫向排列仍是縱向排列。
LinearLayout的經常使用XML屬性及相關方法
XML屬性 |
相關方法 |
說明 |
android:gravity |
setGravity(int) |
設置佈局管理器內組件的對齊方式 |
android:orientation |
setOrientation(int) |
設置佈局管理器內組件的排列方式,能夠設置爲horizontal、vertical兩個值之一 |
其中,gravity屬性支持top, left, right, center_vertical, fill_vertical, center_horizontal, fill_horizontal, center, fill, clip_vertical, clip_horizontal。也能夠同時指定多種對齊方式的組合。
LinearLayout子元素支持的經常使用XML屬性及方法
XML屬性 |
說明 |
android:layout_gravity |
指定該子元素在LinearLayout中的對齊方式 |
android:layout_weight |
指定子元素在LinearLayout中所佔的權重 |
2. TableLayout表格佈局
TableLayout繼承自Linearout,本質上仍然是線性佈局管理器。表格佈局採用行、列的形式來管理UI組件,並不須要明確地聲明包含多少行、多少列,而是經過添加TableRow、其餘組件來控制表格的行數和列數。
每向TableLayout中添加一個TableRow就表明一行;
每向TableRow中添加一個一個子組件就表示一列;
若是直接向TableLayout添加組件,那麼該組件將直接佔用一行;
在表格佈局中,能夠爲單元格設置以下三種行爲方式:
- Shrinkable:該列的全部單元格的寬度能夠被收縮,以保證該表格能適應父容器的寬度;
- Strentchable:該列全部單元格的寬度能夠被拉伸,以保證組件能徹底填滿表格空餘空間;
- Collapsed:若是該列被設置爲Collapsed,那麼該列的全部單元格會被隱藏;
TableLayout的經常使用XML屬性及方法
XML屬性 |
相關方法 |
說明 |
android:collapseColumns |
setColumns(int, boolean) |
設置須要被隱藏的列的序號,多個序號間用逗號分隔 |
android:shrinkColumns |
setShrinkAllColumns(boolean) |
設置須要被收縮的列的序號 |
android:stretchColumns |
setStretchAllColumns(boolean) |
設置容許被拉伸的列的序號 |
3. FrameLayout幀佈局
FrameLayout直接繼承自ViewGroup組件。幀佈局爲每一個加入其中的組件建立一個空白的區域(稱爲一幀),每一個子組件佔據一幀,這些幀會根據gravity屬性執行自動對齊。
FrameLayout的經常使用XM了屬性及方法
XML屬性 |
相關方法 |
說明 |
android:foreground |
setForeground(Drawable) |
設置該幀佈局容器的前景圖像 |
android:foregroundGravity |
setForeGroundGraity(int) |
定義繪製前景圖像的gravity屬性 |
4. RelativeLayout相對佈局
RelativeLayout的XML屬性及相關方法說明
XML屬性 |
相關方法 |
說明 |
android:gravity |
setGravity(int) |
|
android:ignoreGravity |
setIgnoreGravity(int) |
設置哪一個組件不受gravity屬性的影響 |
爲了控制該佈局容器的各子組件的佈局分佈,RelativeLayout提供了一個內部類:RelativeLayout.LayoutParams。
RelativeLayout.LayoutParams裏只能設爲boolean的XML屬性
XML屬性 |
說明 |
android:layout_centerHorizontal |
設置該子組件是否位於佈局容器的水平居中 |
android:layout_centerVertical |
|
android:layout_centerParent |
|
android:layout_alignParentBottom |
|
android:layout_alignParentLeft |
|
android:layout_alignParentRight |
|
android:layout_alignParentTop |
RelativeLayout.LayoutParams裏屬性值爲其餘UI組件ID的XML屬性
XML屬性 |
說明 |
android:layout_toRightOf |
控制該子組件位於給出ID組件的右側 |
android:layout_toLeftOf |
|
android:layout_above |
|
android:layout_below |
|
android:layout_alignTop |
|
android:layout_alignBottom |
|
android:layout_alignRight |
|
android:layout_alignLeft |
5. Android 4.0新增的網格佈局GridLayout
GridLayout是Android4.0增長的網格佈局控件,與以前的TableLayout有些類似,它把整個容器劃分爲rows × columns個網格,每一個網格能夠放置一個組件。性能及功能都要比tablelayout好,好比GridLayout佈局中的單元格能夠跨越多行,而tablelayout則不行,此外,其渲染速度也比tablelayout要快。
GridLayout提供了setRowCount(int)和setColumnCount(int)方法來控制該網格的行和列的數量。
GridLayout經常使用的XML屬性和方法說明
XML屬性 |
相關方法 |
說明 |
android:alignmentMode |
setAlignmentMode(int) |
設置該佈局管理器採用的對齊模式 |
android:columnCount |
setColumnCount(int) |
設置該網格的列數量 |
android:columnOrderPreserved |
setColumnOrderPreserved(boolean) |
設置該網格容器是否保留序列號 |
android:roeCount |
setRowCount(int) |
設置該網格的行數量 |
android:rowOrderPreserved |
setRowOrderPreserved(boolean) |
設置該網格容器是否保留行序號 |
android:useDefaultMargins |
setUseDefaultMargins(boolean) |
設置該佈局管理器是否使用默認的頁邊距 |
爲了控制GridLayout佈局容器中各子組件的佈局分佈,GridLayout提供了一個內部類:GridLayout.LayoutParams,來控制Gridlayout佈局容器中子組件的佈局分佈。
GridLayout.LayoutParams經常使用的XML屬性和方法說明
XML屬性 |
說明 |
android:layout_column |
設置該組件在GridLayout的第幾列 |
android:layout_columnSpan |
設置該子組件在GridLayout橫向上跨幾列 |
android:layout_gravity |
設置該子組件採用何種方式佔據該網格的空間 |
android:layout_row |
設置該子組件在GridLayout的第幾行 |
android:layout_rowSpan |
設置該子組件在GridLayout縱向上跨幾行 |
5. AbsoluteLayout絕對佈局
即Android不提供任何佈局控制,而是由開發人員本身經過X座標、Y座標來控制組件的位置。每一個組件均可指定以下兩個XML屬性:
絕對佈局已通過時,不該使用或少使用。
界面佈局類型的選擇和性能優化
首先得明確,界面佈局類型的嵌套越多越深越複雜,會使佈局實例化變慢,使Activity的展開時間延長。建議儘可能減小布局嵌套,儘可能減小建立View對象的數量。
1 . 減小布局層次,可考慮用RelativeLayout來代替LinearLayout。經過Relative的相對其餘元素的位置來佈局,可減小塊狀嵌套;
2 . 另外一種減小布局層次的技巧是使用 <merge />
標籤來合併佈局;
3 . 重用佈局。Android支持在XML中使用 <include />
標籤, <include />
經過指定android:layout屬性來指定要包含的另外一個XML佈局。
如:
<include android:id="@+id/id1" android:layout="@layout/mylayout">
<include android:id="@+id/id2" android:layout="@layout/mylayout">
<include android:id="@+id/id3" android:layout="@layout/mylayout">
三.五大存儲:
在Android中,可供選擇的存儲方式有SharedPreferences、文件存儲、SQLite數據庫方式、內容提供器(Content provider)和網絡。
一.SharedPreferences方式
Android提供用來存儲一些簡單的配置信息的一種機制,例如,一些默認歡迎語、登陸的用戶名和密碼等。其以鍵值對的方式存儲,
使得咱們能夠很方便的讀取和存入.
1)程序要實現的功能:
咱們在Name文本框中輸入wangwu,在Password文本框中輸入123456,而後退出這個應用。咱們在應用程序列表中找到這個應用,從新啓動,能夠看到其使用了前面輸入的Name和Password
2)實現的代碼
佈局
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="SharedPreferences demo"
- />
-
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="name"
- >
- </TextView>
-
- <EditText
- android:id="@+id/name"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text=""
- >
- </EditText>
-
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="password"
- >
- </TextView>
-
- <EditText
- android:id="@+id/password"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:password="true"
- android:text=""
- >
- </EditText>
- </LinearLayout>
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="SharedPreferences demo"
- />
-
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="name"
- >
- </TextView>
-
- <EditText
- android:id="@+id/name"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text=""
- >
- </EditText>
-
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="password"
- >
- </TextView>
-
- <EditText
- android:id="@+id/password"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:password="true"
- android:text=""
- >
- </EditText>
- </LinearLayout>
主要實現代碼
- package com.demo;
-
- import android.app.Activity;
- import android.content.SharedPreferences;
- import android.os.Bundle;
- import android.widget.EditText;
-
- public class SharedPreferencesDemo extends Activity {
-
- public static final String SETTING_INFOS = "SETTING_Infos";
- public static final String NAME = "NAME";
- public static final String PASSWORD = "PASSWORD";
- private EditText field_name; //接收用戶名的組件
- private EditText filed_pass; //接收密碼的組件
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- //Find VIew
- field_name = (EditText) findViewById(R.id.name); //首先獲取用來輸入用戶名的組件
- filed_pass = (EditText) findViewById(R.id.password); //同時也須要獲取輸入密碼的組件
-
- // Restore preferences
- SharedPreferences settings = getSharedPreferences(SETTING_INFOS, 0); //獲取一個SharedPreferences對象
- String name = settings.getString(NAME, ""); //取出保存的NAME
- String password = settings.getString(PASSWORD, ""); //取出保存的PASSWORD
-
- //Set value
- field_name.setText(name); //將取出來的用戶名賦予field_name
- filed_pass.setText(password); //將取出來的密碼賦予filed_pass
- }
-
- @Override
- protected void onStop(){
- super.onStop();
-
- SharedPreferences settings = getSharedPreferences(SETTING_INFOS, 0); //首先獲取一個SharedPreferences對象
- settings.edit()
- .putString(NAME, field_name.getText().toString())
- .putString(PASSWORD, filed_pass.getText().toString())
- .commit();
- } //將用戶名和密碼保存進去
-
- }
- package com.demo;
-
- import android.app.Activity;
- import android.content.SharedPreferences;
- import android.os.Bundle;
- import android.widget.EditText;
-
- public class SharedPreferencesDemo extends Activity {
-
- public static final String SETTING_INFOS = "SETTING_Infos";
- public static final String NAME = "NAME";
- public static final String PASSWORD = "PASSWORD";
- private EditText field_name; //接收用戶名的組件
- private EditText filed_pass; //接收密碼的組件
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- //Find VIew
- field_name = (EditText) findViewById(R.id.name); //首先獲取用來輸入用戶名的組件
- filed_pass = (EditText) findViewById(R.id.password); //同時也須要獲取輸入密碼的組件
-
- // Restore preferences
- SharedPreferences settings = getSharedPreferences(SETTING_INFOS, 0); //獲取一個SharedPreferences對象
- String name = settings.getString(NAME, ""); //取出保存的NAME
- String password = settings.getString(PASSWORD, ""); //取出保存的PASSWORD
-
- //Set value
- field_name.setText(name); //將取出來的用戶名賦予field_name
- filed_pass.setText(password); //將取出來的密碼賦予filed_pass
- }
-
- @Override
- protected void onStop(){
- super.onStop();
-
- SharedPreferences settings = getSharedPreferences(SETTING_INFOS, 0); //首先獲取一個SharedPreferences對象
- settings.edit()
- .putString(NAME, field_name.getText().toString())
- .putString(PASSWORD, filed_pass.getText().toString())
- .commit();
- } //將用戶名和密碼保存進去
-
- }
SharedPreferences保存到哪裏去了?
SharedPreferences是以XML的格式以文件的方式自動保存的,在DDMS中的File Explorer中展開到/data/data/<package
name>/shared_prefs下,以上面這個爲例,能夠看到一個叫作SETTING_Infos.xml的文件
注意:Preferences只能在同一個包內使用,不能在不一樣的包之間使用。
二.文件存儲方式
在Android中,其提供了openFileInput 和 openFileOuput 方法讀取設備上的文件,下面看個例子代碼,具體以下所示:
String FILE_NAME = "tempfile.tmp"; //肯定要操做文件的文件名
FileOutputStream fos = openFileOutput(FILE_NAME, Context.MODE_PRIVATE); //初始化
FileInputStream fis = openFileInput(FILE_NAME); //建立寫入流
上述代碼中兩個方法只支持讀取該應用目錄下的文件,讀取非其自身目錄下的文件將會拋出異常。須要提醒的是,若是調用
FileOutputStream 時指定的文件不存在,Android 會自動建立它。另外,在默認狀況下,寫入的時候會覆蓋原文件內容,若是想把
新寫入的內容附加到原文件內容後,則能夠指定其模式爲Context.MODE_APPEND。
三.SQLite數據庫方式
SQLite是Android所帶的一個標準的數據庫,它支持SQL語句,它是一個輕量級的嵌入式數據庫。
1)實現的功能
在這個例子裏邊,咱們在程序的主界面有一些按鈕,經過這些按鈕能夠對數據庫進行標準的增、刪、改、查。
2)實現代碼
所用到的字符文件
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <string name="app_name">SQLite數據庫操做實例</string>
- <string name="button1">創建數據庫表</string>
- <string name="button2">刪除數據庫表</string>
- <string name="button3">插入兩條記錄</string>
- <string name="button4">刪除一條記錄</string>
- <string name="button5">查看數據庫表</string>
- </resources>
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <string name="app_name">SQLite數據庫操做實例</string>
- <string name="button1">創建數據庫表</string>
- <string name="button2">刪除數據庫表</string>
- <string name="button3">插入兩條記錄</string>
- <string name="button4">刪除一條記錄</string>
- <string name="button5">查看數據庫表</string>
- </resources>
佈局代碼
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
-
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/app_name"
- />
- <Button
- android:text="@string/button1"
- android:id="@+id/button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
- <Button
- android:text="@string/button2"
- android:id="@+id/button2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
- <Button
- android:text="@string/button3"
- android:id="@+id/button3"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
- <Button
- android:text="@string/button4"
- android:id="@+id/button4"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
- <Button
- android:text="@string/button5"
- android:id="@+id/button5"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
-
- </LinearLayout>
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
-
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/app_name"
- />
- <Button
- android:text="@string/button1"
- android:id="@+id/button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
- <Button
- android:text="@string/button2"
- android:id="@+id/button2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
- <Button
- android:text="@string/button3"
- android:id="@+id/button3"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
- <Button
- android:text="@string/button4"
- android:id="@+id/button4"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
- <Button
- android:text="@string/button5"
- android:id="@+id/button5"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- ></Button>
-
- </LinearLayout>
主要代碼
- package com.sqlite;
-
- import android.app.Activity;
- import android.content.Context;
- import android.database.Cursor;
- import android.database.SQLException;
- import android.database.sqlite.SQLiteDatabase;
- import android.database.sqlite.SQLiteOpenHelper;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
-
- /*
- * 什麼是SQLiteDatabase?
- * 一個SQLiteDatabase的實例表明了一個SQLite的數據庫,經過SQLiteDatabase實例的一些方法,咱們能夠執行SQL語句,
- * 對數據庫進行增、刪、查、改的操做。須要注意的是,數據庫對於一個應用來講是私有的,而且在一個應用當中,數據庫的名字也是唯一的。
- */
-
- /*
- * 什麼是SQLiteOpenHelper ?
- * 這個類主要生成一個數據庫,並對數據庫的版本進行管理。
- * 當在程序當中調用這個類的方法getWritableDatabase()或者getReadableDatabase()方法的時候,若是當時沒有數據,那麼Android系統就會自動生成一個數據庫。
- * SQLiteOpenHelper 是一個抽象類,咱們一般須要繼承它,而且實現裏邊的3個函數,
- * onCreate(SQLiteDatabase):在數據庫第一次生成的時候會調用這個方法,通常咱們在這個方法裏邊生成數據庫表。
- * onUpgrade(SQLiteDatabase, int, int):當數據庫須要升級的時候,Android系統會主動的調用這個方法。通常咱們在這個方法裏邊刪除數據表,並創建新的數據表,固然是否還須要作其餘的操做,徹底取決於應用的需求。
- * onOpen(SQLiteDatabase):這是當打開數據庫時的回調函數,通常也不會用到。
- */
-
- public class SQLiteDemo extends Activity {
-
- OnClickListener listener1 = null;
- OnClickListener listener2 = null;
- OnClickListener listener3 = null;
- OnClickListener listener4 = null;
- OnClickListener listener5 = null;
-
- Button button1;
- Button button2;
- Button button3;
- Button button4;
- Button button5;
-
- DatabaseHelper mOpenHelper;
-
- private static final String DATABASE_NAME = "dbForTest.db";
- private static final int DATABASE_VERSION = 1;
- private static final String TABLE_NAME = "diary";
- private static final String TITLE = "title";
- private static final String BODY = "body";
-
- //創建一個內部類,主要生成一個數據庫
- 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) {
- }
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- prepareListener();
- initLayout();
- mOpenHelper = new DatabaseHelper(this);
-
- }
-
- private void initLayout() {
- button1 = (Button) findViewById(R.id.button1);
- button1.setOnClickListener(listener1);
-
- button2 = (Button) findViewById(R.id.button2);
- button2.setOnClickListener(listener2);
-
- button3 = (Button) findViewById(R.id.button3);
- button3.setOnClickListener(listener3);
-
- button4 = (Button) findViewById(R.id.button4);
- button4.setOnClickListener(listener4);
-
- button5 = (Button) findViewById(R.id.button5);
- button5.setOnClickListener(listener5);
-
- }
-
- private void prepareListener() {
- listener1 = new OnClickListener() {
- public void onClick(View v) {
- CreateTable();
- }
- };
- listener2 = new OnClickListener() {
- public void onClick(View v) {
- dropTable();
- }
- };
- listener3 = new OnClickListener() {
- public void onClick(View v) {
- insertItem();
- }
- };
- listener4 = new OnClickListener() {
- public void onClick(View v) {
- deleteItem();
- }
- };
- listener5 = new OnClickListener() {
- public void onClick(View v) {
- showItems();
- }
- };
- }
-
- /*
- * 從新創建數據表
- */
- private void CreateTable() {
- //mOpenHelper.getWritableDatabase()語句負責獲得一個可寫的SQLite數據庫,若是這個數據庫尚未創建,
- //那麼mOpenHelper輔助類負責創建這個數據庫。若是數據庫已經創建,那麼直接返回一個可寫的數據庫。
- 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("數據表重建錯誤");
- }
- }
-
- /*
- * 刪除數據表
- */
- private void dropTable() {
- //mOpenHelper.getWritableDatabase()語句負責獲得一個可寫的SQLite數據庫,若是這個數據庫尚未創建,
- //那麼mOpenHelper輔助類負責創建這個數據庫。若是數據庫已經創建,那麼直接返回一個可寫的數據庫。
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- String sql = "drop table " + TABLE_NAME;
- try {
- db.execSQL(sql);
- setTitle("數據表成功刪除:" + sql);
- } catch (SQLException e) {
- setTitle("數據表刪除錯誤");
- }
- }
-
- /*
- * 插入兩條數據
- */
- private void insertItem() {
- //mOpenHelper.getWritableDatabase()語句負責獲得一個可寫的SQLite數據庫,若是這個數據庫尚未創建,
- //那麼mOpenHelper輔助類負責創建這個數據庫。若是數據庫已經創建,那麼直接返回一個可寫的數據庫。
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- String sql1 = "insert into " + TABLE_NAME + " (" + TITLE + ", " + BODY
- + ") values('haiyang', 'android的發展真是迅速啊');";
- String sql2 = "insert into " + TABLE_NAME + " (" + TITLE + ", " + BODY
- + ") values('icesky', 'android的發展真是迅速啊');";
- try {
- // Log.i()會將參數內容打印到日誌當中,而且打印級別是Info級別
- // Android支持5種打印級別,分別是Verbose、Debug、Info、Warning、Error,固然咱們在程序當中通常用到的是Info級別
- Log.i("haiyang:sql1=", sql1);
- Log.i("haiyang:sql2=", sql2);
- db.execSQL(sql1);
- db.execSQL(sql2);
- setTitle("插入兩條數據成功");
- } catch (SQLException e) {
- setTitle("插入兩條數據失敗");
- }
- }
-
- /*
- * 刪除其中的一條數據
- */
- private void deleteItem() {
- try {
- //mOpenHelper.getWritableDatabase()語句負責獲得一個可寫的SQLite數據庫,若是這個數據庫尚未創建,
- //那麼mOpenHelper輔助類負責創建這個數據庫。若是數據庫已經創建,那麼直接返回一個可寫的數據庫。
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- //第一個參數是數據庫表名,在這裏是TABLE_NAME,也就是diary。
- //第二個參數,至關於SQL語句當中的where部分,也就是描述了刪除的條件。
- //若是在第二個參數當中有「?」符號,那麼第三個參數中的字符串會依次替換在第二個參數當中出現的「?」符號。
- db.delete(TABLE_NAME, " title = 'haiyang'", null);
- setTitle("刪除title爲haiyang的一條記錄");
- } catch (SQLException e) {
-
- }
-
- }
-
- /*
- * 在屏幕的title區域顯示當前數據表當中的數據的條數。
- */
- /*
- * Cursor cur = db.query(TABLE_NAME, col, null, null, null, null, null)語句將查詢到的數據放到一個Cursor 當中。
- 這個Cursor裏邊封裝了這個數據表TABLE_NAME當中的全部條列。
- query()方法至關的有用,在這裏咱們簡單地講一下。
- 第一個參數是數據庫裏邊表的名字,好比在咱們這個例子,表的名字就是TABLE_NAME,也就是"diary"。
- 第二個字段是咱們想要返回數據包含的列的信息。在這個例子當中咱們想要獲得的列有title、body。咱們把這兩個列的名字放到字符串數組裏邊來。
- 第三個參數爲selection,至關於SQL語句的where部分,若是想返回全部的數據,那麼就直接置爲null。
- 第四個參數爲selectionArgs。在selection部分,你有可能用到「?」,那麼在selectionArgs定義的字符串會代替selection中的「?」。
- 第五個參數爲groupBy。定義查詢出來的數據是否分組,若是爲null則說明不用分組。
- 第六個參數爲having ,至關於SQL語句當中的having部分。
- 第七個參數爲orderBy,來描述咱們指望的返回值是否須要排序,若是設置爲null則說明不須要排序。
- */
-
- private void showItems() {
-
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- String col[] = { TITLE, BODY };
- //查詢數據
- Cursor cur = db.query(TABLE_NAME, col, null, null, null, null, null);
- Integer num = cur.getCount();
- setTitle(Integer.toString(num) + " 條記錄");
- }
- }
- package com.sqlite;
-
- import android.app.Activity;
- import android.content.Context;
- import android.database.Cursor;
- import android.database.SQLException;
- import android.database.sqlite.SQLiteDatabase;
- import android.database.sqlite.SQLiteOpenHelper;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
-
- /*
- * 什麼是SQLiteDatabase?
- * 一個SQLiteDatabase的實例表明了一個SQLite的數據庫,經過SQLiteDatabase實例的一些方法,咱們能夠執行SQL語句,
- * 對數據庫進行增、刪、查、改的操做。須要注意的是,數據庫對於一個應用來講是私有的,而且在一個應用當中,數據庫的名字也是唯一的。
- */
-
- /*
- * 什麼是SQLiteOpenHelper ?
- * 這個類主要生成一個數據庫,並對數據庫的版本進行管理。
- * 當在程序當中調用這個類的方法getWritableDatabase()或者getReadableDatabase()方法的時候,若是當時沒有數據,那麼Android系統就會自動生成一個數據庫。
- * SQLiteOpenHelper 是一個抽象類,咱們一般須要繼承它,而且實現裏邊的3個函數,
- * onCreate(SQLiteDatabase):在數據庫第一次生成的時候會調用這個方法,通常咱們在這個方法裏邊生成數據庫表。
- * onUpgrade(SQLiteDatabase, int, int):當數據庫須要升級的時候,Android系統會主動的調用這個方法。通常咱們在這個方法裏邊刪除數據表,並創建新的數據表,固然是否還須要作其餘的操做,徹底取決於應用的需求。
- * onOpen(SQLiteDatabase):這是當打開數據庫時的回調函數,通常也不會用到。
- */
-
- public class SQLiteDemo extends Activity {
-
- OnClickListener listener1 = null;
- OnClickListener listener2 = null;
- OnClickListener listener3 = null;
- OnClickListener listener4 = null;
- OnClickListener listener5 = null;
-
- Button button1;
- Button button2;
- Button button3;
- Button button4;
- Button button5;
-
- DatabaseHelper mOpenHelper;
-
- private static final String DATABASE_NAME = "dbForTest.db";
- private static final int DATABASE_VERSION = 1;
- private static final String TABLE_NAME = "diary";
- private static final String TITLE = "title";
- private static final String BODY = "body";
-
- //創建一個內部類,主要生成一個數據庫
- 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) {
- }
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- prepareListener();
- initLayout();
- mOpenHelper = new DatabaseHelper(this);
-
- }
-
- private void initLayout() {
- button1 = (Button) findViewById(R.id.button1);
- button1.setOnClickListener(listener1);
-
- button2 = (Button) findViewById(R.id.button2);
- button2.setOnClickListener(listener2);
-
- button3 = (Button) findViewById(R.id.button3);
- button3.setOnClickListener(listener3);
-
- button4 = (Button) findViewById(R.id.button4);
- button4.setOnClickListener(listener4);
-
- button5 = (Button) findViewById(R.id.button5);
- button5.setOnClickListener(listener5);
-
- }
-
- private void prepareListener() {
- listener1 = new OnClickListener() {
- public void onClick(View v) {
- CreateTable();
- }
- };
- listener2 = new OnClickListener() {
- public void onClick(View v) {
- dropTable();
- }
- };
- listener3 = new OnClickListener() {
- public void onClick(View v) {
- insertItem();
- }
- };
- listener4 = new OnClickListener() {
- public void onClick(View v) {
- deleteItem();
- }
- };
- listener5 = new OnClickListener() {
- public void onClick(View v) {
- showItems();
- }
- };
- }
-
- /*
- * 從新創建數據表
- */
- private void CreateTable() {
- //mOpenHelper.getWritableDatabase()語句負責獲得一個可寫的SQLite數據庫,若是這個數據庫尚未創建,
- //那麼mOpenHelper輔助類負責創建這個數據庫。若是數據庫已經創建,那麼直接返回一個可寫的數據庫。
- 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("數據表重建錯誤");
- }
- }
-
- /*
- * 刪除數據表
- */
- private void dropTable() {
- //mOpenHelper.getWritableDatabase()語句負責獲得一個可寫的SQLite數據庫,若是這個數據庫尚未創建,
- //那麼mOpenHelper輔助類負責創建這個數據庫。若是數據庫已經創建,那麼直接返回一個可寫的數據庫。
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- String sql = "drop table " + TABLE_NAME;
- try {
- db.execSQL(sql);
- setTitle("數據表成功刪除:" + sql);
- } catch (SQLException e) {
- setTitle("數據表刪除錯誤");
- }
- }
-
- /*
- * 插入兩條數據
- */
- private void insertItem() {
- //mOpenHelper.getWritableDatabase()語句負責獲得一個可寫的SQLite數據庫,若是這個數據庫尚未創建,
- //那麼mOpenHelper輔助類負責創建這個數據庫。若是數據庫已經創建,那麼直接返回一個可寫的數據庫。
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- String sql1 = "insert into " + TABLE_NAME + " (" + TITLE + ", " + BODY
- + ") values('haiyang', 'android的發展真是迅速啊');";
- String sql2 = "insert into " + TABLE_NAME + " (" + TITLE + ", " + BODY
- + ") values('icesky', 'android的發展真是迅速啊');";
- try {
- // Log.i()會將參數內容打印到日誌當中,而且打印級別是Info級別
- // Android支持5種打印級別,分別是Verbose、Debug、Info、Warning、Error,固然咱們在程序當中通常用到的是Info級別
- Log.i("haiyang:sql1=", sql1);
- Log.i("haiyang:sql2=", sql2);
- db.execSQL(sql1);
- db.execSQL(sql2);
- setTitle("插入兩條數據成功");
- } catch (SQLException e) {
- setTitle("插入兩條數據失敗");
- }
- }
-
- /*
- * 刪除其中的一條數據
- */
- private void deleteItem() {
- try {
- //mOpenHelper.getWritableDatabase()語句負責獲得一個可寫的SQLite數據庫,若是這個數據庫尚未創建,
- //那麼mOpenHelper輔助類負責創建這個數據庫。若是數據庫已經創建,那麼直接返回一個可寫的數據庫。
- SQLiteDatabase db = mOpenHelper.getWritableDatabase();
- //第一個參數是數據庫表名,在這裏是TABLE_NAME,也就是diary。
- //第二個參數,至關於SQL語句當中的where部分,也就是描述了刪除的條件。
- //若是在第二個參數當中有「?」符號,那麼第三個參數中的字符串會依次替換在第二個參數當中出現的「?」符號。
- db.delete(TABLE_NAME, " title = 'haiyang'", null);
- setTitle("刪除title爲haiyang的一條記錄");
- } catch (SQLException e) {
-
- }
-
- }
-
- /*
- * 在屏幕的title區域顯示當前數據表當中的數據的條數。
- */
- /*
- * Cursor cur = db.query(TABLE_NAME, col, null, null, null, null, null)語句將查詢到的數據放到一個Cursor 當中。
- 這個Cursor裏邊封裝了這個數據表TABLE_NAME當中的全部條列。
- query()方法至關的有用,在這裏咱們簡單地講一下。
- 第一個參數是數據庫裏邊表的名字,好比在咱們這個例子,表的名字就是TABLE_NAME,也就是"diary"。
- 第二個字段是咱們想要返回數據包含的列的信息。在這個例子當中咱們想要獲得的列有title、body。咱們把這兩個列的名字放到字符串數組裏邊來。
- 第三個參數爲selection,至關於SQL語句的where部分,若是想返回全部的數據,那麼就直接置爲null。
- 第四個參數爲selectionArgs。在selection部分,你有可能用到「?」,那麼在selectionArgs定義的字符串會代替selection中的「?」。
- 第五個參數爲groupBy。定義查詢出來的數據是否分組,若是爲null則說明不用分組。
- 第六個參數爲having ,至關於SQL語句當中的having部分。
- 第七個參數爲orderBy,來描述咱們指望的返回值是否須要排序,若是設置爲null則說明不須要排序。
- */
-
- private void showItems() {
-
- SQLiteDatabase db = mOpenHelper.getReadableDatabase();
- String col[] = { TITLE, BODY };
- //查詢數據
- Cursor cur = db.query(TABLE_NAME, col, null, null, null, null, null);
- Integer num = cur.getCount();
- setTitle(Integer.toString(num) + " 條記錄");
- }
- }
四.內容提供器(Content provider)方式
在Android的設計「哲學」裏是鼓勵開發者使用內部類的,這樣不但使用方便,並且執行效率也高。
1.什麼是ContentProvider
數據在Android當中是私有的,固然這些數據包括文件數據和數據庫數據以及一些其餘類型的數據。難道兩個程序之間就沒有辦法對於數據進行交換?解決這個問題主要靠ContentProvider。
一個Content Provider類實現了一組標準的方法接口,從而可以讓其餘的應用保存或讀取此Content Provider的各類數據類型。也就是說,一個程序能夠經過實現一個Content Provider的抽象接口將本身的數據暴露出去。外界根本看不到,也不用看到這個應用暴露的數據在應用當中是如何存儲的,或者是用數據庫存儲仍是用文件存儲,仍是經過網上得到,這些一切都不重要,重要的是外界能夠經過這一套標準及統一的接口和程序裏的數據打交道,能夠讀取程序的數據,也能夠刪除程序的數據,固然,中間也會涉及一些權限的問題。
下邊列舉一些較常見的接口,這些接口以下所示。
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.什麼是ContentResolver
外界的程序經過ContentResolver接口能夠訪問ContentProvider提供的數據,在Activity當中經過getContentResolver()能夠獲得當前應用的ContentResolver實例。
ContentResolver提供的接口和ContentProvider中須要實現的接口對應,主要有如下幾個。
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而且符合必定條件的數據。
3.ContentProvider和ContentResolver中用到的Uri
在ContentProvider和ContentResolver當中用到了Uri的形式一般有兩種,一種是指定所有數據,另外一種是指定某個ID的數據。
咱們看下面的例子。
content://contacts/people/ 這個Uri指定的就是所有的聯繫人數據。
content://contacts/people/1 這個Uri指定的是ID爲1的聯繫人的數據。
在上邊兩個類中用到的Uri通常由3部分組成。
第一部分是:"content://" 。
第二部分是要得到數據的一個字符串片斷。
最後就是ID(若是沒有指定ID,那麼表示返回所有)。
因爲URI一般比較長,並且有時候容易出錯,且難以理解。因此,在Android當中定義了一些輔助類,而且定義了一些常量來代替這些長字符串的使用,例以下邊的代碼:
Contacts.People.CONTENT_URI (聯繫人的URI)。
1)實現的功能
在這個例子裏邊,首先在系統的聯繫人應用當中插入一些聯繫人信息,而後把這些聯繫人的名字和電話再顯示出來
2)實現方法
- package com.contentProvider;
-
- import android.app.ListActivity;
- import android.database.Cursor;
- import android.os.Bundle;
- import android.provider.Contacts.Phones;
- import android.widget.ListAdapter;
- import android.widget.SimpleCursorAdapter;
-
- public class ContentProviderDemo extends ListActivity {
-
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- //getContentResolver()方法獲得應用的ContentResolver實例。
- // query(Phones.CONTENT_URI, null, null, null, null)。它是ContentResolver裏的方法,負責查詢全部聯繫人,並返回一個Cursor。這個方法參數比較多,每一個參數的具體含義以下。
- //· 第一個參數爲Uri,在這個例子裏邊這個Uri是聯繫人的Uri。
- //· 第二個參數是一個字符串的數組,數組裏邊的每個字符串都是數據表中某一列的名字,它指定返回數據表中那些列的值。
- //· 第三個參數至關於SQL語句的where部分,描述哪些值是咱們須要的。
- //· 第四個參數是一個字符串數組,它裏邊的值依次代替在第三個參數中出現的「?」符號。
- //· 第五個參數指定了排序的方式。
- Cursor c = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null);
- startManagingCursor(c); //讓系統來管理生成的Cursor。
- 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); //將ListView和SimpleCursorAdapter進行綁定。
- }
-
- }
- package com.contentProvider;
-
- import android.app.ListActivity;
- import android.database.Cursor;
- import android.os.Bundle;
- import android.provider.Contacts.Phones;
- import android.widget.ListAdapter;
- import android.widget.SimpleCursorAdapter;
-
- public class ContentProviderDemo extends ListActivity {
-
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- //getContentResolver()方法獲得應用的ContentResolver實例。
- // query(Phones.CONTENT_URI, null, null, null, null)。它是ContentResolver裏的方法,負責查詢全部聯繫人,並返回一個Cursor。這個方法參數比較多,每一個參數的具體含義以下。
- //· 第一個參數爲Uri,在這個例子裏邊這個Uri是聯繫人的Uri。
- //· 第二個參數是一個字符串的數組,數組裏邊的每個字符串都是數據表中某一列的名字,它指定返回數據表中那些列的值。
- //· 第三個參數至關於SQL語句的where部分,描述哪些值是咱們須要的。
- //· 第四個參數是一個字符串數組,它裏邊的值依次代替在第三個參數中出現的「?」符號。
- //· 第五個參數指定了排序的方式。
- Cursor c = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null);
- startManagingCursor(c); //讓系統來管理生成的Cursor。
- 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); //將ListView和SimpleCursorAdapter進行綁定。
- }
-
- }
五. 網絡存儲方式
1.例子介紹
經過郵政編碼查詢該地區的天氣預報,以POST發送的方式發送請求到webservicex.NET站點,訪問WebService.webservicex.Net站點上提供查詢天氣預報的服務,具體信息請參考其WSDL文檔,網址爲:
http://www.webservicex.net/WeatherForecast.asmx?WSDL。
輸入:美國某個城市的郵政編碼。
輸出:該郵政編碼對應城市的天氣預報。
2.實現步驟以下
(1)若是須要訪問外部網絡,則須要在AndroidManifest.xml文件中加入以下代碼申請權限許可:
<!-- Permissions -->
<uses-permission Android:name="Android.permission.INTERNET" />
(2)以HTTP POST的方式發送(注意: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」(美國WASHINGTON D.C)的內容,其返回的內容以下:
<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>