Android几种数据存储的方式

来源:互联网 发布:文章数据库设计 编辑:程序博客网 时间:2024/06/08 06:17

这是我的第一篇博客,前言也不多说什么,有点小激动,还是直接进入正题吧。

RT,今天要写的是安卓几种数据存储的方式。

一,首先我想到的就是创建本地数据库,前段时间刚用了一个叫GreenDao的第三方,他的用法很简单,这里我直接贴上操作步骤和代码,网上很多教程(我也是跟着教程来,然后再自己加以琢磨)。

(下面这个是基本配置网上抄的)

一. 在 ANDROID 工程中配置「GREENDAO GENERATOR」模块

  1. 在 .src/main 目录下新建一个与 java 同层级的「java-gen」目录,用于存放由 greenDAO 生成的 Bean、DAO、DaoMaster、DaoSession 等类。 

  2. 配置 Android 工程(app)的 build.gradle,如图分别添加 sourceSets 与dependencies。 

1
2
3
4
5
sourceSets {
        main {
            java.srcDirs = ['src/main/java''src/main/java-gen']
        }
    }
1
compile 'de.greenrobot:greendao:2.1.0'(这里注意下版本要高) 


二. 新建「GREENDAO GENERATOR」模块 (纯 JAVA 工程)

  1. 通过 File -> New -> New Module -> Java Library -> 填写相应的包名与类名 -> Finish.

  2. 在另外的模块里面的gradle配置 daoexamplegenerator 工程的 build.gradle,添加 dependencies.

  3.  

1
compile 'de.greenrobot:greendao-generator:1.3.1'
  1. 编写 ExampleDaoGenerator 类,注意: 我们的 Java 工程只有一个类,它的内容决定了「GreenDao Generator」的输出,你可以在这个类中通过对象、关系等创建数据库结构,下面我将以注释的形式详细讲解代码内容。

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
public class ExampleDaoGenerator {
    public static void main(String[] args) throws Exception {
        // 正如你所见的,你创建了一个用于添加实体(Entity)的模式(Schema)对象。
        // 两个参数分别代表:数据库版本号与自动生成代码的包路径。
        Schema schema = new Schema(1, "me.itangqi.greendao");//版本号,生成代码的包路径
//      当然,如果你愿意,你也可以分别指定生成的 Bean 与 DAO 类所在的目录,只要如下所示:
//      Schema schema = new Schema(1, "me.itangqi.bean");
//      schema.setDefaultJavaPackageDao("me.itangqi.dao");
 
        // 模式(Schema)同时也拥有两个默认的 flags,分别用来标示 entity 是否是 activie 以及是否使用 keep sections。
        // schema2.enableActiveEntitiesByDefault();
        // schema2.enableKeepSectionsByDefault();
 
        // 一旦你拥有了一个 Schema 对象后,你便可以使用它添加实体(Entities)了。
        addNote(schema);
 
        // 最后我们将使用 DAOGenerator 类的 generateAll() 方法自动生成代码,此处你需要根据自己的情况更改输出目录(既之前创建的 java-gen)。
        // 其实,输出目录的路径可以在 build.gradle 中设置,有兴趣的朋友可以自行搜索,这里就不再详解。
        new DaoGenerator().generateAll(schema, "/Users/tangqi/android-dev/AndroidStudioProjects/MyGreenDAO/app/src/main/java-gen");//这句必须要
    }
 
    /**
     * @param schema
     */
    private static void addNote(Schema schema) {
        // 一个实体(类)就关联到数据库中的一张表,此处表名为「Note」(既类名)
        Entity note = schema.addEntity("Note");//创建关联实体类的表,输入类的名字
        // 你也可以重新给表命名
        // note.setTableName("NODE");
 
        // greenDAO 会自动根据实体类的属性值来创建表字段,并赋予默认值
        // 接下来你便可以设置表中的字段:
        note.addIdProperty();//开始设置字段了
        note.addStringProperty("text").notNull();
        // 与在 Java 中使用驼峰命名法不同,默认数据库中的命名是使用大写和下划线来分割单词的。
        // For example, a property called “creationDate” will become a database column “CREATION_DATE”.
        note.addStringProperty("comment");
        note.addDateProperty("date");
    }
}

