【2017.2.14】Android之四組件刺桃、五存儲、六布局

<h1>一.四大組件:</h1>

Android四大組件分別為activity、service、content provider敢靡、broadcast receiver。
一苦银、Android四大組件詳解
1啸胧、activity
(1)一個Activity通常就是一個單獨的屏幕(窗口)。
(2)Activity之間通過Intent進行通信幔虏。
(3)android應(yīng)用中每一個Activity都必須要在AndroidManifest.xml配置文件中聲明纺念,否則系統(tǒng)將不識別也不執(zhí)行該Activity。
2想括、service
(1)service用于在后臺完成用戶指定的操作陷谱。service分為兩種:
(a)started(啟動):當(dāng)應(yīng)用程序組件(如activity)調(diào)用startService()方法啟動服務(wù)時,服務(wù)處于started狀態(tài)主胧。
(b)bound(綁定):當(dāng)應(yīng)用程序組件調(diào)用bindService()方法綁定到服務(wù)時叭首,服務(wù)處于bound狀態(tài)习勤。
(2)startService()與bindService()區(qū)別:
(a)started service(啟動服務(wù))是由其他組件調(diào)用startService()方法啟動的踪栋,這導(dǎo)致服務(wù)的onStartCommand()方法被調(diào)用。當(dāng)服務(wù)是started狀態(tài)時图毕,其生命周期與啟動它的組件無關(guān)夷都,并且可以在后臺無限期運行,即使啟動服務(wù)的組件已經(jīng)被銷毀予颤。因此囤官,服務(wù)需要在完成任務(wù)后調(diào)用stopSelf()方法停止,或者由其他組件調(diào)用stopService()方法停止蛤虐。
(b)使用bindService()方法啟用服務(wù)党饮,調(diào)用者與服務(wù)綁定在了一起,調(diào)用者一旦退出驳庭,服務(wù)也就終止刑顺,大有“不求同時生,必須同時死”的特點饲常。
(3)開發(fā)人員需要在應(yīng)用程序配置文件中聲明全部的service蹲堂,使用<service></service>標(biāo)簽。
(4)Service通常位于后臺運行贝淤,它一般不需要與用戶交互柒竞,因此Service組件沒有圖形用戶界面。Service組件需要繼承Service基類播聪。Service組件通常用于為其他組件提供后臺服務(wù)或監(jiān)控其他組件的運行狀態(tài)朽基。
3布隔、content provider
(1)android平臺提供了Content Provider使一個應(yīng)用程序的指定數(shù)據(jù)集提供給其他應(yīng)用程序。其他應(yīng)用可以通過ContentResolver類從該內(nèi)容提供者中獲取或存入數(shù)據(jù)稼虎。
(2)只有需要在多個應(yīng)用程序間共享數(shù)據(jù)是才需要內(nèi)容提供者执泰。例如,通訊錄數(shù)據(jù)被多個應(yīng)用程序使用渡蜻,且必須存儲在一個內(nèi)容提供者中术吝。它的好處是統(tǒng)一數(shù)據(jù)訪問方式。
(3)ContentProvider實現(xiàn)數(shù)據(jù)共享茸苇。ContentProvider用于保存和獲取數(shù)據(jù)排苍,并使其對所有應(yīng)用程序可見。這是不同應(yīng)用程序間共享數(shù)據(jù)的唯一方式学密,因為android沒有提供所有應(yīng)用共同訪問的公共存儲區(qū)淘衙。
(4)開發(fā)人員不會直接使用ContentProvider類的對象,大多數(shù)是通過ContentResolver對象實現(xiàn)對ContentProvider的操作腻暮。
(5)ContentProvider使用URI來唯一標(biāo)識其數(shù)據(jù)集彤守,這里的URI以content://作為前綴,表示該數(shù)據(jù)由ContentProvider來管理哭靖。
4具垫、broadcast receiver
(1)你的應(yīng)用可以使用它對外部事件進行過濾,只對感興趣的外部事件(如當(dāng)電話呼入時试幽,或者數(shù)據(jù)網(wǎng)絡(luò)可用時)進行接收并做出響應(yīng)筝蚕。廣播接收器沒有用戶界面。然而铺坞,它們可以啟動一個activity或serice來響應(yīng)它們收到的信息起宽,或者用NotificationManager來通知用戶。通知可以用很多種方式來吸引用戶的注意力济榨,例如閃動背燈坯沪、震動、播放聲音等擒滑。一般來說是在狀態(tài)欄上放一個持久的圖標(biāo)腐晾,用戶可以打開它并獲取消息。
(2)廣播接收者的注冊有兩種方法橘忱,分別是程序動態(tài)注冊和AndroidManifest文件中進行靜態(tài)注冊赴魁。
(3)動態(tài)注冊廣播接收器特點是當(dāng)用來注冊的Activity關(guān)掉后,廣播也就失效了钝诚。靜態(tài)注冊無需擔(dān)憂廣播接收器是否被關(guān)閉颖御,只要設(shè)備是開啟狀態(tài),廣播接收器也是打開著的。也就是說哪怕app本身未啟動潘拱,該app訂閱的廣播在觸發(fā)時也會對它起作用疹鳄。
二、android四大組件總結(jié):
(1)4大組件的注冊
4大基本組件都需要注冊才能使用芦岂,每個Activity瘪弓、service、Content Provider都需要在AndroidManifest文件中進行配置禽最。AndroidManifest文件中未進行聲明的activity腺怯、服務(wù)以及內(nèi)容提供者將不為系統(tǒng)所見,從而也就不可用川无。而broadcast receiver廣播接收者的注冊分靜態(tài)注冊(在AndroidManifest文件中進行配置)和通過代碼動態(tài)創(chuàng)建并以調(diào)用Context.registerReceiver()的方式注冊至系統(tǒng)呛占。需要注意的是在AndroidManifest文件中進行配置的廣播接收者會隨系統(tǒng)的啟動而一直處于活躍狀態(tài),只要接收到感興趣的廣播就會觸發(fā)(即使程序未運行)懦趋。
(2)4大組件的激活
內(nèi)容提供者的激活:當(dāng)接收到ContentResolver發(fā)出的請求后晾虑,內(nèi)容提供者被激活。而其它三種組件activity仅叫、服務(wù)和廣播接收器被一種叫做intent的異步消息所激活帜篇。
(3)4大組件的關(guān)閉
內(nèi)容提供者僅在響應(yīng)ContentResolver提出請求的時候激活。而一個廣播接收器僅在響應(yīng)廣播信息的時候激活诫咱。所以笙隙,沒有必要去顯式的關(guān)閉這些組件。Activity關(guān)閉:可以通過調(diào)用它的finish()方法來關(guān)閉一個activity遂跟。服務(wù)關(guān)閉:對于通過startService()方法啟動的服務(wù)要調(diào)用Context.stopService()方法關(guān)閉服務(wù)逃沿,使用bindService()方法啟動的服務(wù)要調(diào)用Contex.unbindService()方法關(guān)閉服務(wù)。
(4)android中的任務(wù)(activity棧)
(a)任務(wù)其實就是activity的棧幻锁,它由一個或多個Activity組成,共同完成一個完整的用戶體驗边臼。棧底的是啟動整個任務(wù)的Activity哄尔,棧頂?shù)氖钱?dāng)前運行的用戶可以交互的Activity,當(dāng)一個activity啟動另外一個的時候柠并,新的activity就被壓入棧岭接,并成為當(dāng)前運行的activity。而前一個activity仍保持在棧之中臼予。當(dāng)用戶按下BACK鍵的時候鸣戴,當(dāng)前activity出棧,而前一個恢復(fù)為當(dāng)前運行的activity粘拾。棧中保存的其實是對象窄锅,棧中的Activity永遠不會重排,只會壓入或彈出缰雇。
(b)任務(wù)中的所有activity是作為一個整體進行移動的入偷。整個的任務(wù)(即activity棧)可以移到前臺追驴,或退至后臺。
(c)Android系統(tǒng)是一個多任務(wù)(Multi-Task)的操作系統(tǒng)疏之,可以在用手機聽音樂的同時殿雪,也執(zhí)行其他多個程序。每多執(zhí)行一個應(yīng)用程序锋爪,就會多耗費一些系統(tǒng)內(nèi)存丙曙,當(dāng)同時執(zhí)行的程序過多,或是關(guān)閉的程序沒有正確釋放掉內(nèi)存其骄,系統(tǒng)就會覺得越來越慢河泳,甚至不穩(wěn)定。為了解決這個問題年栓,Android引入了一個新的機制拆挥,即生命周期(Life Cycle)。

