編輯:關於android開發
前幾天學習了Android中的數據存儲,包括文件存儲,SharedPreferences存儲,還有就是Acndroid中的特色:SQLite數據庫存儲了。讓我比較驚訝的是Android中竟然內嵌了一個輕量型的數據庫SQLite數據庫,使得本地的數據持久化有了一個質的飛躍。
通過前兩天上課聽老師講解,和課下自己看書總結,想在博客上把自己對於SQLite數據庫的理解做一下總結,也是方便之後的復習。Android為了讓我們能夠更加方便的管理數據庫,專門提供了SQLiteOpenHelper幫助類,這個類是一個抽象類,在這個類中,有兩個抽象方法,一個是onCreate(),一個是onUpdate(),我們必須在自己的幫助類中繼承SQLiteOpenHelper,並實現這兩個抽象方法,並分別在這兩個抽象方法中完成表的創建和數據庫的更新和維護。SQLiteOpenHelper中還有兩個非常重要的實例方法,getReadableDatabase()和getWriteableDatabase()。這兩個方法都可以打開或創建一個現有的數據庫(若數據庫已經存在久直接打開,否則創建一個新的數據庫),並返回一個可對數據庫進行操作的對象。不同的是,當數據庫不可以寫入的時候(如磁盤空間已滿),getReadableDatabase()方法返回的對象以只讀的方式打開數據庫,而getWriteableDatabase()方法出現異常(正如常常情況下使用二者獲得的對象都具有讀寫功能)。SQLiteOpenHelper有兩個構造方法可以重寫,這裡我們選擇參數少的那一個。這個構造方法裡面接收4個參數,第一個參數Context,這個沒什麼好說的,代表上下文,必須要有它才能對數據庫進行操作;第二個參數是數據庫名,他代表我們將要創建的數據庫的名字;第三個參數允許我們創建數據庫的時候返回一個自定義的Curs o r,一般都是傳入nu ll;第四個參數代表當前數據庫的版本號,可以用於數據庫升級操作
構建出SQLiteOpenHelper實例後,再調用它的getReadableDatabase()或著getWriteableDatabase()方法就可以創建出數據庫了,數據庫文件會存放在/data/data/<package name >/databases目錄下。此時重寫的onCreate方法也會執行,通常在裡面完成一些表的創建操作。
SQLite數據庫不像其他數據庫擁有眾多繁雜的數據類型,它的常用的數據類型很簡單:integer代型,real代表浮點型,text代表文本型,blob代表二進制類型。
由於創建好的數據庫雖然能在File Explorer中看到, 但卻不能看到其內部包含的表,還有表中的數據,所以我們在這裡使用adb shell來查看,使用adb shell需要配置adb的環境變量在這裡不再敘述,網上有簡單的教程。配置好環境變量後,Win+R中輸入cmd進入命令提示符模式,輸入adb shell進入adb環境,然後輸入命令:cd /data/data/<package name >/databases進入到該目錄下,輸入ls來查看目錄下的文件,此時輸入sqlite3+數據庫名即進入sql編輯模式。鍵入.table可以查看數據庫中有哪些表,鍵入.schema命令可以查看建表語句。(在sqlite編輯模式下每句語句後面都要有';'結束)。下面通過一個小Demo來講解SQLi te數據庫中的CRUD操作以及數據庫的一些其他需要注意的地方。
首先創建我們自己的SQLOpenHelper類繼承自SQLiteOpenHelper,並重寫其中的方法和構造函數:
1 package com.example.databasetest; 2 3 import android.content.Context; 4 import android.database.sqlite.SQLiteDatabase; 5 import android.database.sqlite.SQLiteDatabase.CursorFactory; 6 import android.database.sqlite.SQLiteOpenHelper; 7 8 public class SqlOpenHelper extends SQLiteOpenHelper { 9 10 public static final String CREATE_BOOK = "create table book(" 11 + "id integer primary key autoincrement, " 12 + "name text," 13 + "price real)"; 14 public SqlOpenHelper(Context context, String name, CursorFactory factory, 15 int version) { 16 super(context, name, factory, version); 17 // TODO Auto-generated constructor stub 18 } 19 20 @Override 21 public void onCreate(SQLiteDatabase db) { 22 // TODO Auto-generated method stub 23 db.execSQL(CREATE_BOOK); 24 } 25 26 @Override 27 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 28 // TODO Auto-generated method stub 29 } 30 } 31 32 }
可以看到我們在重寫的onreate方法中調用SQLiteDatbas的execSQL()方法建了一個表book
然後在我們的主界面中添加了四個按鈕,用於創建數據庫病完成CRUD操作:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" 6 > 7 8 <Button 9 android:id="@+id/btn1" 10 android:layout_width="match_parent" 11 android:layout_height="wrap_content" 12 android:text="CREATE_BOOK"/> 13 <Button 14 android:id="@+id/btn2" 15 android:layout_width="match_parent" 16 android:layout_height="wrap_content" 17 android:text="update"/> 18 <Button 19 android:id="@+id/btn3" 20 android:layout_width="match_parent" 21 android:layout_height="wrap_content" 22 android:text="delete"/> 23 <Button 24 android:id="@+id/btn4" 25 android:layout_width="match_parent" 26 android:layout_height="wrap_content" 27 android:text="select"/> 28 </LinearLayout> activity_main我們在MainActivity中注冊並實例化了四個按鈕,並注冊按鈕的監聽事件:
1 1 package com.example.databasetest; 2 2 3 3 import android.app.Activity; 4 4 import android.content.ContentValues; 5 5 import android.database.Cursor; 6 6 import android.database.sqlite.SQLiteDatabase; 7 7 import android.os.Bundle; 8 8 import android.util.Log; 9 9 import android.view.View; 10 10 import android.view.View.OnClickListener; 11 11 import android.widget.Button; 12 12 import android.widget.Toast; 13 13 14 14 public class MainActivity extends Activity implements OnClickListener { 15 15 16 16 private Button btn1,btn2,btn3,btn4; 17 17 private SqlOpenHelper helper; 18 18 private SQLiteDatabase db; 19 19 @Override 20 20 protected void onCreate(Bundle savedInstanceState) { 21 21 super.onCreate(savedInstanceState); 22 22 setContentView(R.layout.activity_main); 23 23 helper=new SqlOpenHelper(this, "book_store", null, 1); 24 24 btn1=(Button) findViewById(R.id.btn1); 25 25 btn2=(Button) findViewById(R.id.btn2); 26 26 btn3=(Button) findViewById(R.id.btn3); 27 27 btn4=(Button) findViewById(R.id.btn4); 28 28 btn1.setOnClickListener(this); 29 29 btn2.setOnClickListener(this); 30 30 btn3.setOnClickListener(this); 31 31 btn4.setOnClickListener(this); 32 32 } 33 33 34 34 35 35 @Override 36 36 public void onClick(View v) { 37 37 // TODO Auto-generated method stub 38 38 switch (v.getId()) { 39 39 case R.id.btn1: 40 40 db = helper.getWritableDatabase(); 41 41 db.beginTransaction(); //開始事務 42 42 try { 43 43 ContentValues values=new ContentValues(); 44 44 values.put("name", "Android"); 45 45 values.put("price", 16.5); 46 46 values.put("category_id", "1"); 47 47 db.insert("book", null, values); 48 48 db.setTransactionSuccessful(); //事務已經成功執行 49 49 Toast.makeText(this, "Create Success", Toast.LENGTH_SHORT).show(); 50 50 } catch (Exception e) { 51 51 // TODO Auto-generated catch block 52 52 e.printStackTrace(); 53 53 }finally{ 54 54 db.endTransaction(); //結束事務 55 55 db.close(); 56 56 } 57 57 break; 58 58 case R.id.btn2: 59 59 db=helper.getWritableDatabase(); 60 60 ContentValues values=new ContentValues(); 61 61 values.put("name", "zhangsan"); 62 62 values.put("price", 20); 63 63 db.update("book", values, "id=?", new String[]{5+""}); 64 64 break; 65 65 case R.id.btn3: 66 66 db=helper.getWritableDatabase(); 67 67 db.delete("book", "id=?",new String[]{1+""} ); 68 68 break; 69 69 case R.id.btn4: 70 70 db=helper.getWritableDatabase(); 71 71 Cursor cursor=db.query("book", null, null, null, null, null, "id DESC"); 72 72 while(cursor.moveToNext()){ 73 73 String name=cursor.getString(cursor.getColumnIndex("name")); 74 74 String price=String.valueOf(cursor.getFloat(2)); 75 75 Log.d("MainActivity", name); 76 76 Log.d("MainActivity", price); 77 77 } 78 78 break; 79 79 default: 80 80 break; 81 81 } 82 82 } 83 83 84 84 }
其中btn1代表創建數據庫並向數據庫中添加數據,btn2的點擊事件是向數據庫中更新數據,btn3則是刪除操作,btn4是最為復雜的查詢操作。
在向表中插入數據的時候,用到了事務,事務中的操作是要麼都做,要麼都不做,可以保證數據的正確。在每次操作數據庫前,先使用我們自定義的幫助類的getWriteableDatabase()來打開(創建)數據庫,並返回一個SQLiteDatabase類型的可操作對象。
添加數據:
調用SQLiteDatabase的insert方法,我們使用方法中有三個參數的那個就可以,第一個參數代表要操作的數據庫表名,第二個參數表示哪列的值為空,一般填null,第三個參數則表示要插入的數據,是為ContentValues類型,ContentValues類型的變量有一個put方法,可以將數據以鍵-值對的形式存儲。
更新數據:
SQLiteDatabase.update方法,我們使用有四個參數的方法,第一個參數還是代表我們要操作的數據庫,第二個參數是要更新的值,為ContentValues類型,還是通過他的put方法來將要更新的值以鍵-值對的形式存儲,第三個參數是相當於where條件,它跟第四個參數以占位符的方式來組成where條件,控制更新哪些滿足條件的行。如:
db.update("book", values, "id=?", new String[]{5+""}); id=? 第四個參數中的值則為'?'部分內容
若這兩個參數填null,則更新所有行。該方法返回一個整型結果,為受影響行數。
刪除數據:
SQLiteDatabase.delete方法,該方法有三個參數,第一個參數是代表我們要操作的數據庫,第二個第三個參數與update中的基本一樣,不在敘述。
查詢數據:
也是數據庫中最為復雜的一種操作,在此只簡單地說下其用法,數據庫的查詢方法返回一個Cursor類型變量,我們通過Cursor的moveToNext方法來取出查詢結果。查詢有好多種寫法可以使用,比如本Demo中的SQLiteDatabase.query方法,接收7個參數,不過我們不用擔心,我們先不去管這些參數,只用第一個參數:要查詢的表。和最後一個參數:按照id降序排列。然後再一個while循環中通過Cursor.getString()將值取出來。此方法的7個參數含義如下:
使用上面的方法來操作數據庫得益於Android給我們提供的方便的API,這樣即使我們不太懂SQL語言,也可以做出操作數據庫的操作,但其實我們還可以使用SQL方式來操作數據庫:
添加數據的方法:
db.execSQL("insert into book(name,price) values("haha",23)"); //sql語句方式
db.execSQL("insert into book(name,price) values(?,?)",new String[]{"haha",34}); //占位符的方式
更新數據:
db.execSQL("update book set name=? where id=?",new String[]{"pig",2+""});
刪除數據:
db.execSQL("delete from book where id>?",new String[]{"3"});
查詢數據:
db.rawQuery("select * from book",null); //第二個參數是查詢條件
計時器(Chronometer)的使用,計時器chronometer安卓提供了一個計時器組件:Chronometer,該組件extends TextView,因此都會顯示
Android 手機衛士10--應用管理器,android10-- 1.添加不同類型條目 1 class MyAdapter extends BaseAdapter{
Android,androidstudio當我們自定義View的時候,在給View賦值一些長度寬度的時候,一般都是在layout布局文件中進行的。,比如android:l
android ListView的介紹和優化,androidlistviewxml設計 <?xml version=1.0?> -<RelativeL