主要經過流來完成java
獲得輸出流對象FileOutputStream:經過Context的openFileOuput("文件名",模式)方法獲取android
文件路徑:/data/data/<包名>/files/ 存放在這個目錄下
模式有二:Activity.MODE_PRIVATE覆蓋;Activity.MODE_APPEND——追加程序員
獲得輸入流對象FileInputStream:經過Context的openFileInput("文件名")返回一個輸入流對象sql
會自動在路徑:/data/data/<包名>/files/ 下找到要讀取的文件名shell
接下來的操做即爲java的IO操做技術!數據庫
貼入一段小代碼app
1 package com.example.filepersistencetest; 2 3 import java.io.BufferedReader; 4 import java.io.BufferedWriter; 5 import java.io.FileInputStream; 6 import java.io.FileOutputStream; 7 import java.io.InputStreamReader; 8 import java.io.OutputStreamWriter; 9 10 import android.app.Activity; 11 import android.os.Bundle; 12 import android.util.Log; 13 import android.view.View; 14 import android.view.View.OnClickListener; 15 import android.widget.Button; 16 import android.widget.EditText; 17 18 public class MainActivity extends Activity implements OnClickListener { 19 private EditText editText; 20 private Button sava_button; 21 private Button read_button; 22 23 @Override 24 protected void onCreate(Bundle savedInstanceState) { 25 super.onCreate(savedInstanceState); 26 setContentView(R.layout.activity_main); 27 editText = (EditText) findViewById(R.id.edit); 28 sava_button = (Button) findViewById(R.id.save); 29 read_button = (Button) findViewById(R.id.read); 30 31 // 綁定單擊事件 32 sava_button.setOnClickListener(this); 33 read_button.setOnClickListener(this); 34 35 } 36 37 @Override 38 public void onClick(View v) { 39 // 監聽 40 switch (v.getId()) { 41 case R.id.save: 42 save(); 43 break; 44 case R.id.read: 45 read(); 46 break; 47 48 default: 49 break; 50 } 51 52 } 53 54 public void save() { 55 String inputText = editText.getText().toString(); 56 BufferedWriter bufw = null; 57 FileOutputStream out = null; 58 // 獲得輸出流 Context->openFileOutput("文件名",寫出模式——覆蓋Private或者追加append) 59 // 返回FileOutputStream對象 60 try { 61 62 out = openFileOutput("my_data.txt", Activity.MODE_PRIVATE); 63 bufw = new BufferedWriter(new OutputStreamWriter(out)); 64 bufw.write(inputText); 65 Log.d("test", inputText); 66 bufw.flush(); 67 editText.setText(""); 68 } catch (Exception e) { 69 throw new RuntimeException("打開文件異常!!"); 70 } finally { 71 try { 72 if (null != bufw) 73 bufw.close(); 74 } catch (Exception e2) { 75 throw new RuntimeException("關閉流失敗"); 76 } 77 } 78 } 79 80 public void read() { 81 editText.setText(""); 82 FileInputStream in = null; 83 BufferedReader bur = null; 84 try { 85 in = openFileInput("my_data.txt"); 86 bur = new BufferedReader(new InputStreamReader(in)); 87 String line = null; 88 boolean flag = false; 89 while ((line = bur.readLine()) != null) { 90 if (flag) 91 editText.append("\n" + line);// 92 else { 93 editText.append(line); 94 flag=true; 95 } 96 } 97 } catch (Exception e) { 98 // TODO: handle exception 99 } finally { 100 try { 101 bur.close(); 102 } catch (Exception e2) { 103 // TODO: handle exception 104 } 105 } 106 107 } 108 109 }
另外補充兩點編輯器
a.TextUtils.isEmpty(inputText)——文本工具類,雙重判空
b.edit.setSelection(inputText.length())——設置光標到末尾ide
文件操做方式有點相似於無腦讀,無腦寫工具
而SharedPreferences則將數據分類的比較好,能夠作到存什麼類型就讀什麼類型,以鍵值對的方式存儲
一般映射關係簡單的時候,用SharedPreferences是比較合適的
存儲路徑:/data/data/<packagename>/shared_prefs/目錄下
A.獲取SharedPreferences,三種方法
a.Context 的 getSharedPreferences("文件名",模式)——若是指定的文件不存在,則會自動建立
MODE_PRIVATE(=0,默認,只有當前應用程序能夠訪問)
MODE_MULTI_PROCESS,用於多個進程多同一個SharedPreferences進行訪問
b.Activity 的 getPreferences(模式) 會自動將當前活動的類名做爲SharedPreferences文件名
c.PreferenceManager 的 靜態getDefaultSharedPreferences(Context)——自動使用當前應用程序名稱做爲文件名的前綴
B.寫
a.得到編輯器 經過SharedPreferences對象的edit()方法獲取一個SharedPreferences.Editor對象
b.經過編輯器寫數據 putBoolean putString ==
c.提交 commit()
代碼示例:
1 saveButton.setOnClickListener(new OnClickListener() { 2 3 @Override 4 public void onClick(View v) { 5 // Context獲取SharedPreferences對象,建立編輯器 6 SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit(); 7 // put內容 8 editor.putString("name", "二哥"); 9 editor.putInt("age", 22); 10 editor.putBoolean("married", false); 11 // 提交 12 editor.commit(); 13 } 14 });
1 getButton.setOnClickListener(new OnClickListener() { 2 3 @Override 4 public void onClick(View v) { 5 SharedPreferences pref = getSharedPreferences("data", MODE_PRIVATE); 6 String name = pref.getString("name", "null"); 7 int age = pref.getInt("age", 0); 8 boolean married = pref.getBoolean("married", false); 9 10 Toast.makeText(MainActivity.this, name+"::"+age+"::"+married, Toast.LENGTH_LONG).show(); 11 } 12 });
記住密碼功能實現——參看BroadcastBestPractice
a.定義一個控制器ActivityController管理全部的活動:包括增長,移除活動和銷燬全部活動,經過一個List承載
1 package com.example.broadcastbestpractic; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import android.app.Activity; 7 8 /** 9 * 活動控制器 10 * 1.添加活動 11 * 2.刪除活動 12 * 3.銷燬全部活動 13 */ 14 public class ActivityController { 15 public static List<Activity> activities = new ArrayList<Activity>(); 16 public static void addActivity(Activity activity ){ 17 activities.add(activity); 18 } 19 public static void removeActivity(Activity activity ){ 20 21 activities.remove(activity); 22 } 23 public static void finishAll(){ 24 for(Activity activity:activities){ 25 activity.finish(); 26 } 27 } 28 }
b.定義一個基類繼承Activity,改類的onCreate和onDestory方法分別實現增長和移除活動
1 package com.example.broadcastbestpractic; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 6 public class BaseActivity extends Activity { 7 8 @Override 9 protected void onCreate(Bundle savedInstanceState) { 10 // TODO Auto-generated method stub 11 super.onCreate(savedInstanceState); 12 ActivityController.addActivity(this); 13 } 14 15 @Override 16 protected void onDestroy() { 17 // TODO Auto-generated method stub 18 super.onDestroy(); 19 ActivityController.removeActivity(this); 20 } 21 22 }
c.主界面MainActivity,具備Button,用於發送強制下線廣播
1 <RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin" 6 android:paddingLeft="@dimen/activity_horizontal_margin" 7 android:paddingRight="@dimen/activity_horizontal_margin" 8 android:paddingTop="@dimen/activity_vertical_margin" 9 tools:context="com.example.broadcastbestpractic.MainActivity" > 10 11 <Button 12 android:id="@+id/force_offline" 13 android:layout_width="match_parent" 14 android:layout_height="wrap_content" 15 android:text="Send a force offline broadcast" 16 android:gravity="center" 17 /> 18 19 </RelativeLayout>
1 package com.example.broadcastbestpractic; 2 3 import android.app.Activity; 4 import android.content.Intent; 5 import android.os.Bundle; 6 import android.view.View; 7 import android.view.View.OnClickListener; 8 import android.widget.Button; 9 10 11 public class MainActivity extends Activity { 12 13 @Override 14 protected void onCreate(Bundle savedInstanceState) { 15 super.onCreate(savedInstanceState); 16 setContentView(R.layout.activity_main); 17 18 Button offLine_btn = (Button) findViewById(R.id.force_offline); 19 offLine_btn.setOnClickListener(new OnClickListener() { 20 21 @Override 22 public void onClick(View v) { 23 // 發送輕質下線廣播 24 Intent intent = new Intent("com.example.broadcastbestpractic.FORCE_OFFLINE"); 25 26 sendBroadcast(intent); 27 28 } 29 }); 30 } 31 32 }
d.登陸界面LoginActivity,登陸成功則跳轉至主界面
1 <?xml version="1.0" encoding="utf-8"?> 2 <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:stretchColumns="1" 6 > 7 8 <TableRow > 9 <TextView 10 android:layout_height="wrap_content" 11 android:text="Account:" 12 /> 13 <EditText 14 android:id="@+id/account" 15 android:layout_height="wrap_content" 16 android:hint="admin 123456" 17 /> 18 </TableRow> 19 20 <TableRow > 21 <TextView 22 android:layout_height="wrap_content" 23 android:text="Password:" 24 /> 25 <EditText 26 android:id="@+id/password" 27 android:layout_height="wrap_content" 28 android:inputType="textPassword" 29 /> 30 </TableRow> 31 <TableRow > 32 <CheckBox 33 android:id="@+id/remember_pass" 34 android:layout_height="wrap_content" 35 android:layout_gravity="right" 36 android:layout_marginRight="10dp" 37 /> 38 <TextView 39 android:layout_height="wrap_content" 40 android:layout_gravity="center_vertical" 41 android:text="Remenbered password" 42 /> 43 </TableRow> 44 <TableRow > 45 <Button 46 android:id="@+id/login" 47 android:text="login" 48 android:layout_span="2" 49 /> 50 51 </TableRow> 52 53 </TableLayout>
1 package com.example.broadcastbestpractic; 2 3 import android.content.Intent; 4 import android.content.SharedPreferences; 5 import android.os.Bundle; 6 import android.view.View; 7 import android.view.View.OnClickListener; 8 import android.widget.Button; 9 import android.widget.CheckBox; 10 import android.widget.EditText; 11 import android.widget.Toast; 12 13 public class LoginActivity extends BaseActivity { 14 private EditText accoutnEdit; 15 private EditText passwordEdit; 16 private Button loginButton; 17 private CheckBox rememberBox; 18 19 20 private SharedPreferences pref; 21 private SharedPreferences.Editor editor; 22 @Override 23 protected void onCreate(Bundle savedInstanceState) { 24 super.onCreate(savedInstanceState); 25 26 setContentView(R.layout.login); 27 28 loginButton = (Button) findViewById(R.id.login); 29 accoutnEdit = (EditText) findViewById(R.id.account); 30 passwordEdit = (EditText) findViewById(R.id.password); 31 rememberBox = (CheckBox) findViewById(R.id.remember_pass); 32 33 /* 在登陸界面建立的時候,先讀取xml文件,看複選框的值是否爲true 34 * 若是爲true,複選框狀態改成true,帳號密碼的內容設置爲xml文件的帳號密碼 35 * 不爲true,則無論 36 */ 37 // 獲取checkbox的值 38 pref = getSharedPreferences("data", MODE_PRIVATE); 39 Boolean isRemember = pref.getBoolean("isRemember", false); 40 41 if(isRemember){ 42 accoutnEdit.setText(pref.getString("account", "")); 43 passwordEdit.setText(pref.getString("password", "")); 44 45 // 注意設置選中的語句爲 setChecked(true) 46 rememberBox.setChecked(true); 47 } 48 49 loginButton.setOnClickListener(new OnClickListener() { 50 51 @Override 52 public void onClick(View v) { 53 // 驗證成功則跳轉至主界面,失敗者提示帳號密碼不正確 54 if("admin".equals(accoutnEdit.getText().toString())&&"123456".equals(passwordEdit.getText().toString())){ 55 // 記錄帳號 56 editor = getSharedPreferences("data", MODE_PRIVATE).edit(); 57 // 若是選中,則上傳 58 if(rememberBox.isChecked()){ 59 editor.putBoolean("isRemember", true); 60 editor.putString("account", "admin"); 61 editor.putString("password", "123456"); 62 63 }else { 64 // 若是未選中,則清除,若是不清除,依然會記住密碼 65 // 可用的方案二是,若是不清除,能夠吧isRemember這個值設置爲false,就不用大範圍清空數據 66 editor.clear(); 67 } 68 editor.commit(); 69 70 Intent intent = new Intent(LoginActivity.this,MainActivity.class); 71 72 startActivity(intent); 73 }else { 74 Toast.makeText(LoginActivity.this, "account or password is not corret", Toast.LENGTH_SHORT).show(); 75 } 76 77 } 78 }); 79 } 80 }
e.靜態廣播接收器,用於接收強制下線廣播,收到後銷燬全部活動,彈出AlertDialog,提示從新登陸
1 package com.example.broadcastbestpractic; 2 3 import android.app.AlertDialog; 4 import android.content.BroadcastReceiver; 5 import android.content.Context; 6 import android.content.DialogInterface; 7 import android.content.DialogInterface.OnClickListener; 8 import android.content.Intent; 9 import android.view.WindowManager; 10 /** 11 * 12 * 靜態註冊一個廣播接收器,用於銷燬活動和開啓活動 13 */ 14 public class OfflineReceiver extends BroadcastReceiver { 15 16 @Override 17 public void onReceive(final Context context, Intent intent) { 18 // 銷燬活動 19 ActivityController.finishAll(); 20 // 彈出對話框 21 AlertDialog.Builder alerBuilder = new AlertDialog.Builder(context); 22 alerBuilder.setTitle("Warnning!"); 23 alerBuilder.setMessage("You are forced line , plese try to login agin."); 24 alerBuilder.setCancelable(false); 25 alerBuilder.setPositiveButton("OK", new OnClickListener() { 26 27 @Override 28 public void onClick(DialogInterface dialog, int which) { 29 // 銷燬全部活動 30 ActivityController.finishAll(); 31 // 重啓登陸 32 Intent intent = new Intent(context, LoginActivity.class); 33 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 34 context.startActivity(intent); 35 } 36 }); 37 38 AlertDialog dialog = alerBuilder.create(); 39 40 // dialog 建立好了,必需要讓其顯示,而且屏蔽home鍵 41 dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); 42 dialog.show(); 43 44 45 } 46 47 }
f.Manifest註冊,LoginActivity(入口),MainActivity(主界面),靜態廣播
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3 package="com.example.broadcastbestpractic" 4 android:versionCode="1" 5 android:versionName="1.0" > 6 7 <uses-sdk 8 android:minSdkVersion="14" 9 android:targetSdkVersion="19" /> 10 11 <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> 12 13 <application 14 android:allowBackup="true" 15 android:icon="@drawable/ic_launcher" 16 android:label="@string/app_name" 17 android:theme="@style/AppTheme" > 18 <activity 19 android:name=".LoginActivity" 20 android:label="@string/app_name" > 21 <intent-filter> 22 <action android:name="android.intent.action.MAIN" /> 23 24 <category android:name="android.intent.category.LAUNCHER" /> 25 </intent-filter> 26 </activity> 27 <activity android:name=".MainActivity" > 28 </activity> 29 <receiver android:name="com.example.broadcastbestpractic.OfflineReceiver"> 30 <intent-filter > 31 <action android:name="com.example.broadcastbestpractic.FORCE_OFFLINE"/> 32 </intent-filter> 33 </receiver> 34 </application> 35 36 </manifest>
注意:
a.Receiver中彈出對話框的步驟以及須要的權限
b.Manifest中要聲明權限 android.permission.SYSTEM_ALERT_WINDOW,由於須要對話框一直存活直到點擊從新ok從新登陸
首先得知道的事情:
1.當數據映射覆雜的時候,必然會用到數據庫
2.Android內置輕量級數據庫sqlite,路徑在/system/xbin/sqlite3
3.程序中建立的數據庫地址:/data/data/<包名>/databases/目錄下
4.用實現抽象類SQLiteOpenHelper的子類對象XXX來建立和升級數據庫
5.用XXX.getReadableDatabase()或XXX.getWritableDatabase()獲取SQLiteDatabase對象YYY
6.經過YYY進行數據的增刪改查
補充下cmd下sqlite測試操做
C:\Users\joho>adb shell
$ su
# cd /data/data/com.example.databasetest/databases
# sqlite3 BookStore.db
sqlite>.table
sqlite>.schema
sqlite>select * from Book;
sqlite>.quit
...
1.建立數據庫
23.sqLiteOpenHelper = new MyDatabaseHelper(this, "BookStore.db", null, 1); 38.sqLiteOpenHelper.getWritableDatabase();
2.增
1 addDataButton.setOnClickListener(new OnClickListener() { 2 3 @Override 4 public void onClick(View v) { 5 // SQLiteOpenHelper的getWritableDatabase和getReadableDatab會返回一個SQLiteDatabase對象 6 SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase(); 7 // public long insert(String table, String nullColumnHack, ContentValues values) 8 ContentValues values = new ContentValues(); 9 values.put("author", "erge"); 10 values.put("price", "88.8"); 11 values.put("pages", "1"); 12 values.put("name", "程序員的自我修養"); 13 db.insert("Book", null, values);// 插入一條數據 14 15 values.clear(); // 準備插入第二條 16 values.put("author", "erge"); 17 values.put("price", "888.8"); 18 values.put("pages", "2"); 19 values.put("name", "程序員的將來"); 20 db.insert("Book", null, values); //插入第二條 21 22 } 23 });
3.改
1 updateButton.setOnClickListener(new OnClickListener() { 2 3 @Override 4 public void onClick(View v) { 5 // TODO Auto-generated method stub 6 SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase(); 7 // public int update(String table, ContentValues values, String whereClause, String[] whereArgs) 8 // (表名,值,where,where的值) 9 ContentValues values = new ContentValues(); 10 values.put("name", "the self_improvement of developer"); 11 db.update("Book", values, "name = ?", new String[]{"程序員的自我修養"}); 12 13 values.clear(); 14 values.put("name", "the future of developer"); 15 db.update("Book", values, "name = ?", new String[]{"程序員的將來"}); 16 Toast.makeText(MainActivity.this, "update sucess", Toast.LENGTH_SHORT).show(); 17 } 18 });
4.刪
1 deleteButton.setOnClickListener(new OnClickListener() { 2 3 @Override 4 public void onClick(View v) { 5 // 6 SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase(); 7 // public int delete(String table, String whereClause, String[] whereArgs) 8 db.delete("Book", "pages > ?", new String[]{"1"}); 9 } 10 });
5.查
1 // 查詢最爲複雜,參數較多,獲得的結果保存在遊標——Cursor對象中 2 queryButton.setOnClickListener(new OnClickListener() { 3 4 @Override 5 public void onClick(View v) { 6 // TODO Auto-generated method stub 7 SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase(); 8 // public Cursor query(String table, String[] columns, String selection,String[] selectionArgs, String groupBy, String having,String orderBy) 9 //columns用於約束查詢哪幾列,不指定則查所有 10 //selection,selectionArgs用來約束查詢哪些行,不指定則所有; 11 //groupBy指定須要group by的列,不指定則對結果進行group by處理; 12 //having用於對以前group by的數據進一步過濾,不指定則不過濾;orderBy對結果進行排序,不指定則默認排序 13 14 // 遍歷得結果會存儲到一個Course對象中,經過遍歷這個對象,來輸出數據 15 Cursor cursor = db.query("Book",null,null,null,null,null,null); 16 if(cursor.moveToFirst()){ 17 do { 18 String author = cursor.getString(cursor.getColumnIndex("author")); 19 Double price = cursor.getDouble(cursor.getColumnIndex("price")); 20 int pages = cursor.getInt(cursor.getColumnIndex("pages")); 21 String name = cursor.getString(cursor.getColumnIndex("name")); 22 Log.d("test", "name::"+name); 23 Log.d("test", "pages::"+pages); 24 Log.d("test", "price::"+price); 25 Log.d("test", "author::"+author); 26 } while (cursor.moveToNext()); 27 } 28 cursor.close(); 29 } 30 });
DatabaseTest代碼
主佈局
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 <Button 8 android:id="@+id/create" 9 android:layout_height="wrap_content" 10 android:layout_width="match_parent" 11 android:text="create database BookStore.db" 12 /> 13 14 <Button 15 android:id="@+id/add_data" 16 android:layout_height="wrap_content" 17 android:layout_width="match_parent" 18 android:text="Add data" 19 /> 20 <Button 21 android:id="@+id/update_data" 22 android:layout_height="wrap_content" 23 android:layout_width="match_parent" 24 android:text="Update data" 25 /> 26 <Button 27 android:id="@+id/delete_data" 28 android:layout_height="wrap_content" 29 android:layout_width="match_parent" 30 android:text="Delete data" 31 /> 32 <Button 33 android:id="@+id/query_data" 34 android:layout_height="wrap_content" 35 android:layout_width="match_parent" 36 android:text="Query data" 37 /> 38 <Button 39 android:id="@+id/replace_data" 40 android:layout_height="wrap_content" 41 android:layout_width="match_parent" 42 android:text="use transaction to replace Book" 43 /> 44 45 <Button 46 android:id="@+id/upgrade_one" 47 android:layout_height="wrap_content" 48 android:layout_width="match_parent" 49 android:text="upgrade database one" 50 /> 51 <Button 52 android:id="@+id/upgrade_two" 53 android:layout_height="wrap_content" 54 android:layout_width="match_parent" 55 android:text="upgrade database two" 56 /> 57 </LinearLayout>
定義MyDatabaseHelper繼承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 import android.widget.Toast; 8 /** 9 * 10 * 注意 id 設爲主鍵時 primary key 兩個詞,分開的 11 */ 12 public class MyDatabaseHelper extends SQLiteOpenHelper { 13 public static final String CREATE_BOOK = 14 "create table Book(" + 15 "id integer primary key autoincrement," + 16 "author text, " + 17 "price real," + 18 "pages integer," + 19 "name text)"; 20 public static final String CREATE_CATEGORY="create table Category(" + 21 "id integer primary key autoincrement," + 22 "category_name text," + 23 "category_code integer)"; 24 private Context mContext;//爲何須要?獲取SQLiteOpenHelper實例的時候,會傳入context,爲了在這個context中進行操做 25 // 構造方法(contex , 數據庫名 , 光標? , 版本號) 26 public MyDatabaseHelper(Context context, String name, 27 CursorFactory factory, int version) { 28 super(context, name, factory, version); 29 mContext = context; 30 } 31 32 @Override 33 public void onCreate(SQLiteDatabase db) { 34 // 建立數據庫的時候建立一張表 35 db.execSQL(CREATE_BOOK); 36 //db.execSQL(CREATE_CATEGORY); 37 Toast.makeText(mContext, "create table sussessed", Toast.LENGTH_SHORT).show(); 38 } 39 40 @Override 41 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 42 // 更新數據庫——感受這種方法很糟糕,若是存在則刪除,數據不要了?? 43 /* 44 db.execSQL("drop table if exists Category"); 45 db.execSQL("drop table if exists Book"); 46 onCreate(db); 47 */ 48 49 // 最佳寫法——固然第二版建立時就會建立category表,第三版建立時就會增長id 50 // 只有低版本升級是纔會執行到下面的語句,另外特別注意: 51 // 這裏並無寫break語句,是爲了保證誇版本升級能夠執行到全部語句——感受還能改造,事務之類的 52 switch (oldVersion) { 53 //升級至第二版時,會多建立一個category表 54 case 1: 55 db.execSQL(CREATE_CATEGORY); 56 //升級至第三版時,Book表會新建一列 category_id 57 case 2: 58 db.execSQL("alter table Book add column category_id integer"); 59 default: 60 } 61 62 } 63 64 }
主入口
1 package com.example.databasetest; 2 3 import android.app.Activity; 4 import android.content.ContentValues; 5 import android.database.Cursor; 6 import android.database.sqlite.SQLiteDatabase; 7 import android.database.sqlite.SQLiteOpenHelper; 8 import android.os.Bundle; 9 import android.util.Log; 10 import android.view.View; 11 import android.view.View.OnClickListener; 12 import android.widget.Button; 13 import android.widget.Toast; 14 15 16 public class MainActivity extends Activity { 17 private SQLiteOpenHelper sqLiteOpenHelper; 18 @Override 19 protected void onCreate(Bundle savedInstanceState) { 20 super.onCreate(savedInstanceState); 21 setContentView(R.layout.activity_main); 22 // 獲得SQLiteOpentHelper的實例 23 sqLiteOpenHelper = new MyDatabaseHelper(this, "BookStore.db", null, 1); 24 Button createDatabaseButton = (Button) findViewById(R.id.create); 25 Button addDataButton = (Button) findViewById(R.id.add_data); 26 Button updateButton = (Button) findViewById(R.id.update_data); 27 Button deleteButton = (Button) findViewById(R.id.delete_data); 28 Button queryButton = (Button) findViewById(R.id.query_data); 29 Button replaceButton = (Button) findViewById(R.id.replace_data); 30 Button upgrade_One_Button = (Button) findViewById(R.id.upgrade_one); 31 Button upgrade_Two_Button = (Button) findViewById(R.id.upgrade_two); 32 33 createDatabaseButton.setOnClickListener(new OnClickListener() { 34 35 @Override 36 public void onClick(View v) { 37 // 沒有則會建立數據庫,有則不建立 38 sqLiteOpenHelper.getWritableDatabase(); 39 } 40 }); 41 42 43 addDataButton.setOnClickListener(new OnClickListener() { 44 45 @Override 46 public void onClick(View v) { 47 // SQLiteOpenHelper的getWritableDatabase和getReadableDatab會返回一個SQLiteDatabase對象 48 SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase(); 49 // public long insert(String table, String nullColumnHack, ContentValues values) 50 ContentValues values = new ContentValues(); 51 values.put("author", "erge"); 52 values.put("price", "88.8"); 53 values.put("pages", "1"); 54 values.put("name", "程序員的自我修養"); 55 db.insert("Book", null, values);// 插入一條數據 56 57 values.clear(); // 準備插入第二條 58 values.put("author", "erge"); 59 values.put("price", "888.8"); 60 values.put("pages", "2"); 61 values.put("name", "程序員的將來"); 62 db.insert("Book", null, values); //插入第二條 63 64 } 65 }); 66 67 updateButton.setOnClickListener(new OnClickListener() { 68 69 @Override 70 public void onClick(View v) { 71 // TODO Auto-generated method stub 72 SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase(); 73 // public int update(String table, ContentValues values, String whereClause, String[] whereArgs) 74 // (表名,值,where,where的值) 75 ContentValues values = new ContentValues(); 76 values.put("name", "the self_improvement of developer"); 77 db.update("Book", values, "name = ?", new String[]{"程序員的自我修養"}); 78 79 values.clear(); 80 values.put("name", "the future of developer"); 81 db.update("Book", values, "name = ?", new String[]{"程序員的將來"}); 82 Toast.makeText(MainActivity.this, "update sucess", Toast.LENGTH_SHORT).show(); 83 } 84 }); 85 86 deleteButton.setOnClickListener(new OnClickListener() { 87 88 @Override 89 public void onClick(View v) { 90 // 91 SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase(); 92 // public int delete(String table, String whereClause, String[] whereArgs) 93 db.delete("Book", "pages > ?", new String[]{"1"}); 94 } 95 }); 96 97 // 查詢最爲複雜,參數較多 98 queryButton.setOnClickListener(new OnClickListener() { 99 100 @Override 101 public void onClick(View v) { 102 // TODO Auto-generated method stub 103 SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase(); 104 // public Cursor query(String table, String[] columns, String selection,String[] selectionArgs, String groupBy, String having,String orderBy) 105 //columns用於約束查詢哪幾列,不指定則查所有 106 //selection,selectionArgs用來約束查詢哪些行,不指定則所有; 107 //groupBy指定須要group by的列,不指定則對結果進行group by處理; 108 //having用於對以前group by的數據進一步過濾,不指定則不過濾;orderBy對結果進行排序,不指定則默認排序 109 110 // 遍歷得結果會存儲到一個Course對象中,經過遍歷這個對象,來輸出數據 111 Cursor cursor = db.query("Book",null,null,null,null,null,null); 112 if(cursor.moveToFirst()){ 113 do { 114 String author = cursor.getString(cursor.getColumnIndex("author")); 115 Double price = cursor.getDouble(cursor.getColumnIndex("price")); 116 int pages = cursor.getInt(cursor.getColumnIndex("pages")); 117 String name = cursor.getString(cursor.getColumnIndex("name")); 118 Log.d("test", "name::"+name); 119 Log.d("test", "pages::"+pages); 120 Log.d("test", "price::"+price); 121 Log.d("test", "author::"+author); 122 } while (cursor.moveToNext()); 123 } 124 cursor.close(); 125 } 126 }); 127 128 replaceButton.setOnClickListener(new OnClickListener() { 129 130 @Override 131 public void onClick(View v) { 132 // TODO Auto-generated method stub 133 SQLiteDatabase db = sqLiteOpenHelper.getWritableDatabase(); 134 db.beginTransaction(); 135 try { 136 // 刪除原來的表 137 db.delete("Book", null, null); 138 139 // 中斷測試 140 if(true){ 141 throw new RuntimeException("..."); 142 } 143 // 從新添加數據 144 ContentValues values = new ContentValues(); 145 values.put("author", "nima"); 146 values.put("price", 25.5); 147 values.put("pages", 88); 148 values.put("name", "zhiqinchun"); 149 150 db.insert("Book", null, values); 151 db.setTransactionSuccessful(); 152 } catch (Exception e) { 153 // TODO: handle exception 154 }finally{ 155 db.endTransaction(); 156 } 157 } 158 }); 159 160 upgrade_One_Button.setOnClickListener(new OnClickListener() { 161 162 @Override 163 public void onClick(View v) { 164 // 這裏數據庫版本應該搞個變量控制一下,否則升級就只能升級一次 ,後面指定的版本號比以前的大的話,就會調用onUpgrade方法 165 sqLiteOpenHelper = new MyDatabaseHelper(MainActivity.this, "BookStore.db", null, 2); 166 sqLiteOpenHelper.getWritableDatabase(); 167 168 } 169 }); 170 upgrade_Two_Button.setOnClickListener(new OnClickListener() { 171 172 @Override 173 public void onClick(View v) { 174 // 這裏數據庫版本應該搞個變量控制一下,否則升級就只能升級一次 ,後面指定的版本號比以前的大的話,就會調用onUpgrade方法 175 sqLiteOpenHelper = new MyDatabaseHelper(MainActivity.this, "BookStore.db", null, 3); 176 sqLiteOpenHelper.getWritableDatabase(); 177 178 } 179 }); 180 181 } 182 183 }