<h1>二.六大布局:</h1>
Android六大界面布局方式:

聲明Android程序布局有兩種方式:

  1. 使用XML文件描述界面布局某抓;
  2. Java代碼中通過調(diào)用方法進行控制纸兔。
    我們既可以使用任何一種聲明界面布局的方式,也可以同時使用兩種方式否副。
    使用XML文件聲明有以下3個特點:
  3. 將程序的表現(xiàn)層和控制層分離汉矿;
  4. 在后期修改用戶界面時,無須更改程序的源程序备禀;
  5. 可通過WYSIWYG可視化工具直接看到所設(shè)計的用戶界面洲拇,有利于加快界面設(shè)計的過程。

建議盡量采用XML文件聲明界面元素布局曲尸。在程序運行時動態(tài)添加界面布局會大大降低應(yīng)用響應(yīng)速度赋续,但依然可以在必要時動態(tài)改變屏幕內(nèi)容。
六大界面布局方式包括: 線性布局(LinearLayout)另患、框架布局(FrameLayout)纽乱、表格布局(TableLayout)、相對布局(RelativeLayout)昆箕、絕對布局(AbsoluteLayout)和網(wǎng)格布局(GridLayout) 鸦列。

  1. LinearLayout線性布局
    LinearLayout容器中的組件一個挨一個排列,通過控制android:orientation屬性鹏倘,可控制各組件是橫向排列還是縱向排列薯嗤。
    LinearLayout的常用XML屬性及相關(guān)方法
    XML屬性
    相關(guān)方法
    說明

android:gravity
setGravity(int)
設(shè)置布局管理器內(nèi)組件的對齊方式

android:orientation
setOrientation(int)
設(shè)置布局管理器內(nèi)組件的排列方式,可以設(shè)置為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中所占的權(quán)重

  1. TableLayout表格布局
    TableLayout繼承自Linearout诲锹,本質(zhì)上仍然是線性布局管理器繁仁。表格布局采用行、列的形式來管理UI組件归园,并不需要明確地聲明包含多少行黄虱、多少列,而是通過添加TableRow庸诱、其他組件來控制表格的行數(shù)和列數(shù)捻浦。
    每向TableLayout中添加一個TableRow就代表一行;
    每向TableRow中添加一個一個子組件就表示一列桥爽;
    如果直接向TableLayout添加組件朱灿,那么該組件將直接占用一行;
    在表格布局中钠四,可以為單元格設(shè)置如下三種行為方式:
    Shrinkable:該列的所有單元格的寬度可以被收縮盗扒,以保證該表格能適應(yīng)父容器的寬度;
    Strentchable:該列所有單元格的寬度可以被拉伸缀去,以保證組件能完全填滿表格空余空間侣灶;
    Collapsed:如果該列被設(shè)置為Collapsed,那么該列的所有單元格會被隱藏缕碎;

TableLayout的常用XML屬性及方法
XML屬性
相關(guān)方法
說明

android:collapseColumns
setColumns(int, boolean)
設(shè)置需要被隱藏的列的序號褥影,多個序號間用逗號分隔

android:shrinkColumns
setShrinkAllColumns(boolean)
設(shè)置需要被收縮的列的序號

android:stretchColumns
setStretchAllColumns(boolean)
設(shè)置允許被拉伸的列的序號

  1. FrameLayout幀布局
    FrameLayout直接繼承自ViewGroup組件。幀布局為每個加入其中的組件創(chuàng)建一個空白的區(qū)域(稱為一幀)咏雌,每個子組件占據(jù)一幀凡怎,這些幀會根據(jù)gravity屬性執(zhí)行自動對齊。
    FrameLayout的常用XM了屬性及方法
    XML屬性
    相關(guān)方法
    說明

android:foreground
setForeground(Drawable)
設(shè)置該幀布局容器的前景圖像

