Android平台进行数据存储的五大方式

SharedPreferences存储数据

** 适用范围:**保存少量的数据,且这些数据的格式非常简单:字符串型、基本类型的值。比如应用程序的各种配置信息(如是否打开音效、是否使用震动效果、APP版本号等),解锁口 令密码等

核心原理:保存基于XML文件存储的key-value键值对数据,通常用来存储一些简单的配置信息。通过DDMS的File Explorer面板,展开文件浏览树,很明显SharedPreferences数据总是存储在/data/data//shared_prefs目录下。SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过SharedPreferences.edit()获取的内部接口Editor对象实现。

SharedPreferences本身是一 个接口,程序无法直接创建SharedPreferences实例,只能通过Context提供的getSharedPreferences(String name, int mode)方法来获取SharedPreferences实例,该方法中name表示要操作的xml文件名,第二个参数具体如下:

Context.MODE_PRIVATE: 指定该SharedPreferences数据只能被本应用程序读、写。

Context.MODE_WORLD_READABLE:  指定该SharedPreferences数据能被其他应用程序读,但不能写。

Context.MODE_WORLD_WRITEABLE:  指定该SharedPreferences数据能被其他应用程序读,写

Editor有如下主要重要方法:

SharedPreferences.Editor clear():清空SharedPreferences里所有数据

***SharedPreferences.Editor putXxx(String key , xxx value): ***向SharedPreferences存入指定key对应的数据,其中xxx 可以是boolean,float,int等各种基本类型据

***SharedPreferences.Editor remove(): ***删除SharedPreferences中指定key对应的数据项

***                boolean commit(): ***当Editor编辑完成后,使用该方法提交修改

实际案例:运行界面如下

这里只提供了两个按钮和一个输入文本框,布局简单,故在此不给出界面布局文件了,

**程序核心代码如下: **

