Android几种数据存储的方式
2016-06-26 20:02
483 查看
这是我的第一篇博客,前言也不多说什么,有点小激动,还是直接进入正题吧。
RT,今天要写的是安卓几种数据存储的方式。
一,首先我想到的就是创建本地数据库,前段时间刚用了一个叫GreenDao的第三方,他的用法很简单,这里我直接贴上操作步骤和代码,网上很多教程(我也是跟着教程来,然后再自己加以琢磨)。
(下面这个是基本配置网上抄的)
配置 Android 工程(app)的 build.gradle,如图分别添加 sourceSets 与dependencies。
在另外的模块里面的gradle配置 daoexamplegenerator 工程的 build.gradle,添加 dependencies.
编写 ExampleDaoGenerator 类,注意: 我们的 Java 工程只有一个类,它的内容决定了「GreenDao Generator」的输出,你可以在这个类中通过对象、关系等创建数据库结构,下面我将以注释的形式详细讲解代码内容。
然后在studio右键点击 run```的 他就会出来一串write之类的东西主要看看是否有结果生成 不为0就好如我的 Processed 3 entities in 1010ms
如果在此处出错,你可以依据错误日志进行排查,主要看是否输出目录存在?其他配置是否正确?等
举个例子(下面的内容和上面ExampleDaoGenerator类无关·····)
二,要讲的是偏好设置sharedPreferences
可以用来保存用户的一些简单的使用习惯信息,偏好设置实质上是/data/data/包/share_prefs/路径下的一个xml文件,文件名就是偏好设置的名字。
如何使用ShardPreference将数据持久化:
通过getSharedPreferences(String name,int mode)来获取一个SharedPreferences对象,一个应用可以有多个偏好设置文件,第一个参数决定用哪个,第二个参数表示模式,一般用MODE_PRIVATE,只能本应用来读(全局可读、全局可写这些模式不建议使用)
保存: 调用SharedPreferences对象的edit()方法,开始修改它,这个方法会返回一个Editor对象,我们调用这个对象的putXXX方法往里面放简单的信息,在写好后再调用commit()方法来确认
Activity中存入数据
Activity中获取数据
获取: 调用SharedPreferences对象的getXXX方法根据键获取值
写文件示例:
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权限。(权限记得加上不然很蛋疼)
File.getCacheDir():获取代表缓存路径的文件对象,然后可以在这个路径下new文件对象,再使用输入流、输出流对文件进行处理
Activity还提供了getCacheDir()和getFilesDir()方法:
getCacheDir()方法用于获取/data/data//cache目录 getFilesDir()方法用于获取/data/data//files目录。
首先,要访问外部存储设备,必须要声明write_external_storage 权限。
在代码中,要对外存操作,先要判断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对象,再用其中的一些方法进行判断。
可用块数*每块字节数=可用字节数;总块数*每块字节数=总字节数
注意:不要用getFreeBlocks(),这个是空闲块数,空闲不一定可用
好了,以上是我总结的几种数据存储的方式,后面几种写得比较简单,以后慢慢补齐吧。
RT,今天要写的是安卓几种数据存储的方式。
一,首先我想到的就是创建本地数据库,前段时间刚用了一个叫GreenDao的第三方,他的用法很简单,这里我直接贴上操作步骤和代码,网上很多教程(我也是跟着教程来,然后再自己加以琢磨)。
(下面这个是基本配置网上抄的)
一. 在 ANDROID 工程中配置「GREENDAO GENERATOR」模块
在 .src/main 目录下新建一个与 java 同层级的「java-gen」目录,用于存放由 greenDAO 生成的 Bean、DAO、DaoMaster、DaoSession 等类。配置 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 工程)
通过 File -> New -> New Module -> Java Library -> 填写相应的包名与类名 -> Finish.在另外的模块里面的gradle配置 daoexamplegenerator 工程的 build.gradle,添加 dependencies.
1 | compile 'de.greenrobot:greendao-generator:1.3.1' |
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; }
/*********增加数据*********/ @Override public <T> void addDada(T data) { if (alarmBean!=null&&data!=null){ alarmBean.insertOrReplace((AlarmBean) data); } }
/****删除数据****/
@Override public 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没有结果) |
获取: 调用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卡,外置存储器中可以保存更大一些的文件,在应用程序删除时数据可以保留下来首先,要访问外部存储设备,必须要声明write_external_storage 权限。
在代码中,要对外存操作,先要判断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(); } |
相关文章推荐
- Android project的结构
- android 蓝牙搜索功能实现
- 关于回调函数
- 用户登录界面
- Android 5.0以后启动服务的正确做法
- Android之监听手机软键盘弹起与关闭
- Android项目前的准备
- Android中自定义View的MeasureSpec使用
- Android Studio 集成阿里百川SDK
- Android-PullToRefresh的用法 及源码中你应该知道的一些东西
- Android SlidingMenu 开源项目 侧拉菜单的使用(详细配置)
- Android中TabLayout切换选项背景和修改字体大小
- Android SlidingMenu 开源项目实现侧拉菜单(二)
- Android 5.0源码编译问题
- Android开机动画
- Android SlidingMenu 开源项目实现侧拉菜单(一)
- 练习Android大图轮播效果的实现-大致布局
- Android Service的生命周期
- android tv焦点特效实现浅析
- Android进阶