android:foregroundGravity
setForeGroundGraity(int)
定義繪制前景圖像的gravity屬性

  1. RelativeLayout相對布局
    RelativeLayout的XML屬性及相關(guān)方法說明
    XML屬性
    相關(guān)方法
    說明

android:gravity
setGravity(int)

android:ignoreGravity
setIgnoreGravity(int)
設(shè)置哪個組件不受gravity屬性的影響

為了控制該布局容器的各子組件的布局分布赊抖,RelativeLayout提供了一個內(nèi)部類:RelativeLayout.LayoutParams统倒。
RelativeLayout.LayoutParams里只能設(shè)為boolean的XML屬性
XML屬性
說明

android:layout_centerHorizontal
設(shè)置該子組件是否位于布局容器的水平居中

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組件的右側(cè)

android:layout_toLeftOf

android:layout_above

android:layout_below

android:layout_alignTop

android:layout_alignBottom

android:layout_alignRight

android:layout_alignLeft

  1. Android 4.0新增的網(wǎng)格布局GridLayout
    GridLayout是Android4.0增加的網(wǎng)格布局控件,與之前的TableLayout有些相似熏迹,它把整個容器劃分為rows × columns個網(wǎng)格隶债,每個網(wǎng)格可以放置一個組件受啥。性能及功能都要比tablelayout好,比如GridLayout布局中的單元格可以跨越多行猫牡,而tablelayout則不行墓猎,此外捆昏,其渲染速度也比tablelayout要快。
    GridLayout提供了setRowCount(int)和setColumnCount(int)方法來控制該網(wǎng)格的行和列的數(shù)量毙沾。
    GridLayout常用的XML屬性和方法說明
    XML屬性
    相關(guān)方法
    說明

android:alignmentMode
setAlignmentMode(int)
設(shè)置該布局管理器采用的對齊模式

android:columnCount
setColumnCount(int)
設(shè)置該網(wǎng)格的列數(shù)量

android:columnOrderPreserved
setColumnOrderPreserved(boolean)
設(shè)置該網(wǎng)格容器是否保留序列號

android:roeCount
setRowCount(int)
設(shè)置該網(wǎng)格的行數(shù)量

android:rowOrderPreserved
setRowOrderPreserved(boolean)
設(shè)置該網(wǎng)格容器是否保留行序號

android:useDefaultMargins
setUseDefaultMargins(boolean)
設(shè)置該布局管理器是否使用默認(rèn)的頁邊距

為了控制GridLayout布局容器中各子組件的布局分布骗卜,GridLayout提供了一個內(nèi)部類:GridLayout.LayoutParams,來控制Gridlayout布局容器中子組件的布局分布。
GridLayout.LayoutParams常用的XML屬性和方法說明
XML屬性
說明

android:layout_column
設(shè)置該組件在GridLayout的第幾列

android:layout_columnSpan
設(shè)置該子組件在GridLayout橫向上跨幾列

android:layout_gravity
設(shè)置該子組件采用何種方式占據(jù)該網(wǎng)格的空間

android:layout_row
設(shè)置該子組件在GridLayout的第幾行

android:layout_rowSpan
設(shè)置該子組件在GridLayout縱向上跨幾行

  1. AbsoluteLayout絕對布局
    即Android不提供任何布局控制寇仓,而是由開發(fā)人員自己通過X坐標(biāo)举户、Y坐標(biāo)來控制組件的位置。每個組件都可指定如下兩個XML屬性:
    layour_x;
    layout_y;

絕對布局已經(jīng)過時遍烦,不應(yīng)使用或少使用俭嘁。
界面布局類型的選擇和性能優(yōu)化
首先得明確,界面布局類型的嵌套越多越深越復(fù)雜服猪,會使布局實例化變慢供填,使Activity的展開時間延長。建議盡量減少布局嵌套罢猪,盡量減少創(chuàng)建View對象的數(shù)量近她。
1 . 減少布局層次,可考慮用RelativeLayout來代替LinearLayout膳帕。通過Relative的相對其他元素的位置來布局粘捎,可減少塊狀嵌套;
2 . 另一種減少布局層次的技巧是使用 <merge />
標(biāo)簽來合并布局危彩;
3 . 重用布局攒磨。Android支持在XML中使用 <include />
標(biāo)簽, <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數(shù)據(jù)庫方式漆羔、內(nèi)容提供器(Content provider)和網(wǎng)絡(luò)。
一.SharedPreferences方式
Android提供用來存儲一些簡單的配置信息的一種機制狱掂,例如演痒,一些默認(rèn)歡迎語、登錄的用戶名和密碼等趋惨。其以鍵值對的方式存儲鸟顺,
使得我們可以很方便的讀取和存入.
1)程序要實現(xiàn)的功能: 我們在Name文本框中輸入wangwu,在Password文本框中輸入123456器虾,然后退出這個應(yīng)用讯嫂。我們在應(yīng)用程序列表中找到這個應(yīng)用,重新啟動兆沙,可以看到其使用了前面輸入的Name和Password
2)實現(xiàn)的代碼
布局

view plaincopy to clipboard

<?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>

[xhtml] view plain copy

<?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>

    主要實現(xiàn)代碼

view plaincopy to clipboard

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();   
} //將用戶名和密碼保存進去   

}

[java] view plain copy

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只能在同一個包內(nèi)使用憎妙,不能在不同的包之間使用。
二.文件存儲方式
在Android中曲楚,其提供了openFileInput 和 openFileOuput 方法讀取設(shè)備上的文件厘唾,下面看個例子代碼,具體如下所示: String FILE_NAME = "tempfile.tmp"; //確定要操作文件的文件名 FileOutputStream fos = openFileOutput(FILE_NAME, Context.MODE_PRIVATE); //初始化 FileInputStream fis = openFileInput(FILE_NAME); //創(chuàng)建寫入流
上述代碼中兩個方法只支持讀取該應(yīng)用目錄下的文件龙誊,讀取非其自身目錄下的文件將會拋出異常抚垃。需要提醒的是,如果調(diào)用
FileOutputStream 時指定的文件不存在载迄,Android 會自動創(chuàng)建它讯柔。另外,在默認(rèn)情況下护昧,寫入的時候會覆蓋原文件內(nèi)容魂迄,如果想把
新寫入的內(nèi)容附加到原文件內(nèi)容后,則可以指定其模式為Context.MODE_APPEND惋耙。

