数据存储
数据存储
SP
- 存储配置信息:自动登录,记住密码,主题记录
- 首选项sharedpreference不能存太多东西,程序运行时,首选项里的所有数据会全被加载
- MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package com.example.mysp;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
*
* // 参数1:sp的名字
* // 参数2:sp保存用的模式 常规(覆盖)、追加
* public SharedPreferences getSharedPreferences(String name, int mode) {
* throw new RuntimeException("Stub!");
* }
* @param view
*/
public void saveToSP(View view) {
SharedPreferences sp = getSharedPreferences("SPtest", Context.MODE_PRIVATE);
sp.edit().putString("haha", "哈哈").apply(); // 保存到xml
}
public void getSpData(View view) {
SharedPreferences sp = getSharedPreferences("SPtest", Context.MODE_PRIVATE);
String s = sp.getString("haha", "默认值");
Log.e("xxx", "getSpData: " + s);
}
}
通过传递context获取全局资源
- MyData.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.example.mysp3;
import android.content.Context;
import android.content.SharedPreferences;
public class MyData {
public int number;
private Context context;
public MyData(Context context) {
this.context = context;
}
public void save(){
String name = context.getResources().getString(R.string.my_data);
SharedPreferences sp = context.getSharedPreferences(name, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
String key = context.getResources().getString(R.string.my_key);
editor.putInt(key, number);
editor.apply();
}
public int load(){
String name = context.getResources().getString(R.string.my_data);
SharedPreferences sp = context.getSharedPreferences(name, Context.MODE_PRIVATE);
String key = context.getResources().getString(R.string.my_key);
int x = sp.getInt(key, 0);
number = x;
return x;
}
}
- MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package com.example.mysp3;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* 不能传递this,MyData保存着Activity的引用,Activity会反复创建,但无法销毁
* 会导致内存泄漏
*/
MyData myData = new MyData(getApplicationContext()); // myData具备访问全局资源的能力
myData.number = 1000;
myData.save();
int y = myData.load();
Log.d("xxx", "onCreate: " + y);
}
}
自动登录
- activity_main.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="用户名"/>
<EditText
android:id="@+id/et_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="密码"/>
<EditText
android:id="@+id/et_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:password="true"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<CheckBox
android:id="@+id/cb_rememberpwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="记住密码"/>
<CheckBox
android:id="@+id/cb_autologin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="自动登录"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/bt_register"
android:text="注册"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
<Button
android:id="@+id/bt_login"
android:text="登录"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"/>
</LinearLayout>
</LinearLayout>
- MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package com.example.mysp2;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
SharedPreferences sp;
EditText et_name, et_pwd;
CheckBox cb_rememberpwd, cb_autologin;
Button bt_register, bt_login;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获取首选项
sp = getSharedPreferences("config", Context.MODE_PRIVATE);
initView();
// 第二次打开的时候,送sp获取数据,进行画面同步
boolean rememberpwd = sp.getBoolean("rememberpwd", false);
boolean autologin = sp.getBoolean("autologin", false);
if(rememberpwd){
// 从sp里获取数据,并放到edittext中
String name = sp.getString("name", "");
String pwd = sp.getString("pwd", "");
et_name.setText(name);
et_pwd.setText(pwd);
cb_rememberpwd.setChecked(true);
}
if(autologin){
cb_autologin.setChecked(true);
Toast.makeText(this, "自动登录", Toast.LENGTH_SHORT).show();
}
}
private void initView() {
et_name = findViewById(R.id.et_name);
et_pwd = findViewById(R.id.et_pwd);
cb_rememberpwd = findViewById(R.id.cb_rememberpwd);
cb_autologin = findViewById(R.id.cb_autologin);
bt_register = findViewById(R.id.bt_register);
bt_login = findViewById(R.id.bt_login);
// 设置监听
MyOnClickLister myOnClickLister = new MyOnClickLister();
bt_register.setOnClickListener(myOnClickLister);
bt_login.setOnClickListener(myOnClickLister);
}
private class MyOnClickLister implements View.OnClickListener{
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.bt_register:
break;
case R.id.bt_login:
String name = et_name.getText().toString().trim();
String pwd = et_pwd.getText().toString().trim();
if(TextUtils.isEmpty(name) || TextUtils.isEmpty(pwd)){
Toast.makeText(getApplicationContext(), "用户名或密码未填写", Toast.LENGTH_SHORT).show();
} else {
// 保存密码被勾选后,需要记录账号密码和勾选状态
if(cb_rememberpwd.isChecked()){
SharedPreferences.Editor editor = sp.edit();
editor.putString("name", name);
editor.putString("pwd", pwd);
editor.putBoolean("rememberpwd", true);
editor.apply();
}
// 自动登录被勾选
if(cb_autologin.isChecked()){
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("autologin", true);
editor.apply();
}
}
break;
default:
break;
}
}
}
}
SQLite
- activity_main.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="createDB"
android:text="创建db文件"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="query"
android:text="查询"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="insert"
android:text="插入"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="update"
android:text="修改"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="delete"
android:text="删除"/>
</LinearLayout>
- MySqlOpenHelper.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.example.mysqlite;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import androidx.annotation.Nullable;
// 工具类 单例模式:1.构造函数私有化 2.对外提供函数
public class MySqliteOpenHelper extends SQLiteOpenHelper {
// 2.对外提供函数
private static MySqliteOpenHelper mInstance;
public static synchronized SQLiteOpenHelper getmInstance(Context context){
if(mInstance == null){
mInstance = new MySqliteOpenHelper(context, "xxx.db", null, 1);
}
return mInstance;
}
// 1.构造函数私有化
private MySqliteOpenHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
// 数据库初始化时使用 此函数只会执行一次
@Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
// 创建persons表 _id, name
String sql = "create table persons(_id integer primary key autoincrement, name text)";
sqLiteDatabase.execSQL(sql);
}
// 数据库升级时使用
@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
}
}
- MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package com.example.mysqlite;
import androidx.appcompat.app.AppCompatActivity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void createDB(View view) {
SQLiteOpenHelper helper = MySqliteOpenHelper.getmInstance(this);
// 文件夹的创建
SQLiteDatabase readableDatabase = helper.getReadableDatabase();
}
public void query(View view) {
SQLiteOpenHelper helper = MySqliteOpenHelper.getmInstance(this);
SQLiteDatabase db = helper.getReadableDatabase();
if(db.isOpen()){
// 返回游标
Cursor cursor = db.rawQuery("select * from persons", null);
// 迭代游标,遍历数据
while (cursor.moveToNext()){
// int _id = cursor.getInt(0);
int _id = cursor.getInt(cursor.getColumnIndex("_id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
Log.d("xxx", "query: " + _id + " " + name);
// 关闭
cursor.close();
db.close();
}
}
}
public void insert(View view) {
SQLiteOpenHelper helper = MySqliteOpenHelper.getmInstance(this);
SQLiteDatabase db = helper.getWritableDatabase();
if(db.isOpen()){
String sql = "insert into persons(name) values('haha')";
db.execSQL(sql);
db.close();
}
}
public void update(View view) {
SQLiteOpenHelper helper = MySqliteOpenHelper.getmInstance(this);
SQLiteDatabase db = helper.getWritableDatabase();
if(db.isOpen()){
String sql = "update persons set name=? where _id=?";
db.execSQL(sql, new Object[]{"xixi", 2});
db.close();
}
}
public void delete(View view) {
SQLiteOpenHelper helper = MySqliteOpenHelper.getmInstance(this);
SQLiteDatabase db = helper.getWritableDatabase();
if(db.isOpen()){
String sql = "delete from persons where _id =?";
db.execSQL(sql, new Object[]{3});
db.close();
}
}
}
Room
- 导入依赖:implementation ‘androidx.room:room-runtime:2.2.5’
- Student.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
package com.example.myroom;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
@Entity
public class Student {
// 主键唯一 自增id
@PrimaryKey(autoGenerate = true)
private int id;
private String name;
private int age;
// 不需要id
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
- StudentDao.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.example.myroom;
import androidx.room.Dao;
import androidx.room.Delete;
import androidx.room.Insert;
import androidx.room.Query;
import androidx.room.Update;
import java.util.List;
@Dao
public interface StudentDao {
// 增
@Insert
void insertStudents(Student... students);
// 改
@Update
void updateStudents(Student... students);
// 条件删除
@Delete
void deleteStudents(Student... students);
// 删除所有 @Delete单个条件删除
@Query("DELETE FROM Student")
void deleteAllStudents();
// 查询所有
@Query("SELECT * FROM Student ORDER BY ID DESC")
List<Student> getAllStudent();
}
- StudentDatabase.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package com.example.myroom;
import android.content.Context;
import androidx.room.Database;
import androidx.room.Room;
import androidx.room.RoomDatabase;
@Database(entities = {Student.class}, version = 1, exportSchema = false)
public abstract class StudentDatabase extends RoomDatabase {
// 用户只需要操作dao 必须暴露dao
public abstract StudentDao getStudentDao();
// 单例模式 反对db
private static StudentDatabase INSTANCE;
public static synchronized StudentDatabase getInstance(Context context){
if(INSTANCE == null){
INSTANCE = Room.databaseBuilder
(context.getApplicationContext(), StudentDatabase.class, "student_database")
// 默认异步线程
// 可以强制开启主线程使用
//.allowMainThreadQueries()
.build();
}
return INSTANCE;
}
}
- DBEngine.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
package com.example.myroom.manager;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import com.example.myroom.Student;
import com.example.myroom.StudentDao;
import com.example.myroom.StudentDatabase;
import java.util.List;
public class DBEngine {
private StudentDao studentDao;
public DBEngine(Context context){
StudentDatabase studentDatabase = StudentDatabase.getInstance(context);
studentDao = studentDatabase.getStudentDao();
}
// 对dao的增删改查
// 插入
public void insertStudents(Student... students){
new InsertAsyncTask(studentDao).execute(students);
}
// 更新
public void updateStudents(Student... students){
new UpdateAsyncTask(studentDao).execute(students);
}
// 条件删除
public void deleteStudents(Student... students){
new DeleteAsyncTask(studentDao).execute(students);
}
// 全部删除
public void deleteAllStudents(){
new DeleteAllAsyncTask(studentDao).execute();
}
// 全部查询
public void queryAllStudents(){
new QueryAllAsyncTask(studentDao).execute();
}
// 异步操作
// 插入
static class InsertAsyncTask extends AsyncTask<Student, Void, Void>{
private StudentDao dao;
public InsertAsyncTask(StudentDao studentDao){
dao = studentDao;
}
@Override
protected Void doInBackground(Student... students) {
dao.insertStudents(students);
return null;
}
}
// 更新
static class UpdateAsyncTask extends AsyncTask<Student, Void, Void>{
private StudentDao dao;
public UpdateAsyncTask(StudentDao studentDao){
dao = studentDao;
}
@Override
protected Void doInBackground(Student... students) {
dao.updateStudents(students);
return null;
}
}
// 条件删除
static class DeleteAsyncTask extends AsyncTask<Student, Void, Void>{
private StudentDao dao;
public DeleteAsyncTask(StudentDao studentDao){
dao = studentDao;
}
@Override
protected Void doInBackground(Student... students) { // 条件删除
dao.deleteStudents(students);
return null;
}
}
// 全部删除
static class DeleteAllAsyncTask extends AsyncTask<Void, Void, Void>{
private StudentDao dao;
public DeleteAllAsyncTask(StudentDao studentDao){
dao = studentDao;
}
@Override
protected Void doInBackground(Void... voids) {
dao.deleteAllStudents();
return null;
}
}
// 全部查询
static class QueryAllAsyncTask extends AsyncTask<Void, Void, Void>{
private StudentDao dao;
public QueryAllAsyncTask(StudentDao studentDao){
dao = studentDao;
}
@Override
protected Void doInBackground(Void... voids) {
List<Student> allStudent = dao.getAllStudent();
for (Student student : allStudent) {
Log.d("xxx", "doInBackground: " + student.toString());
}
return null;
}
}
}
- activity_main.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="插入"
android:onClick="insertAction"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="修改"
android:onClick="updateAction"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="删除"
android:onClick="deleteAction"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="查询"
android:onClick="queryAction"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="全部删除"
android:onClick="deleteAllAction"/>
</LinearLayout>
- MainActivity.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.example.myroom;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import com.example.myroom.manager.DBEngine;
public class MainActivity extends AppCompatActivity {
private DBEngine dbEngine;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbEngine = new DBEngine(this);
}
// 插入
public void insertAction(View view) {
Student s1 = new Student("张三", 20);
Student s2 = new Student("张四", 21);
Student s3 = new Student("张五", 22);
dbEngine.insertStudents(s1, s2, s3);
}
// 更新
public void updateAction(View view) {
Student s = new Student("王五", 30);
s.setId(2);
dbEngine.updateStudents(s);
}
// 条件删除
public void deleteAction(View view) {
Student student = new Student(null, 0);
student.setId(2);
dbEngine.deleteStudents(student);
}
// 全部查询
public void queryAction(View view) {
dbEngine.queryAllStudents();
}
// 全部删除
public void deleteAllAction(View view) {
dbEngine.deleteAllStudents();
}
}
本文由作者按照 CC BY 4.0 进行授权