以下是本人开发Android过程中涉及数据储存的处理:

  • 配置型数据:SharedPreferences,比如记录用户的行为配置(记住密码、背景、字体等等)
  • 复杂关系型数据:SQLite
  • 多媒体文件、大型文本等:File,常存储于SD卡,可以根据具体需求存放在/data/data下

遵循:简化操作、多次复用、把更多尽力用在业务处理。

推荐:SharedPreferences 和 File可以根据自己的需求封装成自己的工具类,SQLite可利用成熟的ORM框架,强烈推荐greenDAO或者是ORMLite。

下面是我自己的一些工具类,仅供参考。

SharedStore,封装了SharedPreferences的基本操作

package com.example.yummy.tools;

import android.content.Context;
import android.content.SharedPreferences;

/**
 * Created by yummy on 2015/9/28.
 * 数据存储在/data/data/<packagename>/shared_preds目录下
 * 设计思路:
 * 1. SharedPreferences底层为单例模式
 * 2. 读写特定文件所需的Editor对象和SharedPreferences对象两者间有绑定关系
 */
public class SharedStore {

    /**
     * @param context 当前上下文
     * @param fileName 存储文件名
     * @param Mode  一般为Context.MODE_PRIVATE
     * @return SharedPreferences对象
     */
    public static SharedPreferences getSharedPreferences(Context context,String fileName,int Mode) {
        return context.getSharedPreferences(fileName,Context.MODE_PRIVATE);
    }


    /**
     * @param context 当前上下文
     * @param fileName 存储文件名
     * @param Mode 一般为Context.MODE_PRIVATE
     * @return SharedPreferences.Editor对象
     */
    public static SharedPreferences.Editor getEditor(Context context,String fileName,int Mode){
        return getSharedPreferences(context,fileName,Mode).edit();
    }
}


FileStore,封装了文件读写的基本操作,包括本地和SDcard

package com.example.yummy.tools;

import android.content.Context;
import android.os.Environment;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

/**
 * Created by yummy on 2015/9/28.
 * 采用File文件存储,包括两种
 * 1. 保存在/data/data下,一般这种比较少
 * 2. 保存在sdcard下,比较常用
 * 策略:一般配置文件可以写在Sharedpre,大的文件一般存在sd卡,关系比较紧密/复杂的关联信息写在Sqlite
 * 这里的文件保存对象String,如下载的一般都是流,如复制的一般是file,操作大同小异,工具类可以自己改写
 */
public class FileStore {

