一,数据存储

image.png
数据保存到APP本身

image.png
二,数据存储的分类
共享 SP
SQLite 数据库
Room 数据库
数据库存储如何选择?
比如说登陆时记住密码的单选框:这种配置信息的情况保存在*SP中
比如说你的缓存记录,你上次看电子书看到了55页,那么你将这个app退出去了,下次你再打开这个app还是回到你上次阅读的第55页这种情况也保存在SP中。
SQLite和Room 都是数据库
SQLite更简洁,他是原生数据库,Room更简洁
2.1SP
sharedPreference(存储 UI 状态、用户首选项、应用程序设置)
存储.xml的格式的
比如说 主题 夜间主题和白天主题等等
不能存储太多的信息 是map的格式 key:value的
简单使用
保存
/***
* public SharedPreferences getSharedPreferences(String name, int mode) {
* // 参1:sp名字 参2:保存用的模式(追加Context.MODE_APPEND
* ,覆盖 ontext.MODE_PRIVATE)
* return mBase.getSharedPreferences(name, mode);
* }
* 保存到sp
* @param view
*/
public void SaveToSp(View view) {
Log.d(TAG, "SaveToSp: 单击了");
//设置名字和保存模式
SharedPreferences sp = getSharedPreferences("firstSP", Context.MODE_PRIVATE);
//put 进去
sp.edit().putString("admin","154651651").apply();//apply()之后才会写进xml配置文件中
}

image.png

image.png
获取
public void FromToSp(View view) {
SharedPreferences sp = getSharedPreferences("firstSP", Context.MODE_PRIVATE);
String s = sp.getString("admin", "默认值");//找不到会使用第二个参数的默认值
Toast.makeText(this,""+s,Toast.LENGTH_SHORT).show();
}
真实案例
package com.lifang.data;
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 MainActivity2 extends AppCompatActivity {
SharedPreferences sp;
private EditText username;
private EditText password;
private CheckBox rememberPwd;
private CheckBox antoLogin;
private Button regBtn;
private Button logBtnBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
sp = getSharedPreferences("config", Context.MODE_PRIVATE);
initView();
//第二次打开从SP获取数据进行画面同步
boolean remberpwd = sp.getBoolean("rememberPwd",false);//从sp中去拿这些数据
boolean remberauto = sp.getBoolean("antoLogin",false);//从sp中去拿这些数据
if (remberpwd) {
//记住密码
// 获取sp里面的name和pwd
String username1 = sp.getString("username", " ");
String pwd1 = sp.getString("pwd", " ");
username.setText(username1);
password.setText(pwd1);
rememberPwd.setChecked(true);
}
//自动登录
if (remberauto) {
antoLogin.setChecked(true);
Toast.makeText(this,"已经自动登录",Toast.LENGTH_SHORT).show();
}
}
//初始化控件
private void initView() {
//首先找到控件
username = findViewById(R.id.username);
password = findViewById(R.id.password);
rememberPwd =findViewById(R.id.rememberPwd);
antoLogin= findViewById(R.id.antoLogin);
regBtn = findViewById(R.id.regBtn);
logBtnBtn = findViewById(R.id.logBtn);
//设置监听
logBtnBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String name = username.getText().toString().trim();
String pwd =password.getText().toString().trim();
if (TextUtils.isEmpty(name) ||TextUtils.isEmpty(pwd)) {
Toast.makeText(MainActivity2.this,"用户名或密码不能为空",Toast.LENGTH_SHORT).show();
}else{
//登录成功的操作
// 判断复选框是否选中
if(rememberPwd.isChecked()){
//记住密码 将信息保存到SP中
SharedPreferences.Editor editor = sp.edit();
editor.putString("username", name);
editor.putString("pwd", pwd);
editor.putBoolean("rememberPwd",true);//保存状态
editor.apply();//提交
}
//判断自动登录是否选中
if(antoLogin.isChecked()){
//记住密码 将信息保存到SP中
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean("antoLogin",true);
editor.apply();//提交
}
}
}
});
regBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
}
//按钮点击事件监听
}
2.2 SQLite 数据库
体积小,功能强大
是一个嵌入式数据库,几十KB的大小。
各种类型的数据保存到任何字段中但主键只能是Integer类型
有sqlite.c 的执行程序,动态创建数据库
SQLite 可视化工具
SQLite 的增删改查
android系统封装了一个类sqliteOpenHelper类。进行sql操作
写一个自己的帮助类,继承sqliteOpenHelper。
myhelper
***
* mysqliteOpenHelper 是工具类 单例模式
*
*
* 构造函数私有化 不让外界访问 2.对外提供函数
*/
public class MysqliteOpenHelper extends SQLiteOpenHelper {
//对外提供函数 静态
private static SQLiteOpenHelper mInstance;
public static synchronized SQLiteOpenHelper getmInstance(Context context){
if (mInstance == null) {
mInstance = new MysqliteOpenHelper(context,"data.db",null,1);//
}
return mInstance;
}
//构造函数 数据库必须拥有名字 版本号
private MysqliteOpenHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
//数据库初始化使用的
@Override
public void onCreate(SQLiteDatabase db) {
}
//数据库升级i使用的
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
activity.java 增删改查。
package com.lifang.data;
import static androidx.constraintlayout.helper.widget.MotionEffect.TAG;
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;
import android.widget.Toast;
public class MainActivity3 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
}
//单击生成数据库文件
public void createDB(View view) {
//new 不出来数据库 因为单列模式 只有通过函数来拿 帮助类
SQLiteOpenHelper helper = MysqliteOpenHelper.getmInstance(this);
//数据库文件夹的创建
SQLiteDatabase readableDatabase = helper.getReadableDatabase();
}
// 单击查询数据库文件
public void queryDB(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 anInt = cursor.getInt(0);
int _id = cursor.getInt(cursor.getColumnIndex("_id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
// Log.d(TAG, "queryDB: "+_id+name);
// Toast.makeText(this,_id+name,Toast.LENGTH_SHORT).show();
}
//关闭游标 否则浪费性能
cursor.close();
//关闭数据库
db.close();
}
}
//插入数据
public void insertDB(View view) {
SQLiteOpenHelper helper = MysqliteOpenHelper.getmInstance(this);
SQLiteDatabase db = helper.getWritableDatabase();//写
if (db.isOpen()) {
String sql = "insert into persons(name) values('侯旭')";
db.execSQL(sql);
}
//关闭数据库
db.close();
}
//修改数据
public void updateDB(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[]{"曹畅",2});
}
db.close();
}
//删除数据
public void deleteDB(View view) {
SQLiteOpenHelper helper = MysqliteOpenHelper.getmInstance(this);
SQLiteDatabase db = helper.getWritableDatabase();//写
if (db.isOpen()) {
String sql = "delete from persons where _id=4";
db.execSQL(sql);
}
db.close();
}
}
四,Intent 数据共享
activity间的跳转可以携带数据