classViewOclimplementsView.OnClickListener{@OverridepublicvoidonClick(View v){switch(v.getId()){caseR.id.btnSet://步骤1:获取输入值String code = txtCode.getText().toString().trim();//步骤2-1:创建一个SharedPreferences.Editor接口对象,lock表示要写入的XML文件名,MODE_WORLD_WRITEABLE写操作SharedPreferences.Editor editor = getSharedPreferences("lock", MODE_WORLD_WRITEABLE).edit();//步骤2-2:将获取过来的值放入文件editor.putString("code", code);//步骤3:提交editor.commit();                Toast.makeText(getApplicationContext(),"口令设置成功", Toast.LENGTH_LONG).show();break;caseR.id.btnGet://步骤1:创建一个SharedPreferences接口对象SharedPreferences read = getSharedPreferences("lock", MODE_WORLD_READABLE);//步骤2:获取文件中的值String value = read.getString("code","");                Toast.makeText(getApplicationContext(),"口令为:"+value, Toast.LENGTH_LONG).show();break;            }        }            }

读写其他应用的SharedPreferences步骤如下:

1、在创建SharedPreferences时,指定MODE_WORLD_READABLE模式,表明该SharedPreferences数据可以被其他程序读取

2、创建其他应用程序对应的Context:

Context pvCount = createPackageContext("com.tony.app", Context.CONTEXT_IGNORE_SECURITY);这里的com.tony.app就是其他程序的包名

3、使用其他程序的Context获取对应的SharedPreferences

SharedPreferences read = pvCount**.**getSharedPreferences("lock", Context.MODE_WORLD_READABLE);

4、如果是写入数据,使用Editor接口即可,所有其他操作均和前面一致。

优缺点

优点

SharedPreferences对象与SQLite数据库相比,免去了创建数据库,创建表,写SQL语句等诸多操作,相对而言更加方便,简洁。

缺点

SharedPreferences也有其自身缺陷,比如其只能存储boolean,int,float,long和String五种简单的数据类型,比如其无法进行条件查询等。所以不论SharedPreferences的数据存储操作是如何简单,它也只能是存储方式的一种补充,而无法完全替代如SQLite数据库这样的其他数据存储方式。

当存储的类型为对象时:

SharedPreferences.Editor editor = getSharedPreferences("lock",MODE_WORLD_WRITEABLE).edit();

editor.putString("list",new Gson().toJson(userInfoResponse.getData().getMedalList()));

editor.commit();

SharedPreferences read = getSharedPreferences("lock",MODE_WORLD_READABLE);

String list = read.getString("list","");

ArrayList returnList =new Gson().fromJson(list, new TypeToken>(){}.getType());


 文件存储数据

 核心原理: Context提供了两个方法来打开数据文件里的文件IO流 FileInputStream openFileInput(String name); FileOutputStream(String name , int mode),这两个方法第一个参数 用于指定文件名,第二个参数指定打开文件的模式。具体有以下值可选:

MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中。可   以使用Context.MODE_APPEND

MODE_APPEND:模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。

  MODE_WORLD_READABLE:表示当前文件可以被其他应用读取;

MODE_WORLD_WRITEABLE:表示当前文件可以被其他应用写入。

 除此之外,Context还提供了如下几个重要的方法:

getDir(String name , int mode):在应用程序的数据文件夹下获取或者创建name对应的子目录

File getFilesDir():获取该应用程序的数据文件夹得绝对路径

String[] fileList():返回该应用数据文件夹的全部文件

实际案例:界面沿用上图

             核心代码如下:

private Stringread(){

try{

FileInputStream inputStream =this.openFileInput("message.txt");

        byte[] buffer =new byte[1024];

        int hasRead =0;

        StringBuilder sb =new StringBuilder();

        while ((hasRead = inputStream.read(buffer)) != -1){

sb.append(new String(buffer,0,hasRead));

        }

inputStream.close();

        return sb.toString();

    }catch (Exception e){

e.printStackTrace();

    }

return null;

}

private void write(String msg){

if (msg ==null)return;

    try{

FileOutputStream fos = openFileOutput("message.txt",MODE_APPEND);

        fos.write(msg.getBytes());

        fos.close();

    }catch (Exception e){

e.printStackTrace();

    }

}

openFileOutput()方法的第一参数用于指定文件名称,不能包含路径分隔符“/” ,如果文件不存在,Android 会自动创建它。创建的文件保存在/data/data//files目录,如: /data/data/cn.tony.app/files/message.txt,

 下面讲解某些特殊文件读写需要注意的地方:

读写sdcard上的文件

其中读写步骤按如下进行:

1、调用Environment的getExternalStorageState()方法判断手机上是否插了sd卡,且应用程序具有读写SD卡的权限,如下代码将返回true

Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)

Environment类中提供了几个静态常量用于标识外部存储的状态,这些状态都是String类型

MEDIA_BAD_REMOVAL 在没有挂载前存储媒体已经被移除。

MEDIA_CHECKING 正在检查存储媒体。

MEDIA_MOUNTED 存储媒体已经挂载,并且挂载点可读/写。

MEDIA_MOUNTED_READ_ONLY 存储媒体已经挂载,挂载点只读。

MEDIA_NOFS 存储媒体是空白或是不支持的文件系统。

MEDIA_REMOVED 存储媒体被移除。

MEDIA_SHARED 存储媒体正在通过USB共享。

MEDIA_UNMOUNTABLE 存储媒体无法挂载。

MEDIA_UNMOUNTED 存储媒体没有挂载

在Environment中还提供了Android标准目录的路径,以String类型提供。

DIRECTORY_ALARMS 系统提醒铃声存放的标准目录。

DIRECTORY_DCIM 相机拍摄照片和视频的标准目录。

DIRECTORY_DOWNLOADS 下载的标准目录。

DIRECTORY_MOVIES 电影存放的标准目录。

DIRECTORY_MUSIC 音乐存放的标准目录。

DIRECTORY_NOTIFICATIONS 系统通知铃声存放的标准目录。

DIRECTORY_PICTURES 图片存放的标准目录

DIRECTORY_PODCASTS 系统广播存放的标准目录。

DIRECTORY_RINGTONES 系统铃声存放的标准目录。

static File getDataDirectory() 获得data的目录(/data)。

static File getDownloadCacheDirectory() 获得下载缓存目录。(/cache)

static File getExternalStorageDirectory() 获得外部存储媒体目录。(/mnt/sdcard or /storage/sdcard0)

static File getRootDirectory() 获得系统主目录(/system)

除了用Environment获取存储目录之外,还可以通过把路径写死的方式,比如要读取外部存储/mnt/sdcard目录下的文件,可以在程序中直接用全路径,

但是这样做是很不好的,应该Android实在是太开放了,外部存储的目录的什么还是要固件制作商才知道,但是有一点是毋庸置疑的,就是Android框架层里面

已经是指定好了Environment.getDownloadCacheDirectory()的返回路径。所以,尽量用这种方式来获取和存储数据,以免固件厂商不同而造成路径的差异。

2、调用Environment.getExternalStorageDirectory()方法来获取外部存储器,也就是SD卡的目录,或者使用"/mnt/sdcard/"目录

3、使用IO流操作SD卡上的文件 

注意点:手机应该已插入SD卡,对于模拟器而言,可通过mksdcard命令来创建虚拟存储卡

           必须在AndroidManifest.xml上配置读写SD卡的权限

案例代码

:/**

* 文件写操作函数

*/

private void write(String content){

if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){//判断挂载sd卡是否存在

        File file =new File(Environment.getExternalStorageDirectory().toString()+File.separator

        +dir+File.separator+fileName);//定义file对象

        if (!file.getParentFile().exists()){//父文件夹不存在

            file.getParentFile().mkdirs();//创建文件夹

        }

PrintStream out =null;//打印流对象用于输出

        try {

out =new PrintStream(new FileOutputStream(file,true));//追加文件

            out.print(content);

        }catch (Exception e){

e.printStackTrace();

        }finally {

if (out !=null){

out.close();//关闭打印流

            }

}

}else {

Toast.makeText(this, "保存失败,SD卡不存在!", Toast.LENGTH_LONG).show();

    }

}

/**

* 文件读操作

*/

private Stringread(){

if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){

File file =new File(Environment.getExternalStorageDirectory().toString()+

File.separator+dir+File.separator+fileName);

        if (!file.getParentFile().exists()){

file.getParentFile().mkdirs();

        }

Scanner scanner =null;//扫描输入

        StringBuilder sb =new StringBuilder();

        try {

scanner =new Scanner(new FileInputStream(file));

            while (scanner.hasNext()){//循环读取

                sb.append(scanner.next()+"\n");

            }

return sb.toString();

        }catch (Exception e){

e.printStackTrace();

        }finally {

if (scanner !=null){

scanner.close();

            }

}

}

return null;

}