三.SQLite數(shù)據(jù)庫方式
SQLite是Android所帶的一個標(biāo)準(zhǔn)的數(shù)據(jù)庫捣炬,它支持SQL語句,它是一個輕量級的嵌入式數(shù)據(jù)庫绽榛。 1)實現(xiàn)的功能
在這個例子里邊湿酸,我們在程序的主界面有一些按鈕,通過這些按鈕可以對數(shù)據(jù)庫進行標(biāo)準(zhǔn)的增灭美、刪推溃、改、查届腐。
2)實現(xiàn)代碼
所用到的字符文件

view plaincopy to clipboard

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">SQLite數(shù)據(jù)庫操作實例</string>
<string name="button1">建立數(shù)據(jù)庫表</string>
<string name="button2">刪除數(shù)據(jù)庫表</string>
<string name="button3">插入兩條記錄</string>
<string name="button4">刪除一條記錄</string>
<string name="button5">查看數(shù)據(jù)庫表</string>
</resources>

[xhtml] view plain copy

<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">SQLite數(shù)據(jù)庫操作實例</string>
<string name="button1">建立數(shù)據(jù)庫表</string>
<string name="button2">刪除數(shù)據(jù)庫表</string>
<string name="button3">插入兩條記錄</string>
<string name="button4">刪除一條記錄</string>
<string name="button5">查看數(shù)據(jù)庫表</string>
</resources>

      布局代碼

view plaincopy to clipboard

<?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>

[xhtml] view plain copy

<?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>

      主要代碼

view plaincopy to clipboard

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的數(shù)據(jù)庫,通過SQLiteDatabase實例的一些方法犁苏,我們可以執(zhí)行SQL語句硬萍,
  • 對數(shù)據(jù)庫進行增、刪围详、查朴乖、改的操作。需要注意的是助赞,數(shù)據(jù)庫對于一個應(yīng)用來說是私有的买羞,并且在一個應(yīng)用當(dāng)中,數(shù)據(jù)庫的名字也是惟一的雹食。
    */

/*

  • 什么是SQLiteOpenHelper 哩都?
  • 這個類主要生成一個數(shù)據(jù)庫,并對數(shù)據(jù)庫的版本進行管理婉徘。
  • 當(dāng)在程序當(dāng)中調(diào)用這個類的方法getWritableDatabase()或者getReadableDatabase()方法的時候漠嵌,如果當(dāng)時沒有數(shù)據(jù),那么Android系統(tǒng)就會自動生成一個數(shù)據(jù)庫盖呼。
  • SQLiteOpenHelper 是一個抽象類儒鹿,我們通常需要繼承它,并且實現(xiàn)里邊的3個函數(shù)几晤,
  • onCreate(SQLiteDatabase):在數(shù)據(jù)庫第一次生成的時候會調(diào)用這個方法约炎,一般我們在這個方法里邊生成數(shù)據(jù)庫表。 
    
  • onUpgrade(SQLiteDatabase, int, int):當(dāng)數(shù)據(jù)庫需要升級的時候蟹瘾,Android系統(tǒng)會主動的調(diào)用這個方法圾浅。一般我們在這個方法里邊刪除數(shù)據(jù)表,并建立新的數(shù)據(jù)表憾朴,當(dāng)然是否還需要做其他的操作狸捕,完全取決于應(yīng)用的需求。 
    
  • onOpen(SQLiteDatabase):這是當(dāng)打開數(shù)據(jù)庫時的回調(diào)函數(shù)众雷,一般也不會用到灸拍。  
    

*/

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";  

//建立一個內(nèi)部類,主要生成一個數(shù)據(jù)庫   
private static class DatabaseHelper extends SQLiteOpenHelper {  
      
    DatabaseHelper(Context context) {  
        super(context, DATABASE_NAME, null, DATABASE_VERSION);  
    }  

    //在數(shù)據(jù)庫第一次生成的時候會調(diào)用這個方法,一般我們在這個方法里邊生成數(shù)據(jù)庫表砾省。   
    @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();  
        }  
    };  
}  

/* 
 * 重新建立數(shù)據(jù)表 
 */  
private void CreateTable() {  
    //mOpenHelper.getWritableDatabase()語句負(fù)責(zé)得到一個可寫的SQLite數(shù)據(jù)庫鸡岗,如果這個數(shù)據(jù)庫還沒有建立,   
    //那么mOpenHelper輔助類負(fù)責(zé)建立這個數(shù)據(jù)庫编兄。如果數(shù)據(jù)庫已經(jīng)建立轩性,那么直接返回一個可寫的數(shù)據(jù)庫。   
    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("數(shù)據(jù)表成功重建");  
    } catch (SQLException e) {  
        setTitle("數(shù)據(jù)表重建錯誤");  
    }  
}  

/* 
 * 刪除數(shù)據(jù)表 
 */  
private void dropTable() {  
    //mOpenHelper.getWritableDatabase()語句負(fù)責(zé)得到一個可寫的SQLite數(shù)據(jù)庫狠鸳,如果這個數(shù)據(jù)庫還沒有建立揣苏,   
    //那么mOpenHelper輔助類負(fù)責(zé)建立這個數(shù)據(jù)庫。如果數(shù)據(jù)庫已經(jīng)建立碰煌,那么直接返回一個可寫的數(shù)據(jù)庫舒岸。   
    SQLiteDatabase db = mOpenHelper.getWritableDatabase();  
    String sql = "drop table " + TABLE_NAME;  
    try {  
        db.execSQL(sql);  
        setTitle("數(shù)據(jù)表成功刪除:" + sql);  
    } catch (SQLException e) {  
        setTitle("數(shù)據(jù)表刪除錯誤");  
    }  
}  

/* 
 * 插入兩條數(shù)據(jù) 
 */  
