美文网首页
Android入门05 -- 数据存储

Android入门05 -- 数据存储

作者: YanZi_33 | 来源:发表于2022-03-08 09:58 被阅读0次
    • Android的数据存储方式有:SharedPreferences,File,SQLite,下面来详细介绍每种数据存储的特点与使用;

    SharedPreferences

    • SharedPreferences是Android平台上一个轻量级的数据存储辅助类,用来保存应用的一些常用配置,它提供了string,set,int,long,float,boolean六种数据类型,最终数据是以xml形式进行存储,在应用中通常做一些简单数据的持久化缓存
    SharedPreferences的使用注意事项:
    • 不要存放大的key和value在SharedPreferences中,否则会一直存储在内存中得不到释放,内存使用过高会频发引发GC,导致界面丢帧甚至ANR;
    • 不相关的配置选项最好不要放在一起,单个文件越大读取速度则越慢;
    • 读取频繁的key和不频繁的key尽量不要放在一起(如果整个文件本身就较小则忽略,为了这点性能添加维护得不偿失);
    • 不要每次都edit,因为每次都会创建一个新的EditorImpl对象,最好是批量处理统一提交,否则edit().commit每次创建一个EditorImpl对象并且进行一次IO操作,严重影响性能;
    • commit发生在UI线程中apply发生在工作线程中,对于数据的提交最好是批量操作统一提交,虽然apply发生在工作线程(不会因为IO阻塞UI线程)但是如果添加任务较多也有可能带来其他严重后果(参照ActivityThread源码中handleStopActivity方法实现)
    • 尽量不要存放json和html,这种可以直接文件缓存;
    • SharedPreferences不能跨进程通信 Context.PROCESS
    • 最好提前初始化SharedPreferences,避免第一次创建时读取文件线程未结束而出现等待情况;
    SharedPreferences的创建
    • 创建SharedPreferences有两种方式:
      • 第一种:调用Context对象的getSharedPreferences()方法;
      • 第二种:调用Activity对象的getPreferences()方法;
    • 区别在于:第一种方式获得的可以被同一应用程序下的组件共用,但是第二种方式获得的只可以在该Activity下使用
    SharedPreferences的操作模式
    • MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下写入的内容会覆盖原文件的内容;
    • MODE_APPEND:检查文件是否存在,存在就往文件追加内容,否则就创建新文件;
    • MODE_WORLD_READABLE:表示当前文件可以被其他应用读取;
    • MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入;
    SharedPreferences的增删改查
    • 封装成单例类SFSharedPreferences,代码实现如下:
    package com.example.yyshop.general.database;
    
    import android.content.Context;
    import android.content.SharedPreferences;
    
    import static android.content.Context.MODE_PRIVATE;
    
    public class SFSharedPreferences {
    
        private static volatile SFSharedPreferences mInstance;
        private SharedPreferences sharedPreferences;
        private SharedPreferences.Editor editor;
    
        public static synchronized SFSharedPreferences getInstance(Context context){
            if (mInstance == null) {
                synchronized (SFSharedPreferences.class) {
                    if (mInstance == null) {
                        mInstance = new SFSharedPreferences(context);
                    }
                }
            }
            return mInstance;
        }
    
        private SFSharedPreferences(Context context){
            if (sharedPreferences == null) {
                //创建SharedPreferences实例对象
                sharedPreferences = context.getSharedPreferences("config",MODE_PRIVATE);
                editor = sharedPreferences.edit();
            }
        }
    
        //存储数据
        public void save(String key,String data) {
            editor.putString(key,data);
            editor.commit();
        }
    
        //读取数据
        public String read(String key){
            String data = sharedPreferences.getString(key,"");
            return data;
        }
    
        //删除数据
        public void remove(String key) {
            editor.remove(key);
            editor.commit();
        }
    
        //清空所有数据
        public void clear() {
            editor.clear();
            editor.commit();
        }
    }
    
    • 注意⚠️:SharedPreferences在存储,删除,清空数据时,都是通过editor对象进行操作的,且必须调用editor.commit(),进行提交操作才能生效;
    • 外界调用代码如下:
    public class SFShopCarFragment extends SFBaseFragment {
        @Override
        protected void initUI() {
            Button button = find(R.id.shopcar_button);
            button.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(getActivity(), SFShopDetailActivity.class);
                    startActivity(intent);
    
                    SFSharedPreferences.getInstance(getContext()).save("name","yanzi");
                    String name = SFSharedPreferences.getInstance(getActivity()).read("name");
                    Log.i("SFShopCarFragment",name);
                }
            });
        }
    
        @Override
        protected int getLayoutId() {
            return R.layout.fragment_shopcar;
        }
    }
    
    • SharedPreferences存储数据的位置为:/data/data/项目包/shared_prefs/名称.xml,可通过Device File Explore进行查看,如下所示:
      image.png

    SQLite数据库

    • SQLite是一款轻量型数据库,广泛使用于移动端;
    • 在Android中,系统封装了一个SQLite数据库的抽象类SQLiteOpenHelper,我们需要自定义一个子类继承自抽象类SQLiteOpenHelper,实现其相关的抽象方法,然后进行数据库的增删改查操作;
    抽象类SQLiteOpenHelper的两个抽象方法
    • 第一个抽象方法是:onCreate方法,在实例化继承自SQLiteOpenHelper的子类时调用(创建数据库时),在这个方法中我们可进行数据库表的创建,此方法只会调用一次;
    • 第二个抽象方法是:onUpgrade方法,在数据库升级时使用;
    • 有关数据库的增删改查操作,见如下代码:
    package com.example.yyshop.general.database;
    
    import android.content.Context;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.util.Log;
    import com.example.yyshop.home.model.SFGoodModel;
    import java.util.ArrayList;
    import java.util.List;
    
    public class SFSQLShopCarHelper extends SQLiteOpenHelper {
    
        //数据库版本号
        private static Integer Version = 1;
    
        //数据库的名称
        private static final String DATA_BASE_NAME = "shopcar.db";
    
        //购物车商品表
        private static final String SHOP_CAR_TABLE_NAME = "t_goods";
    
        //单例对象
        private static volatile SFSQLShopCarHelper mInstance;
    
        //在SQLiteOpenHelper的子类当中,必须有该构造函数
        private SFSQLShopCarHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
            //必须通过super调用父类当中的构造函数
            super(context, name, factory, version);
        }
    
        private SFSQLShopCarHelper(Context context, String name, int version) {
            this(context,name,null,version);
        }
    
        private SFSQLShopCarHelper(Context context, String name) {
            this(context, name, Version);
        }
    
        private SFSQLShopCarHelper(Context context) {
            this(context,DATA_BASE_NAME);
        }
    
        public static synchronized SFSQLShopCarHelper getInstance(Context context) {
            if (mInstance == null) {
                synchronized (SFSharedPreferences.class) {
                    if (mInstance == null) {
                        mInstance = new SFSQLShopCarHelper(context);
                    }
                }
            }
            return mInstance;
        }
    
        @Override
        public void onCreate(SQLiteDatabase db) {
            Log.i("SFSQLShopCarHelper","开始创建数据库表 t_shopCar");
            createTable(db);
            Log.i("SFSQLShopCarHelper","完成创建数据库表 t_shopCar");
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            //数据库升级
    
        }
    
        //创建表
        private void createTable(SQLiteDatabase database){
            String create_shop_car_goods = "create table if not exists " + SHOP_CAR_TABLE_NAME +"(id integer primary key autoincrement,goodId text,goodName text,goodPic text,goodPrice text)";
            try {
                database.execSQL(create_shop_car_goods);
            } catch (Exception e) {
                e.printStackTrace();
                Log.i("SFSQLShopCarHelper", "创表shop_car_goods -- 出现异常");
            };
        }
    
        //插入单条数据
        public void insert(SFGoodModel model){
            SQLiteDatabase database = getWritableDatabase();
    
            String goodId = model.getGoodsId();
            String goodName = model.getGoodsName();
            String goodPic = model.getComPic();
            String goodPrice = model.getPrice();
    
            String insert = "insert into " + SHOP_CAR_TABLE_NAME + "(goodId,goodName,goodPic,goodPrice)values" + "('"+goodId+"','"+goodName+"','"+goodPic+"','"+goodPrice+"')";
            database.execSQL(insert);
            Log.i("SFShopCarFragment",insert);
            Log.i("SFShopCarFragment","插入了1条数据");
            database.close();
        }
    
        //查询所有商品
        public List<SFGoodModel> select(){
            SQLiteDatabase database = getReadableDatabase();
            List<SFGoodModel> models = new ArrayList<>();
    
            String select = "select * from " + SHOP_CAR_TABLE_NAME;
            Cursor cursor = database.rawQuery(select,null);
    
            while (cursor.moveToNext()) {
                String id = cursor.getString(cursor.getColumnIndex("id"));
                String goodName = cursor.getString(cursor.getColumnIndex("goodName"));
                String goodId = cursor.getString(cursor.getColumnIndex("goodId"));
                String goodPic = cursor.getString(cursor.getColumnIndex("goodPic"));
                String goodPrice = cursor.getString(cursor.getColumnIndex("goodPrice"));
    
                SFGoodModel model = new SFGoodModel();
                model.setGoodsId(goodId);
                model.setGoodsName(goodName);
                model.setGoodsId(goodPic);
                model.setGoodsId(goodPrice);
                models.add(model);
                Log.i("SFShopCarFragment", id + " " + goodName + " " + goodId + " " + goodPic + " " + goodPrice);
            }
            //关闭数据库
            cursor.close();
            database.close();
            return models;
        }
    
        //删除指定商品
        public void delete(SFGoodModel model) {
            SQLiteDatabase database = getReadableDatabase();
            String delete = "delete from " + SHOP_CAR_TABLE_NAME + " where goodid = '"+model.getGoodsId()+"'";
            try {
                database.execSQL(delete);
                Log.i("SFSQLShopCarHelper","成功删除一条数据");
                database.close();
            } catch (Exception e) {
                e.printStackTrace();
                Log.i("SFSQLShopCarHelper", "删除指定数据 -- 出现异常");
                database.close();
            }
        }
    
        //删除所有商品
        public void deleteAll(){
            SQLiteDatabase database = getReadableDatabase();
            String delete = "delete from " + SHOP_CAR_TABLE_NAME;
            try {
                database.execSQL(delete);
                Log.i("SFSQLShopCarHelper","成功删除所有数据");
                database.close();
            } catch (Exception e) {
                e.printStackTrace();
                Log.i("SFSQLShopCarHelper", "删除所有数据 -- 出现异常");
                database.close();
            }
        }
    }
    
    • 上述自定义子类SFSQLShopCarHelper继承自SQLiteOpenHelper系统抽象类;
    • 在进行数据库的增删改查时,首先是获取database,调用getReadableDatabase()或者getWritableDatabase()方法,相当于打开数据库,在执行完数据库的增删改查操作之后,调用close()方法,关闭数据库;

    相关文章

      网友评论

          本文标题:Android入门05 -- 数据存储

          本文链接:https://www.haomeiwen.com/subject/fuxarrtx.html