$《第一行代码:Android》读书笔记——第6章 数据持久化

  主要讲述了Android数据持久化的三种方式:文件存储、SharedPreference存储、SQLite数据库存储。

(一)文件存储

  其实Android中文件存储方式和Java的文件操作类似,就是用IO流进行操作。文件存储只能保存简单的字符串或二进制数据,不适合保存结构较为复杂的数据。

  1、示例程序(代码中有详细注释):

  (1)xml文件:

  其中有一个EditText,可以在里面输入字符,还有两个Button,一个用于保存输入的内容到一个文件中,另一个用于载入相应的文件内容到EditText中。

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:layout_width="match_parent"
 3     android:layout_height="match_parent"
 4     android:orientation="vertical" >
 5 
 6     <EditText
 7         android:id="@+id/input_et"
 8         android:layout_width="match_parent"
 9         android:layout_height="wrap_content" />
10 
11     <Button
12         android:id="@+id/save_btn"
13         android:layout_width="match_parent"
14         android:layout_height="wrap_content"
15         android:text="保存" />
16 
17 
18     <Button
19         android:id="@+id/load_btn"
20         android:layout_width="match_parent"
21         android:layout_height="wrap_content"
22         android:text="载入文件内容" />
23 
24 </LinearLayout>

  (2)MainActivity:

  1 import java.io.BufferedReader;
  2 import java.io.BufferedWriter;
  3 import java.io.FileInputStream;
  4 import java.io.FileOutputStream;
  5 import java.io.InputStreamReader;
  6 import java.io.OutputStreamWriter;
  7 
  8 import android.app.Activity;
  9 import android.content.Context;
 10 import android.os.Bundle;
 11 import android.text.TextUtils;
 12 import android.view.Menu;
 13 import android.view.MenuItem;
 14 import android.view.View;
 15 import android.view.View.OnClickListener;
 16 import android.widget.Button;
 17 import android.widget.EditText;
 18 import android.widget.Toast;
 19 
 20 public class MainActivity extends Activity implements OnClickListener {
 21 
 22     private String dataFileName = "MyDataFile";
 23 
 24     private EditText inputEt;
 25     private Button saveBtn;
 26     private Button loadBtn;
 27 
 28     @Override
 29     protected void onCreate(Bundle savedInstanceState) {
 30         super.onCreate(savedInstanceState);
 31         setContentView(R.layout.activity_main);
 32 
 33         inputEt = (EditText) findViewById(R.id.input_et);
 34         saveBtn = (Button) findViewById(R.id.save_btn);
 35         loadBtn = (Button) findViewById(R.id.load_btn);
 36 
 37         saveBtn.setOnClickListener(this);
 38         loadBtn.setOnClickListener(this);
 39     }
 40 
 41     @Override
 42     public void onClick(View v) {
 43         switch (v.getId()) {
 44         case R.id.save_btn:
 45             String inputText = inputEt.getText().toString();
 46             if (inputText.length() == 0) {
 47                 Toast.makeText(MainActivity.this, "未输入任何内容!",
 48                         Toast.LENGTH_SHORT).show();
 49             } else {
 50                 save(dataFileName, inputText);
 51                 Toast.makeText(MainActivity.this, "保存成功!", Toast.LENGTH_SHORT)
 52                         .show();
 53             }
 54             break;
 55 
 56         case R.id.load_btn:
 57             String fileContent = load(dataFileName);
 58 
 59             // 用于判断一个字符串是否是null或者空内容的工具方法
 60             if (!TextUtils.isEmpty(fileContent)) {
 61                 inputEt.setText(fileContent);
 62                 // 让光标移到文字最后
 63                 inputEt.setSelection(fileContent.length());
 64                 Toast.makeText(this, "载入文件内容成功!", Toast.LENGTH_SHORT).show();
 65             }
 66             break;
 67         default:
 68             break;
 69         }
 70     }
 71 
 72     // 保存输入内容到文件的方法
 73     public void save(String fileName, String inputText) {
 74         FileOutputStream out = null;
 75         BufferedWriter writer = null;
 76 
 77         try {
 78             // 1.用Context类的openFileOutput方法创建FileOutputStream实例
 79             // MODE_PRIVATE模式是默认操作模式,表示当指定同样文件名时,所写入的内容将会覆盖原来的内容
 80             // MODE_APPEND表示如果该文件已经存在就往文件里面追加内容,不存在就创建新文件
 81             // 注:这里的文件名不可以包含路径,因为所有的文件都是默认存储到/data/data/包名/files目录的
 82             out = openFileOutput(fileName, Context.MODE_PRIVATE);
 83 
 84             // 2.用FileOutputStream实例创建OutputStreamWriter实例,再用OutputStreamWriter实例创建BufferedWriter实例
 85             writer = new BufferedWriter(new OutputStreamWriter(out));
 86 
 87             // 3.写入内容到文件
 88             writer.write(inputText);
 89 
 90             /**
 91              * 注:查看该文件的方法: DDMS—>File
 92              * Explorer—>/data/data/com.example.filepersistencetest(包名)/files/
 93              * 该目录下即可看到刚刚保存的文件,DDMS按钮下方有一个导出文件,即可把文件导出到电脑上用记事本查看
 94              */
 95 
 96         } catch (Exception e) {
 97             e.printStackTrace();
 98         } finally {
 99             try {
100                 if (writer != null) {
101                     writer.close();
102                 }
103             } catch (Exception e) {
104                 e.printStackTrace();
105             }
106         }
107     }
108 
109     // 载入并读取文件内容的方法
110     public String load(String fileName) {
111         FileInputStream in = null;
112         BufferedReader reader = null;
113         StringBuilder content = new StringBuilder();
114 
115         try {
116             // 1.用Context类的openFileInput方法创建FileInputStream实例
117             in = openFileInput(fileName);
118 
119             if (in == null) {
120                 Toast.makeText(MainActivity.this, "数据文件不存在!",
121                         Toast.LENGTH_SHORT).show();
122                 return "";
123             }
124 
125             // 2.创建BufferedReader实例
126             reader = new BufferedReader(new InputStreamReader(in));
127 
128             String line = "";
129 
130             // 3.读取每一行
131             while ((line = reader.readLine()) != null) {
132                 content.append(line);
133             }
134         } catch (Exception e) {
135             e.printStackTrace();
136         } finally {
137             if (reader != null) {
138                 try {
139                     reader.close();
140                 } catch (Exception e) {
141                     e.printStackTrace();
142                 }
143             }
144         }
145 
146         return content.toString();
147     }
148 
149     @Override
150     protected void onDestroy() {
151         super.onDestroy();
152         String inputText = inputEt.getText().toString();
153         if (inputText.length() != 0) {
154             save(dataFileName, inputText);
155         }
156     }
157 
158 }

  2、用openFileOutput和openFileInput创建文件时,参数中的文件名不可以包含路径,因为所有的文件都是默认存储到/data/data/包名/files目录的。

  3、查看该文件的方法: DDMS—>File Explorer—>/data/data/com.example.filepersistencetest(包名)/files/,该目录下即可看到刚刚保存的文件,DDMS按钮下方有一个导出文件按钮,即可把文件导出到电脑上用记事本查看。

