Android的数据存储

416 阅读4分钟

一、Android数据存储技术

1、本地数据存取技术:

  • SharedPreferences(XML格式数据)

  • File(二进制数据为主)

  • SQLite(关系型数据)

2、远程数据存取技术

基于Socket使用TCP/IP直接访问网络服务器(数据从数据源直接传送到目的地)

基于HTTP相关协议访问Web服务(从互联网上获取HTML、json/xml、二进制格式的数据)

  • 使用文件保存数据的基本特点:

(1)可以保存任意类型、任意大小的数据,但是需要自行编写数据解析代码

(2)Android使用标准Java变成方式,通过Stream(及派生或组合类型)存取底层文件

  • 适用场景

(1)保存二进制的,数据量较大的数据

(2)有特殊格式的文本型数据

(3)有特殊处理需求的数据

  • 使用关系数据库存储数据的基本情况:

(1)Android内置对SQLite的支持,在android.database.sqlite包中提供了相应的组件

(2)SQLite是一种单用户单文件型数据库,文件保存于本机内置存储空间,占用系统资源小,适合于手机这种内存受限制的运行环境

(3)如果其他APP需要访问这些数据,可以使用ContentProvider

  • 适用场景

(1)以文本型数据为主

(2)需要进行频繁的CRUD操作

二、SharedPreferences

1、使用SharedPreferences

(1)操作前,需获取SharedPreferences对象

(2)存储数据步骤:

  • 用SharePreferences对象的方法edit()获得一个Editor对象

  • 通过putString以键值<String key,String value>方法把字符串值写入Editor对象中,其他类型数据调用相应的put()方法

  • 最后利用commit()或apply()方法提交数据

    private void savePrefs(String username){ SharedPreferences.Editor editor=gentSharedPreferences("pref",Context.MODE_PRIVATE).edit(); editor.putString("username",username); editor.apply(); }

2、获取SharedPreferences对象

(1)可通过多种方式获得SharedPreferences对象

(2)Context.getSharedPreferences(String name,int mode)

  • name为文件名称

  • mode为操作模式,默认的模式为0或MODE_PRIVATE,还可以使用MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE

3、Activity.getPreferences(int mode):只能在当前activity使用,一般不用当前不带包名的的类名作为文件的名称

3、SharedPreferences读取

(1)从已经保存的Shared Preferences中读取数据

  • 调用getSharedPreferences()函数

  • 通过get()函数获取保存在SharedPreferences中的键值对

    private String readPrefs(){
    SharedPreferences prefs=getSharedPreferences("pref",Context.MODE_PRIVATE);
    return prefs.getString("username","");
    }
    

三、文件存取

1、Android的存储系统

(1)本机内置系统存储

  • /data/data/package name/
  • 仅供App自己使用,属“私有数据”
  • App卸载是自动删除

(2)本机外部系统存储

  • /stprage/emulated/package name/
  • 存储照片、音乐等,属“共享数据”
  • App卸载时保留

(3)外部可扩充存储

  • SD卡上的任意文件夹
  • 可供任意App访问
  • App卸载后仍然保存
  • 不在配置SD卡

2、Android存储系统的重要的文件夹

  • /data/app:保存各个应用
  • /data/data:各个应用保存私有数据的地方
  • /mnt/sdcard:代表SD卡的根目录
  • /system:对应用只读,保存Android操作系统文件

3、文件内部存取数据

private void saveDataInternal(String fileName,String username){
    try {
        //打开文件输出流
        FileOutputStream out=openFileOutput(fileName, Context.MODE_PRIVATE);
        //创建BufferedWriter对象
        BufferedWriter Writer=new BufferedWriter(new OutputStreamWriter(out));
        //写入数据
        Writer.write(username);
        //关闭输出流
        Writer.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private String readDataInternal(String fileName){
    String data=null;
    try {
        FileInputStream in=openFileInput(fileName);
        BufferedReader reader=new BufferedReader(new InputStreamReader(in));
        data=reader.readLine();
        reader.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return data;
}

4、外部存储的公有文件的存储

  • 在AndroidManifest配置文件中设置权限

     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    
  • Android 6.0及以上版本需申请运行时权限

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
          if (ContextCompat.checkSelfPermission(this,
                  Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
              ActivityCompat.requestPermissions(this,
                      new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 2);
              return;
          }
      }
    
  • 申请权限的回调方法

       @Override
        public void onRequestPermissionsResult(int requestCode,
                                         @NonNull String[] permissions,
                                         @NonNull int[] grantResults) {
      super.onRequestPermissionsResult(requestCode, permissions, grantResults);
      if(grantResults.length==0||grantResults[0]!=PackageManager.PERMISSION_GRANTED){
          Toast.makeText(this,"权限申请被拒绝",Toast.LENGTH_SHORT).show();
          return;
      }
      switch (requestCode){
          case 1:
              saveToSD("qyqx.jpg");
              break;
          case 2:
      }
    }
    

四、数据库存取

1、Android数据库编程方式

  • 直接访问:使用SQLiteDatabase类

  • 初步封装:使用SQLiteOpenHelper类

    SQLiteOpenHelper类是一个用于创建或打开数据库的辅助类

    SQLiteOpenHelper类是一个抽象类,包含两个重要的方法:

    onCreate(SQLiteDatabase db):新建数据库时调用
    onUpgrade(SQLiteDatabase db,int lodVersion,int newVersion):数据库版本升级时调用
    

    构造出实例后调用getWritableDatabase()或getReadableDatabase()方法获取Database对象

    创建的数据库存放目录:/data/data/packageName/databases/

  • 自定义:我们自己封装数据库取代吗

2、使用SQLiteOpenHelper

MyDBHelper helper=new MyDBHelper(this);
SQLiteDatabase db=helper.getWritableDatabase();

五、ContentProvider

1、ContentProvider是Android的四大组件之一

2、不同应用程序之间数据交换的标准API,实现数据在不同应用程序直接的共享

3、管理联系人

private void readContacts() {
    Cursor cursor=getContentResolver().query(
            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
            null,null,null,null);

    contacts=new ArrayList<>();
    if(cursor!=null&&cursor.moveToFirst()){
        do{
            String name=cursor.getString(cursor.getColumnIndex(
                    ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
            String phone=cursor.getString(cursor.getColumnIndex(
                    ContactsContract.CommonDataKinds.Phone.NUMBER));
            contacts.add(name+":"+phone);
        }while (cursor.moveToNext());
        cursor.close();
    }
    //设置Adapter
    if(contacts.isEmpty()){
        Toast.makeText(MainActivity.this,"没有联系人",Toast.LENGTH_SHORT).show();
        return;
    }
    ArrayAdapter<String> arrayAdapter= new ArrayAdapter<>(MainActivity.this,
            android.R.layout.simple_list_item_1,contacts);
    list.setAdapter(arrayAdapter);
}