ContentProvider保存数据介绍

一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据完全暴露出去,而且ContentProvider是以类似数据库中表的方式将数据暴露的。那么外界获取其提供的数据,也就应该与从数据库中获取数据的操作基本一样,只不过是采用URL来表示外界需要访问的“数据库”。

ContentProvider提供了一种多应用间数据共享的方式。

ContentProvider是个实现了一组用于提供其他应用程序存取数据的标准方法的类。应用程序可以在ContentProvider中执行如下操作:查询数据、修改数据、添加数据、删除数据。

标准的ContentProvider:Android提供了一些已经在系统中实现的标准ContentProvider,比如联系人信息,图片库等等,可以用这些ContentProvider来访问设备上存储的联系人信息、图片等等。

在ContentProvider中使用的查询字符串有别于标准的SQL查询,很多诸如select、add、delete、modify等操作都使用一种特殊的URL进行,这种URL由3部分组成,“content://”,代表数据的路径和一个可选的表示数据的ID。

content://media/internal/images 这个URL将返回设备上存储的所有图片

content://contacts/people/ 这个URL将返回设备上的所有联系人信息

content://contacts/people/45 这个URL返回单个结果(联系人信息中ID为45的联系人记录)

 如果想要存储字节型数据,比如位图文件等,那保存该数据的数据列其实是一个表示实际保存保存文件的URL字符串,客户端通过它来读取对应的文件数据,处理这种数据类型的ContentProvider需要实现一个名为_data的字段,_data字段列出了该文件在Android文件系统上的精确路径。这个字段不仅是供客户端使用,而且也可以供ContentResolver使用。客户端可以调用ContentResolver.openOutputStream()方法来处理该URL指向的文件资源,如果是ContentResolver本身的话,由于其持有的权限比客户端要高,所以它能直接访问该数据文件

你可能感兴趣的:(Android平台进行数据存储的五大方式)