編輯:關於Android編程
SQLite是一種輕量級的小型數據庫,雖然比較小,但是功能相對比較完善,一些常見的數據庫基本功能也具有,在現在的嵌入式系統中使用該數據庫的比較多,因為它占用系統資源很少。Android系統中也不例外,也是采用SQLite,本節中就學習下在andorid中怎樣使用該數據庫來存放數據,並且對SQLite完成簡單的新建,更新,查詢,刪除等操作。
實驗說明:
Android中使用SQLite數據庫時,需要用adb來輔助調試,如果想在windows下的cmd命令行中使用adb,必須先配置環境變量,我這裡是配的用戶環境變量path: C:\Program Files\android-sdk\platform-tools;
配置好環境變量後,在cmd中輸入adb shell進入linux shell環境前,需要把android模擬器打開(本文都是針對模擬器而言,並非真機)。如果啟動好了模擬器,且輸入adb shell命令後出現error: device not found錯誤提示,則可以殺掉adb進程然後重新啟動該進程,在cmd中輸入如下命令:
adb kill-server
adb start-server
如果要在android中使用SQLite,一般需要重新寫一個類,而該類繼承一個android提供訪問該數據庫的助手類SQLiteOpenHelper。 本次實驗中我們在src文件夾下新建一個類,類名為DatabaseHelper,該類繼承SQLiteOpenHelper類,而繼承SQLiteOpenHelper類的類必須有自己的構造函數,因此按照mars老師的代碼,在程序中寫了3個構造函數,這3個函數的區別是參數個數的不同,參數個數少的函數是因為另外一些參數已經被固定了,且它們都是顯示或隱式調用了父類的構造函數,下面是SQLiteOpenHelper的構造函數。
public SQLiteOpenHelper (Context context, String name, SQLiteDatabase.CursorFactory factory, int version)
第一個參數為該類本身;第二個參數為數據庫的名字;第3個參數是用來設置游標對象的,這裡一般設置為null;參數四是數據庫的版本號。
public void execSQL (String sql)
該函數是類SQLiteDatabase中的一個函數,其功能是執行一條SQL語句命令,這條語句的內容就是該函數的參數。因此參數sql需要符合SQL語法規則。
public ContentValues ()
ContentValues是用於數據庫中存放數據的類,也是采用的鍵值對來存放數據的,有點類似content和bundle等。該構造函數是建立一個默認大小的空的數據集。
實驗步驟和結果:
界面設計:
該程序的界面設計比較簡單,因為需要完成6中功能,所以在界面中只有6個按鈕,每個按鈕對應一種功能,這些按鈕的功能依次為新建數據庫,更新數據庫的版本,向數據庫中插入記錄,更新數據庫中的記錄,查詢數據庫中的記錄,刪除數據庫中的記錄。其界面效果如下:
建立數據庫:
運行模擬器,單擊create sqlite database按鈕,創建一個名為”tornadomeet”的數據庫,版本號為1,這時候可以看到程序終端顯示”create a sqlite database”字樣。在cmd中輸入如下命令:adb shell;cd data; cd data; ls; cd com.example.sqlite_test; ls;命令,其中com.example.splite是本程序的包名,輸入最後ls命令後可以看到有2個文件夾cache, lib。然後在單擊後繼續ls命令查看,多了一個database文件夾。使用命令cd database進入該文件夾後ls發現裡面有數據庫,截圖如下:
繼續在cmd命令行輸入sqlite3 tornadomeet.db;(其中tornadomeet為單擊創建數據庫後新建立的數據庫名稱。)輸入 .schema;(注意前面有個點)顯示如下:
可以看到這個數據庫有2個表,且可以看到這2個表建立的sqlite語句,其中第一個表示android自帶的,第二個表示我們新建的。
繼續輸入命令select * from user1;(注意此時因為是真正的sqlite語句,所以在命令行中要以分號結束)查詢自己建立的數據庫中的表user1,發現裡面什麼內容都沒有。
更新數據庫版本:
在該步驟中,當按下update sqlite database按鈕後,我們在監聽器函數中新建了一個數據庫,數據庫名為”tornadomeet”不變,只是將其版本號設置為了2。因為版本號變了,所以程序會自動去調用SQLiteOpenHelper的子類的onUpgrade方法,該程序中只是在該方法中輸出一條語句而已。
數據庫插入:
單擊模擬器的insert按鈕,進入sqlite對應的數據庫後,輸入select * from user1;命令後(帶分號)可以看到有如下顯示:1 | tornado,說明我們的數據庫成功插入了一條記錄,該記錄的內容是在程序中靜態給的。
更新數據庫內容:
更新操作相當於執行SQL的UPDATE語句,語法為:UPDATE table_name SET ###col =###1 WHERE ###col = ###2
本程序將上面插入的一條記錄的name名有tornado改為了tornadomeet,所以當按下update按鈕後,重新在cmd使用select * from user1可以看出那條記錄變成了1 | tornadomeet了。
查詢操作:
查詢操作使用SQLiteOpenHelper中的query方法,這裡的查詢是指按照列名name去查詢的,實際查詢過程中是有一個游標,開始時指向表頭,後面一次一次往下移,直到滿足查詢的條件時就輸出,然後終止查詢。
刪除操作:
刪除操作與前面的類似,使用SQLiteOpenHelper中的delete方法,按照指定列名為某一值,然後刪除那條記錄即可。
下面是在依次單擊新建一個SQLite數據庫按鈕,插入記錄按鈕,更新記錄按鈕,再次插入記錄按鈕,刪除按鈕後adb後台調試的結果:
由此可以看出,刪除操作也是成功的。
實驗主要部分代碼及注釋(附錄有實驗工程code下載鏈接):
復制代碼 代碼如下:
package com.example.sqlite_test;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private Button create_database = null;
private Button update_database = null;
private Button insert = null;
private Button update = null;
private Button query = null;
private Button delete = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
create_database = (Button)findViewById(R.id.create_database);
create_database.setOnClickListener(new CreateDatabaseOnClickListener());
update_database = (Button)findViewById(R.id.update_database);
update_database.setOnClickListener(new UpdateDatabaseOnClickListener());
insert = (Button)findViewById(R.id.insert);
insert.setOnClickListener(new InsertOnClickListener());
update = (Button)findViewById(R.id.update);
update.setOnClickListener(new UpdateOnClickListener());
query = (Button)findViewById(R.id.query);
query.setOnClickListener(new QueryOnClickListener());
delete = (Button)findViewById(R.id.delete);
delete.setOnClickListener(new DeleteOnClickListener());
}
public class CreateDatabaseOnClickListener implements OnClickListener{
public void onClick(View v) {
// TODO Auto-generated method stub
//創建一個DatabaseHelper類的對象,該類是單獨一個java文件,這裡采用2個參數的構造函數,建立的數據
//庫的名字為tornadomeet.db
DatabaseHelper database_helper = new DatabaseHelper(MainActivity.this, "tornadomeet.db");
//只有調用getReadableDatabase()或者getWriteableDatabase()函數後才能返回一個SQLiteDatabase對象
SQLiteDatabase db = database_helper.getReadableDatabase();
}
}
public class UpdateDatabaseOnClickListener implements OnClickListener{
public void onClick(View v) {
// TODO Auto-generated method stub
DatabaseHelper database_helper = new DatabaseHelper(MainActivity.this, "tornadomeet.db", 2);
SQLiteDatabase db = database_helper.getReadableDatabase();
}
}
public class InsertOnClickListener implements OnClickListener{
public void onClick(View v) {
// 生成contentvallues對象,該對象用來存數據的
ContentValues values = new ContentValues();
values.put("id", 1);//注意值的類型要匹配
values.put("name", "tornado");
DatabaseHelper database_helper = new DatabaseHelper(MainActivity.this, "tornadomeet.db");
SQLiteDatabase db = database_helper.getWritableDatabase();//這裡是獲得可寫的數據庫
db.insert("user1", null, values);
}
}
public class UpdateOnClickListener implements OnClickListener{
public void onClick(View v) {
// TODO Auto-generated method stub
DatabaseHelper database_helper = new DatabaseHelper(MainActivity.this, "tornadomeet.db");
SQLiteDatabase db = database_helper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", "tornadomeet");
//參數1為表名,參數2為更新後的值,參數3表示滿足條件的列名稱,參數4為該列名下的值
db.update("user1", values, "id=?", new String[]{"1"});
}
}
public class QueryOnClickListener implements OnClickListener{
public void onClick(View v) {
// TODO Auto-generated method stub
DatabaseHelper database_helper = new DatabaseHelper(MainActivity.this, "tornadomeet.db");
SQLiteDatabase db = database_helper.getWritableDatabase();
//查詢的語法,參數1為表名;參數2為表中的列名;參數3為要查詢的列名;參數時為對應列的值;該函數返回的是一個游標
Cursor cursor = db.query("user1", new String[]{"id", "name"}, "id=?", new String[]{"1"}, null, null, null);
//遍歷每一個記錄
while(cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex("name"));//返回列名為name的值
System.out.println("query---->" + name);
}
}
}
public class DeleteOnClickListener implements OnClickListener{
public void onClick(View v) {
// TODO Auto-generated method stub
DatabaseHelper database_helper = new DatabaseHelper(MainActivity.this, "tornadomeet.db");
SQLiteDatabase db = database_helper.getWritableDatabase();
//直接刪除名為tornadomeet對應的那條記錄
db.delete("user1", "name=?" ,new String[]{"tornadomeet"});
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
DatabaseHelper.java:
復制代碼 代碼如下:
package com.example.sqlite_test;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper {
private static final int VERSON = 1;//默認的數據庫版本
//繼承SQLiteOpenHelper類的類必須有自己的構造函數
//該構造函數4個參數,直接調用父類的構造函數。其中第一個參數為該類本身;第二個參數為數據庫的名字;
//第3個參數是用來設置游標對象的,這裡一般設置為null;參數四是數據庫的版本號。
public DatabaseHelper(Context context, String name, CursorFactory factory, int verson){
super(context, name, factory, verson);
}
//該構造函數有3個參數,因為它把上面函數的第3個參數固定為null了
public DatabaseHelper(Context context, String name, int verson){
this(context, name, null, verson);
}
//該構造函數只有2個參數,在上面函數 的基礎山將版本號固定了
public DatabaseHelper(Context context, String name){
this(context, name, VERSON);
}
//該函數在數據庫第一次被建立時調用
@Override
public void onCreate(SQLiteDatabase arg0) {
// TODO Auto-generated method stub
System.out.println("create a sqlite database");
//execSQL()為執行參數裡面的SQL語句,因此參數中的語句需要符合SQL語法,這裡是創建一個表
arg0.execSQL("create table user1(id int, name varchar(20))");
}
@Override
public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
// TODO Auto-generated method stub
System.out.println("update a sqlite database");
}
}
activity_main.xml:
復制代碼 代碼如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<Button
android:id="@+id/create_database"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="@string/create_database"
/>
<Button
android:id="@+id/update_database"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="@id/create_database"
android:layout_alignParentLeft="true"
android:text="@string/update_database" />
<Button
android:id="@+id/insert"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="@id/update_database"
android:layout_alignParentLeft="true"
android:text="@string/insert" />
<Button
android:id="@+id/update"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_above="@id/insert"
android:layout_alignParentLeft="true"
android:text="@string/update" />
<Button
android:id="@+id/query"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_above="@id/update"
android:text="@string/query"
/>
<Button
android:id="@+id/delete"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_above="@id/query"
android:text="@string/delete"
/>
</RelativeLayout>
總結: 通過本次實驗,對SQLite在andorid中的使用流程有了初步的了解。
附錄:
實驗工程code下載
類加載流程在周志明寫的<<深入理解java虛擬機的一本書中>>已經詳細地介紹java加載類過程,在HotSpot虛擬機實現中是通過雙親委派機制來加
首先呈上效果圖當今APP,哪個沒有點滑動刷新功能,簡直就太落伍了。正因為需求多,因此自然而然開源的也就多。但是若想引用開源庫,則很麻煩,比如PullToRefreshVi
由於android系統中應用程序之間不能共享內存。因此,在不同應用程序之間交互數據(跨進程通訊)就稍微麻煩一些。在android SDK中提供了4種用於跨進程通訊的方式。
如果你在開發過程中經常使用 RadioGroup,那你是否遇到過下面這種情況每當你點擊EditText彈出輸入法時,RadioGroup總是向上移動到輸入法的上面。你可能