(二)SharedPreferences

  SharedPreferences用键值对形式存储数据,适合保存程序的一些偏好设置等。SharedPreferences文件会自动存放在/data/data/包名/shared_prefs目录下,是xml格式的文件。

  1、获取SharedPreferences对象的三种方法:

  (1)Activity类的getPreferences方法,只接收一个模式参数,这个方法会自动把当前活动类名作为SharedPreferences文件名。
  (2)PreferencesManager类中的getDefaultSharedPreferences方法,这是一个静态方法,接收一个Context参数,并自动使用当前 应用程序的包名作为前缀来命名SharedPreferences文件。

  (3)Context类的getSharedPreferences方法,接受两个参数,第一个为文件名字符串(不要带路径!),第二个是文件操作模式。

  2、向SharedPreferences文件写入数据的步骤:

  (1)用SharedPreferences对象的edit方法获取SharedPreferences.Editor实例:

1 SharedPreferences.Editor editor = getSharedPreferences("dataFile",
2                 MODE_PRIVATE).edit();

  (2)写入数据到SharedPreferences中:

1 editor.putString("name", "贾永基");
2 editor.putInt("age", 23);
3 editor.putBoolean("married", false);

  (3)用commit方法提交:

1 editor.commit();

  3、从SharedPreferences文件读数据的步骤:

  (1)创建SharedPreferences实例:

1 SharedPreferences pref = getSharedPreferences("dataFile", MODE_PRIVATE);

  (2)用getXXX方法读取数据:

1      // 第一个参数表示键名,第二个参数表示如果找不到数据时候返回的默认值
2         String name = pref.getString("name", "");
3         int age = pref.getInt("age", 0);
4         boolean married = pref.getBoolean("married", false);
5 
6         Log.d("MainActivity", "name is " + name);
7         Log.d("MainActivity", "age is " + age);
8         Log.d("MainActivity", "married is " + married);

  4、示例程序:

  (1)XML文件:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:layout_width="match_parent"
 3     android:layout_height="match_parent"
 4     android:orientation="vertical" >
 5 
 6     <Button
 7         android:id="@+id/save_data_btn"
 8         android:layout_width="match_parent"
 9         android:layout_height="wrap_content"
10         android:text="保存数据" />
11 
12     <Button
13         android:id="@+id/load_data_btn"
14         android:layout_width="match_parent"
15         android:layout_height="wrap_content"
16         android:text="载入数据" />
17 
18 </LinearLayout>

  (2)MainActivity:

 1 package com.example.sharedpreferencestest;
 2 
 3 import android.app.Activity;
 4 import android.content.SharedPreferences;
 5 import android.os.Bundle;
 6 import android.util.Log;
 7 import android.view.Menu;
 8 import android.view.MenuItem;
 9 import android.view.View;