private void insertItem() {  
    //mOpenHelper.getWritableDatabase()語句負(fù)責(zé)得到一個可寫的SQLite數(shù)據(jù)庫,如果這個數(shù)據(jù)庫還沒有建立芦圾,   
    //那么mOpenHelper輔助類負(fù)責(zé)建立這個數(shù)據(jù)庫蛾派。如果數(shù)據(jù)庫已經(jīng)建立,那么直接返回一個可寫的數(shù)據(jù)庫个少。   
    SQLiteDatabase db = mOpenHelper.getWritableDatabase();  
    String sql1 = "insert into " + TABLE_NAME + " (" + TITLE + ", " + BODY  
            + ") values('haiyang', 'android的發(fā)展真是迅速啊');";  
    String sql2 = "insert into " + TABLE_NAME + " (" + TITLE + ", " + BODY  
            + ") values('icesky', 'android的發(fā)展真是迅速啊');";  
    try {  
        // Log.i()會將參數(shù)內(nèi)容打印到日志當(dāng)中洪乍,并且打印級別是Info級別   
        // Android支持5種打印級別,分別是Verbose夜焦、Debug壳澳、Info、Warning茫经、Error巷波,當(dāng)然我們在程序當(dāng)中一般用到的是Info級別   
        Log.i("haiyang:sql1=", sql1);  
        Log.i("haiyang:sql2=", sql2);  
        db.execSQL(sql1);  
        db.execSQL(sql2);  
        setTitle("插入兩條數(shù)據(jù)成功");  
    } catch (SQLException e) {  
        setTitle("插入兩條數(shù)據(jù)失敗");  
    }  
}  

/* 
 * 刪除其中的一條數(shù)據(jù) 
 */  
private void deleteItem() {  
    try {  
        //mOpenHelper.getWritableDatabase()語句負(fù)責(zé)得到一個可寫的SQLite數(shù)據(jù)庫萎津,如果這個數(shù)據(jù)庫還沒有建立,   
        //那么mOpenHelper輔助類負(fù)責(zé)建立這個數(shù)據(jù)庫抹镊。如果數(shù)據(jù)庫已經(jīng)建立锉屈,那么直接返回一個可寫的數(shù)據(jù)庫。   
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();  
        //第一個參數(shù)是數(shù)據(jù)庫表名垮耳,在這里是TABLE_NAME颈渊,也就是diary。    
        //第二個參數(shù)终佛,相當(dāng)于SQL語句當(dāng)中的where部分俊嗽,也就是描述了刪除的條件。   
        //如果在第二個參數(shù)當(dāng)中有“铃彰?”符號绍豁,那么第三個參數(shù)中的字符串會依次替換在第二個參數(shù)當(dāng)中出現(xiàn)的“?”符號豌研。    
        db.delete(TABLE_NAME, " title = 'haiyang'", null);  
        setTitle("刪除title為haiyang的一條記錄");  
    } catch (SQLException e) {  

    }  

}  

/* 
 * 在屏幕的title區(qū)域顯示當(dāng)前數(shù)據(jù)表當(dāng)中的數(shù)據(jù)的條數(shù)妹田。 
 */  
/* 
 * Cursor cur = db.query(TABLE_NAME, col, null, null, null, null, null)語句將查詢到的數(shù)據(jù)放到一個Cursor 當(dāng)中。 
    這個Cursor里邊封裝了這個數(shù)據(jù)表TABLE_NAME當(dāng)中的所有條列鹃共。  
    query()方法相當(dāng)?shù)挠杏霉碛叮谶@里我們簡單地講一下。 
        第一個參數(shù)是數(shù)據(jù)庫里邊表的名字霜浴,比如在我們這個例子晶衷,表的名字就是TABLE_NAME,也就是"diary"阴孟。 
        第二個字段是我們想要返回數(shù)據(jù)包含的列的信息晌纫。在這個例子當(dāng)中我們想要得到的列有title、body永丝。我們把這兩個列的名字放到字符串?dāng)?shù)組里邊來锹漱。 
        第三個參數(shù)為selection,相當(dāng)于SQL語句的where部分慕嚷,如果想返回所有的數(shù)據(jù)哥牍,那么就直接置為null。 
        第四個參數(shù)為selectionArgs喝检。在selection部分嗅辣,你有可能用到“?”,那么在selectionArgs定義的字符串會代替selection中的“?”挠说。 
        第五個參數(shù)為groupBy澡谭。定義查詢出來的數(shù)據(jù)是否分組,如果為null則說明不用分組损俭。 
        第六個參數(shù)為having 蛙奖,相當(dāng)于SQL語句當(dāng)中的having部分潘酗。 
        第七個參數(shù)為orderBy,來描述我們期望的返回值是否需要排序外永,如果設(shè)置為null則說明不需要排序崎脉。 
 */  
  
private void showItems() {  

    SQLiteDatabase db = mOpenHelper.getReadableDatabase();  
    String col[] = { TITLE, BODY };  
    //查詢數(shù)據(jù)   
    Cursor cur = db.query(TABLE_NAME, col, null, null, null, null, null);  
    Integer num = cur.getCount();  
    setTitle(Integer.toString(num) + " 條記錄");  
}  

}

[java] view plain copy

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的數(shù)據(jù)庫伯顶,通過SQLiteDatabase實例的一些方法,我們可以執(zhí)行SQL語句骆膝,
  • 對數(shù)據(jù)庫進行增祭衩、刪、查阅签、改的操作掐暮。需要注意的是,數(shù)據(jù)庫對于一個應(yīng)用來說是私有的政钟,并且在一個應(yīng)用當(dāng)中路克,數(shù)據(jù)庫的名字也是惟一的。
    */

/*

  • 什么是SQLiteOpenHelper 养交?
  • 這個類主要生成一個數(shù)據(jù)庫精算,并對數(shù)據(jù)庫的版本進行管理。
  • 當(dāng)在程序當(dāng)中調(diào)用這個類的方法getWritableDatabase()或者getReadableDatabase()方法的時候碎连,如果當(dāng)時沒有數(shù)據(jù)灰羽,那么Android系統(tǒng)就會自動生成一個數(shù)據(jù)庫。
  • SQLiteOpenHelper 是一個抽象類鱼辙,我們通常需要繼承它廉嚼,并且實現(xiàn)里邊的3個函數(shù),
  • onCreate(SQLiteDatabase):在數(shù)據(jù)庫第一次生成的時候會調(diào)用這個方法倒戏,一般我們在這個方法里邊生成數(shù)據(jù)庫表怠噪。 
    
  • onUpgrade(SQLiteDatabase, int, int):當(dāng)數(shù)據(jù)庫需要升級的時候,Android系統(tǒng)會主動的調(diào)用這個方法杜跷。一般我們在這個方法里邊刪除數(shù)據(jù)表傍念,并建立新的數(shù)據(jù)表,當(dāng)然是否還需要做其他的操作葱椭,完全取決于應(yīng)用的需求捂寿。 
    
  • onOpen(SQLiteDatabase):這是當(dāng)打開數(shù)據(jù)庫時的回調(diào)函數(shù),一般也不會用到孵运。  
    

*/

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";  

