一、文件存储
1. 将数据存储到文件中
在onDestroy()方法中,调用save()方法,目的是为了关闭窗口后,将文本框中的文本保存到指定文件中。
save()方法实现将文本写入到文件中。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
edit = (EditText) findViewById(R.id.edit);
}
@Override
protected void onDestroy() {
super.onDestroy();
String inputText = edit.getText().toString();
save(inputText);
}
public void save(String inputText) {
FileOutputStream out = null;
BufferedWriter writer = null;
try {
out = openFileOutput("data", MODE_PRIVATE);
writer = new BufferedWriter(new OutputStreamWriter(out));
writer.write(inputText);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (writer != null) {
writer.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用Android Device Monitor查看保存着文本的文件
Android 7.0版本以上,Android Device Monitor需要通过命令行访问Android\Sdk文件夹来开启。
C:\Users\lenovo>cd AppData\Local\Android\Sdk
C:\Users\lenovo\AppData\Local\Android\Sdk>cd tools
C:\Users\lenovo\AppData\Local\Android\Sdk\tools>monitor
输入monitor以后,就可以打开ADM了
2. 从文件中读取数据
@Override
protected void onCreate(Bundle savedInstanceState) {
...
String inputText = load();
if (!TextUtils.isEmpty(inputText)) {
edit.setText(inputText);
edit.setSelection(inputText.length());
Toast.makeText(this, "Restoring succeeded", Toast.LENGTH_SHORT).show();
}
}
...
public String load(){
FileInputStream in = null;
BufferedReader reader = null;
StringBuilder content = new StringBuilder();
try{
in = openFileInput("data");
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while((line = reader.readLine()) != null) {
content.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try{
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return content.toString();
}
二、SharedPreferences
特点:
- 使用键值对
- 支持多种数据类型
- 使用XML格式对数据进行管理
1. 将数据存储到SharedPreferences中
1.1 获取SharedPreferences对象
- Context类中的getSharedPreferences()方法
- Activity类中的getPreferences()方法
- PreferenceManager类中的getDefaultSharedPreferences()方法
1.2 存储数据
三步走:
- 调用SharedPreferences对象的 edit() 方法来获取一个SharedPreferences.Editor对象
- 向SharedPreferences.Editor对象中添加数据,使用 putXX() 方法
- 调用 apply() 方法将添加的数据提交,完成数据存储操作
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button saveData = (Button) findViewById(R.id.save_data);
saveData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences.Editor editor = getSharedPreferences("data", MODE_PRIVATE).edit();
editor.putString("name", "Tom");
editor.putInt("age", 28);
editor.putBoolean("married", false);
editor.apply();
}
});
}
}
运行程序后,数据被保存在data.xml文件中,文件内容如下所示:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="name">Tom</string>
<boolean name="married" value="false" />
<int name="age" value="28" />
</map>
2. 从SharedPreferences中读取数据
调用getSharedPreferences() 方法获取一个SharedPreferences对象pref,调用pref的getXX() 方法获取属性值,该方法有两个参数,一个为属性键值对的键,另一个为读取数据时的默认值。
Button restoreData = (Button) findViewById(R.id.restore_data);
restoreData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SharedPreferences pref = getSharedPreferences("data", MODE_PRIVATE);
String name = pref.getString("name", "");
int age = pref.getInt("age", 0);
boolean married = pref.getBoolean("married", false);
Log.d("MainActivity", "name is " + name);
Log.d("MainActivity", "age is " + age);
Log.d("MainActivity", "married is " + married);
}
});
运行结果:
05-04 01:33:24.600 10134-10134/? D/MainActivity: name is Tom
05-04 01:33:24.600 10134-10134/? D/MainActivity: age is 28
05-04 01:33:24.600 10134-10134/? D/MainActivity: married is false
Tip:实现记住密码的功能
三、SQLite数据库存储
特点:轻量级关系数据库,占用内存少,运算快
1. 创建数据库
Android提供SQLiteOpenHelper抽象类来帮助操作SQLite数据库。
若要创建一个数据库,则必须创建一个继承自SQLiteOpenHelper的子类。
SQLiteOpenHelper中有两个抽象方法:onCreate() 和onUpgrade() 方法
public class MyDatabaseHelper extends SQLiteOpenHelper {
public static final String CREATE_BOOK =
"create table book(" +
"id integer primary key autoincrement," +
"author text," +
"price real," +
"pages integer," +
"name text)";
private Context mContext;
public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
mContext = context;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK); // 执行SQL语句
Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
修改layout文件
<Button
android:id="@+id/create_database"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Create database" />
修改MainActivity文件
public class MainActivity extends AppCompatActivity {
private MyDatabaseHelper dbHelper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = new MyDatabaseHelper(this, "BookStore.db", null, 1);
Button createDatabase = (Button) findViewById(R.id.create_database);
createDatabase.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dbHelper.getWritableDatabase();
}
});
}
}
使用adb shell查看数据库文件
- 配置环境变量,将\Android\Sdk\platform-tools目录加入到Path变量中
- 打开命令行,输入adb shell
C:\Users\lenovo>adb shell
root@generic_x86:/ #
- 使用cd命令,进入/data/data/com.example.databasetest/databases/目录下,然后使用ls查看该目录中的文件,结果如下,BookStore.db为我们创建的文件,BookStore.db-journal是系统自动创建的支持数据库事件的临时日志:
root@generic_x86:/ # cd /data/data/com.example.lenovo.databasetest/databases/
root@generic_x86:/data/data/com.example.lenovo.databasetest/databases #
ls
BookStore.db
BookStore.db-journal
root@generic_x86:/data/data/com.example.lenovo.databasetest/databases #
- 输入sqlite3,后面加上数据库名,即可访问SQLite数据库
root@generic_x86:/data/data/com.example.lenovo.databasetest/databases #
sqlite3 BookStore.db
SQLite version 3.8.10.2 2015-05-20 18:17:19
Enter ".help" for usage hints.
sqlite>
- 输入 .table 命令,可以查看该数据库的表,android_metadata是每个数据库自动生成的表
sqlite> .table
android_metadata book
- 使用 .schema 命令查看建表语句
sqlite> .schema
CREATE TABLE android_metadata (locale TEXT);
CREATE TABLE book(id integer primary key autoincrement,author text,price real,pages integer,name text);
sqlite>
2. 升级数据库
sqlite> .table
Category android_metadata book
3. CRUD
C(create)R(Retrieve)U(Update)D(Delete)
a. 添加数据
添加数据
Button addData = (Button) findViewById(R.id.add_data);
addData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", "The Da Vinci Code");
values.put("author", "Dan Brown");
values.put("pages", 454);
values.put("price", 16.96);
db.insert("Book", null, values);
values.put("name", "The Lost Symbol");
values.put("author", "Dan Brown");
values.put("pages", 510);
values.put("price", 19.95);
db.insert("Book", null, values);
}
});
查询数据
sqlite> select * from book;
1|Dan Brown|16.96|454|The Da Vinci Code
2|Dan Brown|19.95|510|The Lost Symbol
b. 更新数据
Button updateData = (Button) findViewById(R.id.update_data);
updateData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("price", 10.99);
db.update("Book", values, "name = ?", new String[]{"The Da Vinci Code"});
}
});
sqlite> select * from book;
1|Dan Brown|10.99|454|The Da Vinci Code
2|Dan Brown|19.95|510|The Lost Symbol
c. 删除数据
Button deleteData = (Button) findViewById(R.id.delete_data);
deleteData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
db.delete("Book", "pages > ?", new String[] {"500"});
}
});
sqlite> select * from book;
1|Dan Brown|10.99|454|The Da Vinci Code
sqlite>
d. 查询数据
Button queryData = (Button) findViewById(R.id.query_data);
queryData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.query("Book", null, null, null, null, null, null);
if(cursor.moveToFirst()){
do {
String author = cursor.getString(cursor.getColumnIndex("author"));
String name = cursor.getString(cursor.getColumnIndex("name"));
int pages = cursor.getInt(cursor.getColumnIndex("pages"));
double price = cursor.getDouble(cursor.getColumnIndex("price"));
Log.d("MainActivity", "book name is " + name);
Log.d("MainActivity", "book author is " + author);
Log.d("MainActivity", "book pages is " + pages);
Log.d("MainActivity", "book price is " + price);
} while (cursor.moveToNext());
}
cursor.close();
}
});
使用SQL操作数据库
p228-229
Extra:使用LitePal操作数据库
参考资料:《第一行代码》郭霖 著