10 import android.view.View.OnClickListener;
11 import android.widget.Button;
12 import android.widget.Toast;
13 
14 public class MainActivity extends Activity implements OnClickListener {
15 
16     private Button saveDataBtn;
17     private Button loadDataBtn;
18 
19     @Override
20     protected void onCreate(Bundle savedInstanceState) {
21         super.onCreate(savedInstanceState);
22         setContentView(R.layout.activity_main);
23 
24         saveDataBtn = (Button) findViewById(R.id.save_data_btn);
25         loadDataBtn = (Button) findViewById(R.id.load_data_btn);
26 
27         saveDataBtn.setOnClickListener(this);
28         loadDataBtn.setOnClickListener(this);
29     }
30 
31     @Override
32     public void onClick(View v) {
33         switch (v.getId()) {
34         case R.id.save_data_btn:
35             saveData();
36             Toast.makeText(MainActivity.this, "保存数据成功", Toast.LENGTH_SHORT)
37                     .show();
38             break;
39         case R.id.load_data_btn:
40             loadData();
41             break;
42         default:
43             break;
44         }
45     }
46 
47     // 保存数据到SharedPreferences
48     public void saveData() {
49         // 1.用SharedPreferences对象的edit方法获取SharedPreferences.Editor实例
50         SharedPreferences.Editor editor = getSharedPreferences("dataFile",
51                 MODE_PRIVATE).edit();
52 
53         // 注:获取SharedPreferences对象还有两种方法:
54         // (1)Activity类的getPreferences方法,只接收一个模式参数,这个方法会自动把当前活动类名作为SharedPreferences文件名
55         // (2)PreferencesManager类中的getDefaultSharedPreferences方法,这是一个静态方法,接收一个Context参数,并自动使用当前
56         // 应用程序的包名作为前缀来命名SharedPreferences文件
57 
58         // 2.写入数据到SharedPreferences中
59         editor.putString("name", "贾永基");
60         editor.putInt("age", 23);
61         editor.putBoolean("married", false);
62 
63         // 3.用commit方法提交
64         // 注:SharedPreferences文件会自动存放在/data/data/包名/shared_prefs目录下,是xml格式的文件
65         editor.commit();
66     }
67 
68     // 从SharedPreferences读数据
69     public void loadData() {
70         SharedPreferences pref = getSharedPreferences("dataFile", MODE_PRIVATE);
71 
72         // 第一个参数表示键名,第二个参数表示如果找不到数据时候返回的默认值
73         String name = pref.getString("name", "");
74         int age = pref.getInt("age", 0);
75         boolean married = pref.getBoolean("married", false);
76 
77         Log.d("MainActivity", "name is " + name);
78         Log.d("MainActivity", "age is " + age);
79         Log.d("MainActivity", "married is " + married);
80     }
81 
82 }

 (三)SQLite

  SQLite是Android内嵌的轻量级关系型数据库,速度很快,支持标准的SQL语法,还支持ACID事务。

  1、创建数据库:

  继承SQLiteOpenHelper类创建自己的类MyDatabaseHelper,并实现onCreate和onUpgrade两个抽象方法,在onCreate方法中建表,在onUpgrade中升级数据库。

 1 import android.content.Context;
 2 import android.database.sqlite.SQLiteDatabase;
 3 import android.database.sqlite.SQLiteDatabase.CursorFactory;
 4 import android.database.sqlite.SQLiteOpenHelper;
 5 import android.widget.Toast;
 6 
 7 public class MyDatabaseHelper extends SQLiteOpenHelper {
 8 
 9     // 1.将建表语句定义成字符串常量
10     public static final String CREATE_BOOK = "create table book(" // 注:表名和字段名称不区分大小写
11             + "id integer primary key autoincrement,"
12             + "author text,"
13             + "price real," + "pages integer," + "name text,"+ "category_id integer)";;
14 
15     public static final String CREATE_CATEGORY = "create table category("
16             + "id integer primary key autoincrement," + "category_name text,"
17             + "category_code integer)";
18 
19     private Context mContext;
20 
21     public MyDatabaseHelper(Context context, String name,
22             CursorFactory factory, int version) {
23         super(context, name, factory, version);
24         mContext = context;
25     }
26 
27     @Override
28     public void onCreate(SQLiteDatabase db) {
29         // 2.用SQLiteDatabase的execSQL方法执行建表语句
30         db.execSQL(CREATE_BOOK);
31         db.execSQL(CREATE_CATEGORY);
32 
33         Toast.makeText(mContext, "创建数据库成功!", Toast.LENGTH_SHORT).show();
34     }
35 
36     @Override
37     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
38         switch (oldVersion) {
39         case 1:
40             db.execSQL(CREATE_CATEGORY);
41         case 2: // 注意这里case的最后是不写break的,以应对跨版本升级的情况
42             db.execSQL("alter table book add column category_id integer");
43         default:
44             break;
45         }
46     }
47 
48 }

  2、创建数据库后,在adb shell中可以用命令行方式查看数据库的具体数据,方法如下:

  (1)打开控制台窗口,输入adb shell,然后cd到路径:/data/data/当前包名/databases/,使用ls查看当前目录里的文件。

  (2)假设提前创建的数据库名叫BookStore.db,那么接着就用sqlite3 BookStore.db命令打开数据库,然后可以输入各种SQL语句进行操作。

  (3)输入.table命令可以查看当前数据库的表,.schema命令可以查看所有表的建表语句。.exit或.quit命令可以退出数据库编辑,exit命令可以退出adb shell。

  (4)在数据库中查询结果出现乱码的情况的解决(Win7环境):

  在控制台里输入命令:chcp 65001 确定—>在命令行标题栏上点击右键,选择【属性】 -【字体】,将字体修改为【Lucida Console】 确定
  完成后再通过 adb shell 进入sqlite3,乱码解决.
  注:恢复cmd的默认设置:Win+R -> 输入regedit -> 找到HKEY_CURRENT_USERConsole\%SystemRoot%_system32_cmd.exe -> 右键删除文件夹%SystemRoot%_system32_cmd.exe -> 重启cmd即可。

  3、示例程序:

  (1)xml文件:

 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     android:layout_width="match_parent"
 3     android:layout_height="match_parent"
 4     android:orientation="vertical" >
 5 
 6     <Button
 7         android:id="@+id/create_database_btn"
 8         android:layout_width="match_parent"
 9         android:layout_height="wrap_content"