//建立一個內(nèi)部類,主要生成一個數(shù)據(jù)庫  
private static class DatabaseHelper extends SQLiteOpenHelper {  
      
    DatabaseHelper(Context context) {  
        super(context, DATABASE_NAME, null, DATABASE_VERSION);  
    }  

    //在數(shù)據(jù)庫第一次生成的時候會調(diào)用這個方法秦陋,一般我們在這個方法里邊生成數(shù)據(jù)庫表。  
    @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();  
        }  
    };  
}  

/* 
 * 重新建立數(shù)據(jù)表 
 */  
private void CreateTable() {  
    //mOpenHelper.getWritableDatabase()語句負(fù)責(zé)得到一個可寫的SQLite數(shù)據(jù)庫治笨,如果這個數(shù)據(jù)庫還沒有建立驳概,  
    //那么mOpenHelper輔助類負(fù)責(zé)建立這個數(shù)據(jù)庫赤嚼。如果數(shù)據(jù)庫已經(jīng)建立,那么直接返回一個可寫的數(shù)據(jù)庫顺又。  
    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("數(shù)據(jù)表成功重建");  
    } catch (SQLException e) {  
        setTitle("數(shù)據(jù)表重建錯誤");  
    }  
}  

/* 
 * 刪除數(shù)據(jù)表 
 */  
private void dropTable() {  
    //mOpenHelper.getWritableDatabase()語句負(fù)責(zé)得到一個可寫的SQLite數(shù)據(jù)庫更卒,如果這個數(shù)據(jù)庫還沒有建立,  
    //那么mOpenHelper輔助類負(fù)責(zé)建立這個數(shù)據(jù)庫稚照。如果數(shù)據(jù)庫已經(jīng)建立巷折,那么直接返回一個可寫的數(shù)據(jù)庫。  
    SQLiteDatabase db = mOpenHelper.getWritableDatabase();  
    String sql = "drop table " + TABLE_NAME;  
    try {  
        db.execSQL(sql);  
        setTitle("數(shù)據(jù)表成功刪除:" + sql);  
    } catch (SQLException e) {  
        setTitle("數(shù)據(jù)表刪除錯誤");  
    }  
}  

/* 
 * 插入兩條數(shù)據(jù) 
 */  
private void insertItem() {  
    //mOpenHelper.getWritableDatabase()語句負(fù)責(zé)得到一個可寫的SQLite數(shù)據(jù)庫峻堰,如果這個數(shù)據(jù)庫還沒有建立妨马,  
    //那么mOpenHelper輔助類負(fù)責(zé)建立這個數(shù)據(jù)庫。如果數(shù)據(jù)庫已經(jīng)建立弱恒,那么直接返回一個可寫的數(shù)據(jù)庫辨萍。  
    SQLiteDatabase db = mOpenHelper.getWritableDatabase();  
    String sql1 = "insert into " + TABLE_NAME + " (" + TITLE + ", " + BODY  
            + ") values('haiyang', 'android的發(fā)展真是迅速啊');";  
    String sql2 = "insert into " + TABLE_NAME + " (" + TITLE + ", " + BODY  
            + ") values('icesky', 'android的發(fā)展真是迅速啊');";  
    try {  
        // Log.i()會將參數(shù)內(nèi)容打印到日志當(dāng)中,并且打印級別是Info級別  
        // Android支持5種打印級別返弹,分別是Verbose锈玉、Debug、Info义起、Warning拉背、Error,當(dāng)然我們在程序當(dāng)中一般用到的是Info級別  
        Log.i("haiyang:sql1=", sql1);  
        Log.i("haiyang:sql2=", sql2);  
        db.execSQL(sql1);  
        db.execSQL(sql2);  
        setTitle("插入兩條數(shù)據(jù)成功");  
    } catch (SQLException e) {  
        setTitle("插入兩條數(shù)據(jù)失敗");  
    }  
}  

/* 
 * 刪除其中的一條數(shù)據(jù) 
 */  
private void deleteItem() {  
    try {  
        //mOpenHelper.getWritableDatabase()語句負(fù)責(zé)得到一個可寫的SQLite數(shù)據(jù)庫并扇,如果這個數(shù)據(jù)庫還沒有建立去团,  
        //那么mOpenHelper輔助類負(fù)責(zé)建立這個數(shù)據(jù)庫。如果數(shù)據(jù)庫已經(jīng)建立穷蛹,那么直接返回一個可寫的數(shù)據(jù)庫土陪。  
        SQLiteDatabase db = mOpenHelper.getWritableDatabase();  
        //第一個參數(shù)是數(shù)據(jù)庫表名,在這里是TABLE_NAME肴熏,也就是diary鬼雀。   
        //第二個參數(shù),相當(dāng)于SQL語句當(dāng)中的where部分蛙吏,也就是描述了刪除的條件源哩。  
        //如果在第二個參數(shù)當(dāng)中有“?”符號鸦做,那么第三個參數(shù)中的字符串會依次替換在第二個參數(shù)當(dāng)中出現(xiàn)的“励烦?”符號。   
        db.delete(TABLE_NAME, " title = 'haiyang'", null);  
        setTitle("刪除title為haiyang的一條記錄");  
    } catch (SQLException e) {  

    }  

}  

/* 
 * 在屏幕的title區(qū)域顯示當(dāng)前數(shù)據(jù)表當(dāng)中的數(shù)據(jù)的條數(shù)泼诱。 
 */  