三. 生成 DAO 文件(数据库)

  • 执行 generator 工程,如一切正常,你将会在控制台看到如下日志,并且在主工程「java-gen」下会发现生成了DaoMaster、DaoSession、NoteDao、Note共4个类文件。 

  • 然后在studio右键点击 run```的 他就会出来一串write之类的东西主要看看是否有结果生成  不为0就好如我的   Processed 3 entities in 1010ms

如果在此处出错,你可以依据错误日志进行排查,主要看是否输出目录存在?其他配置是否正确?等

四. 在 ANDROID 工程中进行数据库操作

接下来的操作是在db(我喜欢这么命名)文件下新建一个openhelper类,里面有实力化的方法和一些增删改查的方法

举个例子(下面的内容和上面ExampleDaoGenerator类无关·····

//实例化
public Anamial(Context context) {    alarmBeanList=new ArrayList<>();    try{        alarmBean= GetDaoSession.getDaoSession(context,"alarm.db").getAlarmBeanDao();    }catch (Exception e){        e.printStackTrace();    }}public static  AlarmDaoHelper getInstance(Context context){    if (alarmDaoHelper==null){        synchronized (AlarmDaoHelper.class){            if (alarmDaoHelper==null){                alarmDaoHelper=new AlarmDaoHelper(context);            }        }    }return alarmDaoHelper;}
/*********增加数据*********/@Overridepublic <T> void addDada(T data) {if (alarmBean!=null&&data!=null){    alarmBean.insertOrReplace((AlarmBean) data);    }}
/****删除数据****/

@Overridepublic void deleteData(Long id) {//这个id是要在你的生成的那个类里面的    if (alarmBean!=null&&id!=null){        alarmBean.deleteByKey(id);    }
//查询
/** * get alarms by startdate * * @param startDate * @return */public List<AlarmBean> getAlarmsByStartDate(String startDate) {    if (startDate != null) {        Query query = alarmBean.queryBuilder()                .where(AlarmBeanDao.Properties.StartDate.eq(startDate))                .orderAsc(AlarmBeanDao.Properties.RelshowTime)//插入的意思                .build();        List<AlarmBean> notes = query.list();        QueryBuilder.LOG_SQL = true;        QueryBuilder.LOG_VALUES = true;        return notes;    }    return emptyList;}
//更新数据的话建议根据条件查询到数据之后,获得他对应的ID 在通过ID把原来的删除掉,再添加一条数据,这样就更新好了。



二,要讲的是偏好设置sharedPreferences

可以用来保存用户的一些简单的使用习惯信息,偏好设置实质上是/data/data/包/share_prefs/路径下的一个xml文件,文件名就是偏好设置的名字。

如何使用ShardPreference将数据持久化:

通过getSharedPreferences(String name,int mode)来获取一个SharedPreferences对象,一个应用可以有多个偏好设置文件,第一个参数决定用哪个,第二个参数表示模式,一般用MODE_PRIVATE,只能本应用来读(全局可读、全局可写这些模式不建议使用)

保存: 调用SharedPreferences对象的edit()方法,开始修改它,这个方法会返回一个Editor对象,我们调用这个对象的putXXX方法往里面放简单的信息,在写好后再调用commit()方法来确认

Activity中存入数据

//获取一个私有的偏好设置,名字为demo

SharedPreferences pref = getSharedPreferences("demo"MODE_PRIVATE);

//获取一个编辑器,开始对这个偏好设置进行读写操作

Editor editor = pref.edit();

//往编辑器里存放键值对信息

editor.putString("info""w");

editor.putInt("num", 1000);

//确认,使上述信息生效

editor.commit();//东西一多的话用apply提交(另外开一个线程提交,异步操作,而commit有结果,apply没有结果)

Activity中获取数据

获取: 调用SharedPreferences对象的getXXX方法根据键获取值

SharedPreferences pref = getSharedPreferences("demo"MODE_PRIVATE);

//直接通过偏好设置对象获取存在其中的信息,通过键获取值

//第一个参数就是键名,第一个是默认值(没有存的情况下起作用)

String info = pref.getString("info""信息还未存入");

int number = pref.getInt("num", 0);//是什么数据类型就get什么类型

三.存到应用程序的Data File目录

在内置存储器中,在应用程序目录中,可以保存稍微大些的文件信息,在应用程序被删除时,这个目录及内部的所有内容也会连带删除(在/data/data/包名/files目录下)

写文件示例:

public void save()
 {
 
        try {
            FileOutputStream outStream=this.openFileOutput("a.txt",Context.MODE_WORLD_READABLE);//openFileOutput(): 获取一个字节输出流,向内置文件写
            outStream.write(text.getText().toString().getBytes());
            outStream.close();//关闭流
        } catch (FileNotFoundException e) {
            return;
        }
        catch (IOException e){
            return ;
        }
 
 } 
openFileOutput()方法的第一参数用于指定文件名称,不能包含路径分隔符“/” ,如果文件不存在,Android 会自动创建它。
创建的文件保存在/data/data//files目录,如: /data/data/cn.itcast.action/files/itcast.txt ,
读取文件示例:
public void load()
{
    try {
        FileInputStream inStream=this.openFileInput("a.txt");//openFileInput(): 方法获取一个字节输入流,用来读
        ByteArrayOutputStream stream=new ByteArrayOutputStream();
        byte[] buffer=new byte[1024];
        int length=-1;
while((length=inStream.read(buffer))!=-1)   {
            stream.write(buffer,0,length);
        }
 
        stream.close();
        inStream.close();
        text.setText(stream.toString());
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    catch (IOException e){
        return ;
    }
 
}  
对于私有文件只能被创建该文件的应用访问,如果希望文件能被其他应用读和写,可以在创建文件时,指定Context.MODE_WORLD_READABLE和Context.MODE_WORLD_WRITEABLE权限。(权限记得加上不然很蛋疼)

四.存到应用程序的Data cache目录缓存

在内置存储器中,在应用程序目录中,也可以保存大文件,和File目录的区别是,在存储空间吃紧的情况下,这个目录下的内容可能被自动删除(在/data/data/包名/cache目录下)

File.getCacheDir():获取代表缓存路径的文件对象,然后可以在这个路径下new文件对象,再使用输入流、输出流对文件进行处理

Activity还提供了getCacheDir()和getFilesDir()方法: getCacheDir()方法用于获取/data/data//cache目录 getFilesDir()方法用于获取/data/data//files目录。

五.sdcard 外存

Sd卡,外置存储器中可以保存更大一些的文件,在应用程序删除时数据可以保留下来

  1. 首先,要访问外部存储设备,必须要声明write_external_storage 权限。
  2. 在代码中,要对外存操作,先要判断sd卡是否已挂载。用Environment的静态方法getExternalStorageState()方法获取外存的状态,如果是mounted的话说明已经挂载,如果是removed则没有挂载

3、使用EnvirogetExternalStorageDirectory方法获取sd卡根路径的File对象,再用getPath获取其路径字符串。sd卡根目录是/storage/sdcard

在getExternalStoragePublicDirectory方法中传入DIRECTORY_PICTURES,就返回这个android系统在外存中存储图片的公共目录,在这里是/storage/sdcard/Pictures

在getExternalStoragePublicDirectory方法中传入DIRECTORY_DOWNLOADS,,就返回这个系统在外存中存放下载的文件的公共目录,在这里是/storage/sdcard/Downloads

......

注意:有些手机的文件路径是定制的,所以尽量要使用api去获取路径,而不要将路径写死,避免硬件厂商定制路径造成的bug

除了sd卡中的公有目录,还可以在我们程序自己定的私有目录下读写文件。在sd卡根目录上创建我们自己的目录file.mkdirs(),并在其中创建文件进行读写

 

另外:为了避免sd卡空间不足造成损失,我们可以预先判断sd卡空间,使用StatFs类,先创建一个statFs对象,再用其中的一些方法进行判断。

StatFs stat = new StatFs(Environment.getExternalStorageDirectory().getPath());

int availableBlocks = stat.getAvailableBlocks();//获取sd卡中可用的块数

int blockCount = stat.getBlockCount();//获取sd卡中块的总数

int blockSize = stat.getBlockSize();//获取每个块的字节数

可用块数*每块字节数=可用字节数;总块数*每块字节数=总字节数

注意:不要用getFreeBlocks(),这个是空闲块数,空闲不一定可用

六.将数据保存在服务器端

通过post传参方式,将文件上传到服务器端(云端)

try {

    HttpURLConnection con = (HttpURLConnection) new URL("http://10.31.151.216:8080/up/upload").openConnection();

    con.setDoOutput(true);

    con.setRequestMethod("POST");

    con.setRequestProperty("Content-Type", "multipart/form-data;"+ " boundary=1234");

    con.connect();

    OutputStream os = con.getOutputStream();

    os.write("1234\r\n".getBytes());

    os.write("Content-Disposition: form-data; name=\"file1\"; filename=\"android.png\"\r\n".getBytes());

    os.write("\r\n".getBytes());

    FileInputStream fis = new FileInputStream("e:/android.png");

    int n= 0;

    byte[] buffer = new byte[1024];

    while((n = fis.read(buffer)) != -1){

        os.write(buffer, 0, n);

    }

    fis.close();

    os.write("\r\n\r\n".getBytes());

    os.write("123455\r\n".getBytes());

    System.out.println("read");

    BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));

    String line =  null;

    while((line = br.readLine())!=null){

        System.out.println(line);

    }

} catch (MalformedURLException e) {

    e.printStackTrace();

} catch (IOException e) {

    e.printStackTrace();

}


好了,以上是我总结的几种数据存储的方式,后面几种写得比较简单,以后慢慢补齐吧。

0 0
原创粉丝点击