例
activity1.java
public void Go2(View view) {
//跳转并将数据传送给2页面
Intent intent = new Intent(this,MainActivity2.class);
intent.putExtra("name","侯旭");
startActivity(intent);
}
activity2
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
// 接收页面1传过来的数据
Intent intent = getIntent();
String name = intent.getStringExtra("name");
Log.d(TAG, "onCreate: "+name);
Toast.makeText(this, name, Toast.LENGTH_SHORT).show();
}
4.1 Intent 传递Bundle对象
零散的对象包装成Bundle对象 。

image.png
//单击跳转
public void To2(View view) {
Intent intent = new Intent(this, MainActivity2.class);
//封装bundle对象
Bundle bundle = new Bundle();
bundle.putString("name","侯旭");
bundle.putChar("sex",'0');
//intent携带bundle对象
intent.putExtras(bundle);
startActivity(intent);
}
接收数据
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
//拆包
Intent intent = getIntent();
//自动拆开bundle对象 在取里面的name sex
String name = intent.getStringExtra("name");
char sex = intent.getCharExtra("sex", '男');
Toast.makeText(this, name+sex, Toast.LENGTH_SHORT).show();
}
传递对象
使用Serializable接口对象来进行
//跳转传递对象
public void to(View view) {
Intent intent = new Intent(this, MainActivity2.class);
//传递对象到mainactivity
// 需要实现Serializable接口 来实现传递对象 所以需要去新建一个
Student student = new Student();
student.id = 9;
student.name = "侯旭";
student.age=28;
intent.putExtra("Student",student);
startActivity(intent);
}
新建类实现接口Serializable
public class Student implements Serializable {
//实现Serializable接口才有资格转递
public int id;
public String name;
public int age;
}
main2acticity.java接收对象
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main4);
Intent intent = getIntent();
Student student = (Student) intent.getSerializableExtra("Student");
Toast.makeText(this, student.name, Toast.LENGTH_SHORT).show();
}
Parcelable
android要实现这个接口来进行对象的传输。