/* 
 * Cursor cur = db.query(TABLE_NAME, col, null, null, null, null, null)語句將查詢到的數(shù)據(jù)放到一個Cursor 當(dāng)中坛掠。 
    這個Cursor里邊封裝了這個數(shù)據(jù)表TABLE_NAME當(dāng)中的所有條列。  
    query()方法相當(dāng)?shù)挠杏茫谶@里我們簡單地講一下屉栓。 
        第一個參數(shù)是數(shù)據(jù)庫里邊表的名字舷蒲,比如在我們這個例子,表的名字就是TABLE_NAME友多,也就是"diary"牲平。 
        第二個字段是我們想要返回數(shù)據(jù)包含的列的信息。在這個例子當(dāng)中我們想要得到的列有title域滥、body纵柿。我們把這兩個列的名字放到字符串?dāng)?shù)組里邊來。 
        第三個參數(shù)為selection骗绕,相當(dāng)于SQL語句的where部分藐窄,如果想返回所有的數(shù)據(jù),那么就直接置為null酬土。 
        第四個參數(shù)為selectionArgs。在selection部分格带,你有可能用到“?”撤缴,那么在selectionArgs定義的字符串會代替selection中的“?”。 
        第五個參數(shù)為groupBy叽唱。定義查詢出來的數(shù)據(jù)是否分組屈呕,如果為null則說明不用分組。 
        第六個參數(shù)為having 棺亭,相當(dāng)于SQL語句當(dāng)中的having部分虎眨。 
        第七個參數(shù)為orderBy,來描述我們期望的返回值是否需要排序镶摘,如果設(shè)置為null則說明不需要排序嗽桩。 
 */  
  
private void showItems() {  

    SQLiteDatabase db = mOpenHelper.getReadableDatabase();  
    String col[] = { TITLE, BODY };  
    //查詢數(shù)據(jù)  
    Cursor cur = db.query(TABLE_NAME, col, null, null, null, null, null);  
    Integer num = cur.getCount();  
    setTitle(Integer.toString(num) + " 條記錄");  
}  

}

四.內(nèi)容提供器(Content provider)方式
在Android的設(shè)計“哲學(xué)”里是鼓勵開發(fā)者使用內(nèi)部類的,這樣不但使用方便凄敢,而且執(zhí)行效率也高碌冶。
1.什么是ContentProvider 數(shù)據(jù)在Android當(dāng)中是私有的,當(dāng)然這些數(shù)據(jù)包括文件數(shù)據(jù)和數(shù)據(jù)庫數(shù)據(jù)以及一些其他類型的數(shù)據(jù)涝缝。難道兩個程序之間就沒有辦法對于數(shù)據(jù)進行交換扑庞?解決這個問題主要靠ContentProvider。 一個Content Provider類實現(xiàn)了一組標(biāo)準(zhǔn)的方法接口拒逮,從而能夠讓其他的應(yīng)用保存或讀取此Content Provider的各種數(shù)據(jù)類型罐氨。也就是說,一個程序可以通過實現(xiàn)一個Content Provider的抽象接口將自己的數(shù)據(jù)暴露出去滩援。外界根本看不到,也不用看到這個應(yīng)用暴露的數(shù)據(jù)在應(yīng)用當(dāng)中是如何存儲的,或者是用數(shù)據(jù)庫存儲還是用文件存儲外傅,還是通過網(wǎng)上獲得冰肴,這些一切都不重要,重要的是外界可以通過這一套標(biāo)準(zhǔn)及統(tǒng)一的接口和程序里的數(shù)據(jù)打交道换可,可以讀取程序的數(shù)據(jù),也可以刪除程序的數(shù)據(jù)浆熔,當(dāng)然祈匙,中間也會涉及一些權(quán)限的問題市埋。 下邊列舉一些較常見的接口,這些接口如下所示恕刘。 query(Uri uri, String[] projection, String selection, String[] selectionArgs,String sortOrder):通過Uri進行查詢腰素,返回一個Cursor。 insert(Uri url, ContentValues values):將一組數(shù)據(jù)插入到Uri 指定的地方雪营。 update(Uri uri, ContentValues values, String where, String[] selectionArgs):更新Uri指定位置的數(shù)據(jù)。 delete(Uri url, String where, String[] selectionArgs):刪除指定Uri并且符合一定條件的數(shù)據(jù)衡便。
2.什么是ContentResolver ** 外界的程序通過ContentResolver接口可以訪問ContentProvider提供的數(shù)據(jù)献起,在Activity當(dāng)中通過getContentResolver()可以得到當(dāng)前應(yīng)用的ContentResolver實例。 ContentResolver提供的接口和ContentProvider中需要實現(xiàn)的接口對應(yīng)镣陕,主要有以下幾個谴餐。 query(Uri uri, String[] projection, String selection, String[] selectionArgs,String sortOrder):通過Uri進行查詢,返回一個Cursor呆抑。 insert(Uri url, ContentValues values):將一組數(shù)據(jù)插入到Uri 指定的地方岂嗓。 update(Uri uri, ContentValues values, String where, String[] selectionArgs):更新Uri指定位置的數(shù)據(jù)。 delete(Uri url, String where, String[] selectionArgs):刪除指定Uri并且符合一定條件的數(shù)據(jù)鹊碍。
** 3.ContentProvider和ContentResolver中用到的Uri
在ContentProvider和ContentResolver當(dāng)中用到了Uri的形式通常有兩種厌殉,一種是指定全部數(shù)據(jù),另一種是指定某個ID的數(shù)據(jù)侈咕。 我們看下面的例子公罕。 content://contacts/people/ 這個Uri指定的就是全部的聯(lián)系人數(shù)據(jù)。 content://contacts/people/1 這個Uri指定的是ID為1的聯(lián)系人的數(shù)據(jù)耀销。
在上邊兩個類中用到的Uri一般由3部分組成楼眷。 第一部分是:"content://" 。 第二部分是要獲得數(shù)據(jù)的一個字符串片段。 最后就是ID(如果沒有指定ID罐柳,那么表示返回全部)掌腰。
由于URI通常比較長,而且有時候容易出錯张吉,且難以理解齿梁。所以,在Android當(dāng)中定義了一些輔助類芦拿,并且定義了一些常量來代替這些長字符串的使用士飒,例如下邊的代碼: Contacts.People.CONTENT_URI (聯(lián)系人的URI)。 1)實現(xiàn)的功能
在這個例子里邊蔗崎,首先在系統(tǒng)的聯(lián)系人應(yīng)用當(dāng)中插入一些聯(lián)系人信息酵幕,然后把這些聯(lián)系人的名字和電話再顯示出來
2)實現(xiàn)方法

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()方法得到應(yīng)用的ContentResolver實例。   
    // query(Phones.CONTENT_URI, null, null, null, null)缓苛。它是ContentResolver里的方法芳撒,負(fù)責(zé)查詢所有聯(lián)系人,并返回一個Cursor未桥。這個方法參數(shù)比較多笔刹,每個參數(shù)的具體含義如下。   
    //·  第一個參數(shù)為Uri冬耿,在這個例子里邊這個Uri是聯(lián)系人的Uri舌菜。   
    //·  第二個參數(shù)是一個字符串的數(shù)組,數(shù)組里邊的每一個字符串都是數(shù)據(jù)表中某一列的名字亦镶,它指定返回數(shù)據(jù)表中那些列的值日月。   
    //·  第三個參數(shù)相當(dāng)于SQL語句的where部分,描述哪些值是我們需要的缤骨。   
    //·  第四個參數(shù)是一個字符串?dāng)?shù)組爱咬,它里邊的值依次代替在第三個參數(shù)中出現(xiàn)的“?”符號。   
    //·  第五個參數(shù)指定了排序的方式绊起。   
    Cursor c = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null);  
    startManagingCursor(c); //讓系統(tǒng)來管理生成的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進行綁定。   
}  

}