    /**
     * 保存在/data/data/<packagename>/files中
     * @param data 目标字符串
     * @param fileName 保存文件名
     * @param Mode 写入模式,一共有三种
     * @return 返回操作是否成功
     * MODE_PRIVATE、MODE_APPEND 和 MODE_ENABLE_WRITE_AHEAD_LOGGING
     * 第一种为默认操作模式,表示写入文件的时候会覆盖原文件内容
     * 第二种为追加内容模式,表示写入文件的时候把内容追加在文件后面
     */
    public static boolean writeToFile(Context context,String data,String fileName,int Mode){

        FileOutputStream out = null;
        BufferedWriter writer = null;
        try {
            out = context.openFileOutput(fileName, Context.MODE_ENABLE_WRITE_AHEAD_LOGGING);
            writer = new BufferedWriter(new OutputStreamWriter(out));
            writer.write(data);
            return true;
        }catch (IOException e) {
            e.printStackTrace();
        }finally
        {
            try {
                if(writer != null) {
                    writer.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        return false;
    }

    /**
     *读取的文件位于保存在/data/data/<packagename>/files中
     * @param context 返回内容
     * @param fileName 读取文件的文件名
     * @return 返回文件内容
     */
    public static String readByFile(Context context,String fileName){

        FileInputStream in = null;
        BufferedReader reader = null;
        StringBuilder content = new StringBuilder();
        try{
            in = context.openFileInput(fileName);
            reader = new BufferedReader(new InputStreamReader(in));
            String line = null;
            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();
    }



    /**
     * 判断SdCard是否存在
     * 操作sd卡需要的权限
     * <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"></uses-permission>
     * <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
     * @param fileName 待写文件名
     * @param filecontent 写入内容
     * @return 返回操作是否成功
     */
    public static boolean witreToSdcard(String fileName,String filecontent) {

        FileOutputStream out = null;
        BufferedWriter writer = null;
        File file = null;
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
            try {
                //这里为SD卡根目录,可以自行更改file路径
                file = new File(Environment.getExternalStorageDirectory().toString()+'/'+fileName);
                out = new FileOutputStream(file);
                writer = new BufferedWriter(new OutputStreamWriter(out));
                writer.write(filecontent);
                return true;
            }catch (FileNotFoundException e){
                e.printStackTrace();
            }catch (IOException e){
                e.printStackTrace();
            } finally {
                try {
                    if (writer != null) {
                        writer.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }


    /**
     * 读取sdcard的文件
     * @param fileName
     * @return 返回文件内容
     */
    public static String readBySdcard(String fileName){

        FileInputStream in = null;
        BufferedReader reader = null;
        StringBuilder content = new StringBuilder();
        File file = null;
        try{
            file = new File(Environment.getExternalStorageDirectory().toString()+'/'+fileName);
            in = new FileInputStream(file);
            reader = new BufferedReader(new InputStreamReader(in));
            String line = null;
            while((line = reader.readLine()) != null){
                content.append(line);
            }
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }finally {
            if(reader != null){
                try{
                    reader.close();
                }catch (IOException e){
                    e.printStackTrace();
                }
            }
        }
        return content.toString();
    }

}

SQLite,封装了基本的数据库操作,我仅用来了解熟悉Android提供的API功能,实际项目中不推荐使用,推荐使用ORM框架

package com.example.yummy.tools;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/**
 * 该SQLiteStore类只是简单的介绍了SQLite核心的功能,包括CRUD以及升级策略,API含有大量函数可以直接源码参考
 * 实际应用中,如果CRUD一般都会转化层bean类的形式操作,一般整个过程可以设计,写接口等
 * 不过Android提供了十分好用的ORM开源框架来简化数据库操作
 * 常用有:greenDAO / ORMLite 强烈推荐这两个
 * Created by yummy on 2015/9/29.
 */
public class SQLiteStore {

    class MyDatabaseHelper extends SQLiteOpenHelper{

        //定义sql语句
        public static final String CREATR_TABLE_1 = "一般定义建表的sql语句";
        private SQLiteDatabase reader;
        private SQLiteDatabase writer;

        /**
         * 两个构造器,通常使用前者,后者多了个错误处理接口对象
         * @param context 上下文
         * @param name 数据库文件 *.db
         * @param factory 查询结果游标
         * @param version 数据库版本
         */
        public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
            super(context, name, factory, version);
            reader = getReadableDatabase();
            writer = getWritableDatabase();
        }

        public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {
            super(context, name, factory, version, errorHandler);
            reader = getReadableDatabase();
            writer = getWritableDatabase();
        }


        /**
         * 如果sql文件*.db存在的话,则不会调用该方法
         * @param db 数据库操作对象
         */
        @Override
        public void onCreate(SQLiteDatabase db) {
            db.execSQL(CREATR_TABLE_1);
            //第二版添加的升级语句
            //第三版添加的升级语句
        }


        /**
         * 升级策略:如果第一版app数据库版本号为1,现在有第二版app,数据库版本号为2,默认从1-N,N为升级了N-1次
         * 1.如果用户安装直接安装第二版本,则会直接执行onCreate方法
         * 2.如果用户是从第一版本覆盖安装第二版本的话,则会进入升级程序,执行第二版升级语句
         * @param db 数据库对象
         * @param oldVersion 旧版本号
         * @param newVersion 新版本号
         */
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            switch (oldVersion){
                case 1:
                    //第二版添加的升级语句
                case 2:
                    //第三版添加的升级语句
            }

        }


        /**
         * 插入操作
         * @param table 表名
         * @param nullColumnHack 未指定添加数据的时候添加的备用数据
         * @param values 添加数据
         * @return 返回插入数据的行号ID,失败返回-1
         */
        public long insert(String table, String nullColumnHack, ContentValues values){
            return writer.insert( table,  nullColumnHack,  values);
        }


        /**
         * 更新操作
         * @param table 表名
         * @param values 把该数据更新到参数三四决定的哪些行上
         * @param whereClause 指明约束条件
         * @param whereArgs  为参数三的约束条件赋值,参数三四共同决定了更新哪些行
         * @return 返回更新了多少行
         */
        public int update(String table, ContentValues values, String whereClause, String[] whereArgs){
            return writer.update(table, values, whereClause, whereArgs);
        }

        /**
         * 删除操作
         * @param table 表名
         * @param whereClause 指明约束条件
         * @param whereArgs  为参数二的约束条件赋值,参数二三共同决定了删除哪些行
         * @return 返回删除了多少行,失败返回0
         */
        public int delete(String table, String whereClause, String[] whereArgs){
            return writer.delete(table, whereClause, whereArgs);
        }


        /**
         * 查询表名
         * @param table 查询表名
         * @param columns 查询哪几列,默认所有列
         * @param selection 指明约束条件
         * @param selectionArgs 为约束条件赋值,参数三四共同决定查询哪些行
         * @param groupBy 指定groupBy哪些列,默认不对结果进行该操作
         * @param having 设置过滤条件,对参数五分组后进行过滤
         * @param orderBy 指定对查询结果进行排序,默认不排序
         * @return 返回结果集 Cursor对象
         */
        public Cursor query(String table, String[] columns, String selection,
                          String[] selectionArgs, String groupBy, String having,
                          String orderBy){

           return reader.query( table,  columns,  selection,
                    selectionArgs,  groupBy,  having,
                    orderBy);
        }

    }
}




Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