Android的数据储存方式

Android下一共有5种数据储存方式:

一. SharedPreferences储存数据

SharedPreferences是Android平台上一个轻量级的存储类,主要是保存一些常用的配置比如窗口状态,一般在Activity中 重载窗口状态onSaveInstanceState保存一般使用SharedPreferences完成,它提供了Android平台常规的Long长 整形、Int整形、String字符串型的保存。 

它的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息。

其存储位置在/data/data/<包名>/shared_prefs目录下。

SharedPreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过Editor对象实现。

实现SharedPreferences存储的步骤如下:   

一、根据Context获取SharedPreferences对象   

二、利用edit()方法获取Editor对象。   

三、通过Editor对象存储key-value键值对数据。   

四、通过commit()方法提交数据。


示例代码:

<span style="font-weight: normal;">  //获取SharedPreferences对象
        Context ctx = MainActivity.this;       
        SharedPreferences sp = ctx.getSharedPreferences("SP", MODE_PRIVATE);
        //存入数据
        Editor editor = sp.edit();
        editor.putString("STRING_KEY", "string");
        editor.putInt("INT_KEY", 0);
        editor.putBoolean("BOOLEAN_KEY", true);
        editor.commit();
        
        //返回STRING_KEY的值
        Log.d("SP", sp.getString("STRING_KEY", "none"));
        //如果NOT_EXIST不存在,则返回值为"none"
        Log.d("SP", sp.getString("NOT_EXIST", "none"));
     }</span>

这段代码执行过后,即在/data/data/com.ythl.shouyoufanli/shared_prefs目录下生成了一个SP.xml文件,一个应用可以创建多个这样的xml文件。 


SharedPreferences对象与SQLite数据库相比,免去了创建数据库,创建表,写SQL语句等诸多操作,相对而言更加方便,简洁。但是SharedPreferences也有其自身缺陷,比如其职能存储boolean,int,float,long和String五种简单的数据类型,比如其无法进行条件查询等。所以不论SharedPreferences的数据存储操作是如何简单,它也只能是存储方式的一种补充,而无法完全替代如SQLite数据库这样的其他数据存储方式。  只能在同包下使用,不同包下不能使用.


二. 文件储存数据

  核心原理: 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():返回该应用数据文件夹的全部文件    