[java] view plain copy

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()方法得到應(yīng)用的ContentResolver實例虱歪。  
    // query(Phones.CONTENT_URI, null, null, null, null)蜂绎。它是ContentResolver里的方法,負(fù)責(zé)查詢所有聯(lián)系人实蔽,并返回一個Cursor荡碾。這個方法參數(shù)比較多,每個參數(shù)的具體含義如下局装。  
    //·  第一個參數(shù)為Uri坛吁,在這個例子里邊這個Uri是聯(lián)系人的Uri劳殖。  
    //·  第二個參數(shù)是一個字符串的數(shù)組,數(shù)組里邊的每一個字符串都是數(shù)據(jù)表中某一列的名字拨脉,它指定返回數(shù)據(jù)表中那些列的值哆姻。  
    //·  第三個參數(shù)相當(dāng)于SQL語句的where部分,描述哪些值是我們需要的玫膀。  
    //·  第四個參數(shù)是一個字符串?dāng)?shù)組矛缨,它里邊的值依次代替在第三個參數(shù)中出現(xiàn)的“?”符號。  
    //·  第五個參數(shù)指定了排序的方式帖旨。  
    Cursor c = getContentResolver().query(Phones.CONTENT_URI, null, null, null, null);  
    startManagingCursor(c); //讓系統(tǒng)來管理生成的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進行綁定。  
}  

}

五. 網(wǎng)絡(luò)存儲方式

** 1.例子介紹** 通過郵政編碼查詢該地區(qū)的天氣預(yù)報解阅,以POST發(fā)送的方式發(fā)送請求到webservicex.NET站點落竹,訪問WebService.webservicex.Net站點上提供查詢天氣預(yù)報的服務(wù),具體信息請參考其WSDL文檔货抄,網(wǎng)址為:http://www.webservicex.net/WeatherForecast.asmx?WSDL述召。輸入:美國某個城市的郵政編碼。 輸出:該郵政編碼對應(yīng)城市的天氣預(yù)報蟹地。2.實現(xiàn)步驟如下(1)如果需要訪問外部網(wǎng)絡(luò)积暖,則需要在AndroidManifest.xml文件中加入如下代碼申請權(quán)限許可: <uses-permission Android:name="Android.permission.INTERNET" /> (2)以HTTP POST的方式發(fā)送(注意:SERVER_URL并不是指WSDL的URL,而是服務(wù)本身的URL)怪与。實現(xiàn)的代碼如下所示:private static final String SERVER_URL = "http://www.webservicex.net/WeatherForecast. asmx/GetWeatherByZipCode"; //定義需要獲取的內(nèi)容來源地址HttpPost request = new HttpPost(SERVER_URL); //根據(jù)內(nèi)容來源地址創(chuàng)建一個Http請求// 添加一個變量 List <NameValuePair> params = new ArrayList <NameValuePair>(); // 設(shè)置一個華盛頓區(qū)號params.add(new BasicNameValuePair("ZipCode", "200120")); //添加必須的參數(shù)request.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); //設(shè)置參數(shù)的編碼try { HttpResponse httpResponse = new DefaultHttpClient().execute(request); //發(fā)送請求并獲取反饋// 解析返回的內(nèi)容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)的內(nèi)容夺刑,其返回的內(nèi)容如下:<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>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市分别,隨后出現(xiàn)的幾起案子性誉,更是在濱河造成了極大的恐慌,老刑警劉巖茎杂,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異纫雁,居然都是意外死亡煌往,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門轧邪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來刽脖,“玉大人,你說我怎么就攤上這事忌愚∏埽” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵硕糊,是天一觀的道長院水。 經(jīng)常有香客問我腊徙,道長,這世上最難降的妖魔是什么檬某? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任撬腾,我火速辦了婚禮,結(jié)果婚禮上恢恼,老公的妹妹穿的比我還像新娘民傻。我一直安慰自己,他們只是感情好场斑,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布漓踢。 她就那樣靜靜地躺著,像睡著了一般漏隐。 火紅的嫁衣襯著肌膚如雪喧半。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天锁保,我揣著相機與錄音薯酝,去河邊找鬼。 笑死爽柒,一個胖子當(dāng)著我的面吹牛吴菠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播浩村,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼做葵,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了心墅?” 一聲冷哼從身側(cè)響起酿矢,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎怎燥,沒想到半個月后瘫筐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡铐姚,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年策肝,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片隐绵。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡之众,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出依许,到底是詐尸還是另有隱情棺禾,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布峭跳,位于F島的核電站膘婶,受9級特大地震影響缺前,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜竣付,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一诡延、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧古胆,春花似錦肆良、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至棺牧,卻和暖如春巫糙,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背颊乘。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工参淹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人乏悄。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓浙值,卻偏偏與公主長得像,于是被迫代替她去往敵國和親檩小。 傳聞我的和親對象是個殘疾皇子开呐,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容