10         android:text="创建数据库" />
11 
12     <Button
13         android:id="@+id/add_data_btn"
14         android:layout_width="match_parent"
15         android:layout_height="wrap_content"
16         android:text="添加数据" />
17 
18     <Button
19         android:id="@+id/update_data_btn"
20         android:layout_width="match_parent"
21         android:layout_height="wrap_content"
22         android:text="更新数据" />
23 
24     <Button
25         android:id="@+id/delete_data_btn"
26         android:layout_width="match_parent"
27         android:layout_height="wrap_content"
28         android:text="删除数据" />
29 
30     <Button
31         android:id="@+id/query_data_btn"
32         android:layout_width="match_parent"
33         android:layout_height="wrap_content"
34         android:text="查询数据" />
35 
36     <TextView
37         android:layout_width="match_parent"
38         android:layout_height="wrap_content"
39         android:text="查询结果:" />
40 
41     <TextView
42         android:id="@+id/query_result_tv"
43         android:layout_width="match_parent"
44         android:layout_height="wrap_content" />
45 
46 </LinearLayout>

  (2)MainActivity:

  1 package com.example.databasetest2;
  2 
  3 import java.util.ArrayList;
  4 
  5 import android.app.Activity;
  6 import android.database.Cursor;
  7 import android.database.sqlite.SQLiteDatabase;
  8 import android.os.Bundle;
  9 import android.view.Menu;
 10 import android.view.MenuItem;
 11 import android.view.View;
 12 import android.view.View.OnClickListener;
 13 import android.widget.Button;
 14 import android.widget.EditText;
 15 import android.widget.TextView;
 16 
 17 public class MainActivity extends Activity implements OnClickListener {
 18 
 19     private Button createDatabaseBtn;
 20     private Button addDataBtn;
 21     private Button updateDataBtn;
 22     private Button deleteDataBtn;
 23     private Button queryDataBtn;
 24     private TextView queryResultTv;
 25 
 26     private MyDatabaseHelper dbHelper;
 27 
 28     @Override
 29     protected void onCreate(Bundle savedInstanceState) {
 30         super.onCreate(savedInstanceState);
 31         setContentView(R.layout.activity_main);
 32 
 33         // 1.创建MyDatabaseHelper实例
 34         dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 3); // 这里的3为数据库版本号
 35 
 36         createDatabaseBtn = (Button) findViewById(R.id.create_database_btn);
 37         addDataBtn = (Button) findViewById(R.id.add_data_btn);
 38         updateDataBtn = (Button) findViewById(R.id.update_data_btn);
 39         deleteDataBtn = (Button) findViewById(R.id.delete_data_btn);
 40         queryDataBtn = (Button) findViewById(R.id.query_data_btn);
 41         queryResultTv = (TextView) findViewById(R.id.query_result_tv);
 42 
 43         createDatabaseBtn.setOnClickListener(this);
 44         addDataBtn.setOnClickListener(this);
 45         updateDataBtn.setOnClickListener(this);
 46         deleteDataBtn.setOnClickListener(this);
 47         queryDataBtn.setOnClickListener(this);
 48     }
 49 
 50     @Override
 51     public void onClick(View v) {
 52         SQLiteDatabase db;
 53         switch (v.getId()) {
 54         case R.id.create_database_btn:
 55             // 2.调用MyDatabaseHelper的getWritableDatabase方法打开数据库
 56             dbHelper.getWritableDatabase();
 57             break;
 58         case R.id.add_data_btn:
 59             // 先获取SQLiteDatabase实例,然后直接用execSQL方法执行SQL语句的方式往表中插入数据
 60             db = dbHelper.getWritableDatabase();
 61             db.execSQL(
 62                     "insert into book (name,author,pages,price,category_id) values (?,?,?,?,?)",
 63                     new String[] { "三体", "刘慈欣", "567", "49.9", "1" }); // 注:所有类型的占位符数据都要是字符串,若语句中无占位符参数,则第二个函数参数可为null
 64             db.execSQL(
 65                     "insert into book (name,author,pages,price,category_id) values (?,?,?,?,?)",
 66                     new String[] { "第一行代码——Android", "郭霖", "401", "25.9", "3" });
 67             break;
 68         case R.id.update_data_btn:
 69             db = dbHelper.getWritableDatabase();
 70             // 更新数据
 71             db.execSQL("update book set price = ? where name = ?",
 72                     new String[] { "10.99", "三体" });
 73             break;
 74         case R.id.delete_data_btn:
 75             db = dbHelper.getWritableDatabase();
 76             // 删除数据
 77             db.execSQL("delete from book where pages > ?", new String[] { "1" });
 78             break;
 79         case R.id.query_data_btn:
 80             db = dbHelper.getWritableDatabase();
 81             Cursor cursor = db.rawQuery("select * from book where id < ?",
 82                     new String[] { "100" });
 83             int idIndex = 0;
 84             int authorIndex = 0;
 85             int priceIndex = 0;
 86             int pagesIndex = 0;
 87             int nameIndex = 0;
 88             int categoryIdIndex = 0;
 89 
 90             ArrayList<Book> bookQueryList = new ArrayList<Book>();
 91 
 92             // 获取每个字段的ColumnIndex
 93             if (cursor.getCount() >= 0) {
 94                 idIndex = cursor.getColumnIndex("id");
 95                 authorIndex = cursor.getColumnIndex("author");
 96                 priceIndex = cursor.getColumnIndex("price");
 97                 pagesIndex = cursor.getColumnIndex("pages");
 98                 nameIndex = cursor.getColumnIndex("name");
 99                 categoryIdIndex = cursor.getColumnIndex("category_id");
100             }
101             while (cursor.moveToNext()) {
102                 Book book = new Book();
103                 book.setId(cursor.getInt(idIndex));
104                 book.setAuthor(cursor.getString(authorIndex));
105                 book.setPrice(cursor.getDouble(priceIndex));
106                 book.setPages(cursor.getInt(pagesIndex));
107                 book.setName(cursor.getString(nameIndex));
108                 book.setCategoryId(cursor.getInt(categoryIdIndex));
109 
110                 bookQueryList.add(book);
111             }
112 
113             queryResultTv.setText(bookQueryList.toString());
114             break;
115         default:
116             break;
117         }
118     }
119 }
120 
121 // Book类
122 class Book {
123     private int id;
124     private String author;
125     private double price;
126     private int pages;
127     private String name;
128     private int categoryId;
129 
130     public int getCategoryId() {
131         return categoryId;
132     }
133 
134     public void setCategoryId(int categoryId) {
135         this.categoryId = categoryId;
136     }
137 
138     public int getId() {
139         return id;
140     }
141 
142     public void setId(int id) {
143         this.id = id;
144     }
145 
146     public String getAuthor() {
147         return author;
148     }
149 
150     public void setAuthor(String author) {
151         this.author = author;
152     }
153 
154     public double getPrice() {
155         return price;
156     }
157 
158     public void setPrice(double price) {
159         this.price = price;
160     }
161 
162     public int getPages() {
163         return pages;
164     }
165 
166     public void setPages(int pages) {
167         this.pages = pages;
168     }
169 
170     public String getName() {
171         return name;
172     }
173 
174     public void setName(String name) {
175         this.name = name;
176     }
177 
178     @Override
179     public String toString() {
180         return "Book [ id = " + id + ", author = " + author + ", price = "
181                 + price + ", pages = " + pages + ", name = " + name
182                 + ", category_id = " + categoryId + " ]";
183     }
184 }