<span style="font-weight: normal;"><span style="font-size:18px;">核心代码:</span></span>
<span style="font-weight: normal;"><span style="font-size:18px;">
</span></span>
<span style="font-weight: normal;"><span style="font-size:18px;"></span></span><pre name="code" class="java">public String read() {
        try {
            FileInputStream inStream = this.openFileInput("message.txt");
            byte[] buffer = new byte[1024];
            int hasRead = 0;
            StringBuilder sb = new StringBuilder();
            while ((hasRead = inStream.read(buffer)) != -1) {
                sb.append(new String(buffer, 0, hasRead));
            }

            inStream.close();
            return sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        } 
        return null;
    }
    
    public void write(String msg){
        // 步骤1:获取输入值
        if(msg == null) return;
        try {
            // 步骤2:创建一个FileOutputStream对象,MODE_APPEND追加模式
            FileOutputStream fos = openFileOutput("message.txt",
                    MODE_APPEND);
            // 步骤3:将获取过来的值放入文件
            fos.write(msg.getBytes());
            // 步骤4:关闭数据流
            fos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


 

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

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

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

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

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

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

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

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

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

<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

三. SQLite数据库储存数据

SQLite是轻量级嵌入式数据库引擎,它支持 SQL 语言,并且只利用很少的内存就有很好的性能。现在的主流移动设备像Android、iPhone等都使用SQLite作为复杂数据的存储引擎,在我们为移动设备开发应用程序时,也许就要使用到SQLite来存储我们大量的数据,所以我们就需要掌握移动设备上的SQLite开发技巧

SQLiteDatabase类为我们提供了很多种方法,上面的代码中基本上囊括了大部分的数据库操作;对于添加、更新和删除来说,我们都可以使用

1 db.executeSQL(String sql);  
2 db.executeSQL(String sql, Object[] bindArgs);//sql语句中使用占位符,然后第二个参数是实际的参数集 

除了统一的形式之外,他们还有各自的操作方法:

1 db.insert(String table, String nullColumnHack, ContentValues values);  
2 db.update(String table, Contentvalues values, String whereClause, String whereArgs);  
3 db.delete(String table, String whereClause, String whereArgs);

以上三个方法的第一个参数都是表示要操作的表名;insert中的第二个参数表示如果插入的数据每一列都为空的话,需要指定此行中某一列的名称,系统将此列设置为NULL,不至于出现错误;insert中的第三个参数是ContentValues类型的变量,是键值对组成的Map,key代表列名,value代表该列要插入的值;update的第二个参数也很类似,只不过它是更新该字段key为最新的value值,第三个参数whereClause表示WHERE表达式,比如“age > ? and age < ?”等,最后的whereArgs参数是占位符的实际参数值;delete方法的参数也是一样


四. ContentProvider储存数据

1、ContentProvider简介 
当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据。虽然使用其他方法也可以对外共享数 据,但数据访问方式会因数据存储的方式而不同,如:采用文件方式对外共享数据,需要进行文件操作读写数据;采用sharedpreferences共享数 据,需要使用sharedpreferences API读写数据。而使用ContentProvider共享数据的好处是统一了数据访问方式。 


2、Uri类简介 
Uri代表了要操作的数据,Uri主要包含了两部分信息:1.需要操作的ContentProvider ,2.对ContentProvider中的什么数据进行操作,一个Uri由以下几部分组成: 
1.scheme:ContentProvider(内容提供者)的scheme已经由Android所规定为:content://。 
2.主机名(或Authority):用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。 
3.路径(path):可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下: 
要操作contact表中id为10的记录,可以构建这样的路径:/contact/10 
要操作contact表中id为10的记录的name字段, contact/10/name 
要操作contact表中的所有记录,可以构建这样的路径:/contact  
要操作的数据不一定来自数据库,也可以是文件等他存储方式,如下: 
要操作xml文件中contact节点下的name节点,可以构建这样的路径:/contact/name 
如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下: 
Uri uri = Uri.parse("content://com.changcheng.provider.contactprovider/contact")


3、UriMatcher、ContentUrist和ContentResolver简介 
因为Uri代表了要操作的数据,所以我们很经常需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher 和ContentUris 。掌握它们的使用,会便于我们的开发工作。 
  UriMatcher:用于匹配Uri,它的用法如下: 
1.首先把你需要匹配Uri路径全部给注册上,如下: 
//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码(-1)。 
UriMatcher  uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 
//如果match()方法匹配content://com.changcheng.sqlite.provider.contactprovider/contact路径,返回匹配码为1 
uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider”, “contact”, 1);//添加需要匹配uri,如果匹配就会返回匹配码 
//如果match()方法匹配 content://com.changcheng.sqlite.provider.contactprovider/contact/230路径,返回匹配码为2 
uriMatcher.addURI(“com.changcheng.sqlite.provider.contactprovider”, “contact/#”, 2);//#号为通配符 

2.注册完需要匹配的Uri后,就可以使用uriMatcher.match(uri)方法对输入的Uri进行匹配,如果匹配就返回匹配码,匹配码是调用 addURI()方法传入的第三个参数,假设匹配 content://com.changcheng.sqlite.provider.contactprovider/contact路径,返回的匹配 码为1。 
  
ContentUris:用于获取Uri路径后面的ID部分,它有两个比较实用的方法: 
withAppendedId(uri, id)用于为路径加上ID部分 
parseId(uri)方法用于从路径中获取ID部分 
  ContentResolver:当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用 ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。 ContentResolver使用insert、delete、update、query方法,来操作数据。 

五. 网络储存数据

利用HttpURLConnection对象,我们可以从网络中获取网页数据.
URL url = new URL("http://www.sohu.com");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5* 1000);//设置连接超时
conn.setRequestMethod(“GET”);//以get方式发起请求
if (conn.getResponseCode() != 200) throw new RuntimeException("请求url失败");
InputStream is = conn.getInputStream();//得到网络返回的输入流
String result = readData(is, "GBK");
conn.disconnect();
//第一个参数为输入流,第二个参数为字符集编码
public static String readData(InputStream inSream, String charsetName) throws Exception{
    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
    byte[] buffer = new byte[1024];
    int len = -1;
    while( (len = inSream.read(buffer)) != -1 ){
        outStream.write(buffer, 0, len);
    }
    byte[] data = outStream.toByteArray();
    outStream.close();
    inSream.close();
    return new String(data, charsetName);
}

六:总结说明 


以上5中存储方式,在以后的开发过程中,根据设计目标、性能需求、空间需求等找到合适的数据存储方式。Android 中的数据存储都是私有的,其他应用程序都是无法访问的,除非通过ContentResolver获取其他程序共享的数据。采用文件方式对外共享数据,需要 进行文件操作读写数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读写数据。而使用ContentProvider共享数据的好处是统一了数据访问方式。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值