程序运行效果:

  4、使用事务 

 1             // 删除旧数据并添加新数据,两个操作为一个原子操作
 2             SQLiteDatabase db = dbHelper.getWritableDatabase();
 3             db.beginTransaction(); // 开启事务
 4             try {
 5                 db.delete("book", null, null);
 6                 // if (true) {
 7                 // // 在这里手动抛出一个异常,让事务失败
 8                 // throw new NullPointerException();
 9                 // }
10                 ContentValues values = new ContentValues();
11                 values.put("name", "这是本新书");
12                 values.put("author", "贾永基");
13                 values.put("pages", 123);
14                 values.put("price", 13.4);
15                 db.insert("book", null, values);
16                 db.setTransactionSuccessful();// 事务已经执行成功
17 
18             } catch (Exception e) {
19                 e.printStackTrace();
20             } finally {
21                 db.endTransaction(); // 结束事务
22             }

   5、补充:使用SQLiteDataBase类自带的方法进行数据库的增、删、改操作(因为使用自带的方法进行查询的操作过于复杂不做介绍,直接使用SQL语句即可):

  (1)插入数据:

 1 ...
 2 SQLiteDatabase db = dbHelper.getWritableDatabase();
 3 
 4 // 使用ContentValues对象组装数据
 5 ContentValues values = new ContentValues();
 6 values.put("name","三体");
 7 values.put("pages",565);
 8 values.put("price",23.99);
 9 
10 // 插入数据到数据库中
11 // 第一个参数:表名;第二个参数:用于在未指定添加数据的情况下为某些可为空的字段自动赋值为NULL,一般用不到这个功能,把这个参数传入null即可;第三个参数:携带数据的ContentValues对象
12 db.insert("Book",null,values);
13 ...
原文地址:https://www.cnblogs.com/jiayongji/p/5319485.html