【精华】Android面试精华总结——数据存储与IO

一、File文件存储

1.文件的操作模式

在这里插入图片描述

2.相关操作方法

在这里插入图片描述

3.读取SD卡上的文件

在这里插入图片描述

4.读取raw和assets文件夹下的文件

  如果我们不想自己的文件被编译成二进制文件的话, 我们可以把文件放到这两个目录下,而两者的区别如下:

  • res/raw:文件会被映射到R.java文件中,访问的时候直接通过资源ID即可访问,而且 他不能有目录结构,就是不能再创建文件夹
  • assets:不会映射到R.java文件中,通过AssetManager来访问,能有目录结构,即, 可以自行创建文件夹

  读取文件资源:

  • res/raw:
InputStream is =getResources().openRawResource(R.raw.filename);  
  • assets:
AssetManager am =  getAssets();  
InputStream is = am.open("filename");

二、SharedPreferences保存用户偏好参数

  SharedPreference保存的数据主要是类似于配置信息格式的数据,因此它保存的数据主要是简单类型key-value对,该接口主要负责读取应用程序的Preference数据。SharedPreference接口本身并没有提供写入数据的能力,而是通过SharedPreference的内部接口,SharedPreferene调用edit()方法即可获取它所对应的的Editor对象。
在这里插入图片描述

2.读取其他应用的SharedPreferences

  获得其他app的Context,而这个Context代表访问该app的全局信息的接口,而决定应用的唯一标识是应用的包名,所以可以通过应用包名获得对应app的Context。需要注意的是,其他应用的SharedPreferences文件是否能被读写的前提就是其是否指定了可读或者可写的权限。

实现流程图:
在这里插入图片描述

3.使用MD5对重要数据进行加密

简单的加密处理流程

流程图如下:
在这里插入图片描述

流程图解析:

  1. 用户注册账号密码,账号密码校验后(账号是否重复,密码位数 > 6位等), 即账号密码有效,注册成功后,我们提交给服务器账号以及本地加密过的密码。
  2. 服务器端将用户提交的账号、加密过的密码保存到服务端的数据库中,也就是服务端并不会保存我们的明文密码。
  3. 对于客户端,如果注册成功或者登陆成功,你想保存账号密码到SharedPreferences中,保存的的密码也需要走一趟加密流程:即明文密码–>加密–>保存。如果不保存,每次请求的时候,明文密码也要走一趟加密流程,然后拿着加密后的密码来请求服务器。
  4. 服务器验证账号以及加密密码,成功,分配客户端一个session标识,后续客户端可以拿着这个session来访问服务端提供的相关服务。

MD5简介

  MD5: MD5信息摘要算法(英语:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。MD5不可逆,就是说没有对应的算法,无法从生成的md5值逆向得到原始数据。MD5值不唯一,一个原始数据只对应一个MD5值,但是一个MD5值可能对应多个原始数据

MD5加密实现实例

Md5Util.java:

public class MD5 {
    public static String getMD5(String content) {
        try {
            MessageDigest digest = MessageDigest.getInstance("MD5");
            digest.update(content.getBytes());
            return getHashString(digest);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    private static String getHashString(MessageDigest digest) {
        StringBuilder builder = new StringBuilder();
        for (byte b : digest.digest()) {
            builder.append(Integer.toHexString((b >> 4) & 0xf));
            builder.append(Integer.toHexString(b & 0xf));
        }
        return builder.toString();
    }
}

MainActivity.java直接调用getMD5这个静态方法:

Log.e("HeHe", MD5.getMD5("呵呵"));

可以看到Logcat上打印出:
在这里插入图片描述

4.SharedPreference工具类

SPUtils.java

package com.jay.sharedpreferencedemo3;
import android.content.Context;
import android.content.SharedPreferences;
import java.util.Map;

public class SPUtils {
    /**
     * 保存在手机里的SP文件名
     */
    public static final String FILE_NAME = "my_sp";

    /**
     * 保存数据
     */
    public static void put(Context context, String key, Object obj) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        if (obj instanceof Boolean) {
            editor.putBoolean(key, (Boolean) obj);
        } else if (obj instanceof Float) {
            editor.putFloat(key, (Float) obj);
        } else if (obj instanceof Integer) {
            editor.putInt(key, (Integer) obj);
        } else if (obj instanceof Long) {
            editor.putLong(key, (Long) obj);
        } else {
            editor.putString(key, (String) obj);
        }
        editor.commit();
    }


    /**
     * 获取指定数据
     */
    public static Object get(Context context, String key, Object defaultObj) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        if (defaultObj instanceof Boolean) {
            return sp.getBoolean(key, (Boolean) defaultObj);
        } else if (defaultObj instanceof Float) {
            return sp.getFloat(key, (Float) defaultObj);
        } else if (defaultObj instanceof Integer) {
            return sp.getInt(key, (Integer) defaultObj);
        } else if (defaultObj instanceof Long) {
            return sp.getLong(key, (Long) defaultObj);
        } else if (defaultObj instanceof String) {
            return sp.getString(key, (String) defaultObj);
        }
        return null;
    }

    /**
     * 删除指定数据
     */
    public static void remove(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.remove(key);
        editor.commit();
    }


    /**
     * 返回所有键值对
     */
    public static Map<String, ?> getAll(Context context) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        Map<String, ?> map = sp.getAll();
        return map;
    }

    /**
     * 删除所有数据
     */
    public static void clear(Context context) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sp.edit();
        editor.clear();
        editor.commit();
    }

    /**
     * 检查key对应的数据是否存在
     */
    public static boolean contains(Context context, String key) {
        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, context.MODE_PRIVATE);
        return sp.contains(key);
    }

}

三、SQLite数据库

1.基本概念

  SQLite是一个轻量级的关系型数据库,运算速度快,占用资源少,很适合在移动设备上使用, 不仅支持标准SQL语法,还遵循ACID(数据库事务)原则,无需账号,使用起来非常方便。SQLite是一个嵌入式的数据库引擎,专门适用于资源有限的设备上适量数据存取。SQLite数据库只是一个文件。
  SQLite支持五种数据类型:NULL,INTEGER,REAL(浮点数),TEXT(字符串文本)和BLOB(二进制对象) 。虽然只有五种,但是对于varchar,char等其他数据类型都是可以保存的,因为SQLite有个最大的特点:允许把各种数据类型的数据保存到任何字段中而不用关心字段声明的数据类型。编写建表语句时可以省略数据列后面的类型声明。
  总结: SQlite通过文件来保存数据库,一个文件就是一个数据库,数据库中又包含多个表格,表格里又有多条记录,每个记录由多个字段构成,每个字段有对应的,每个值我们可以指定类型,也可以不指定类型(主键除外)。

2.使用步骤

  1. 获取SQLiteDatabase对象,它代表了与数据库的连接。
  2. 调用SQLiteDatabase的方法来执行SQL语句。
  3. 操作SQL语句的执行结果,比如用SimpleCursorAdapter来封装Cursor。
  4. 关闭SQLiteDatabase,回收资源。

3.常用方法

  • 打开一个文件对应的数据库:static SQLiteDatabase openDatabase(…);
  • 执行带占位符的SQL语句:execSQL(String sql,Object[] bindArgs);
  • 执行SQL语句:execSQL(String sql);
  • 执行带占位符的SQL查询:rawQuery(String sql, String[] selectionArgs);
  • 开始事务:beginTransaction();
  • 结束事务:endTransaction();
  • 如果当前上下文处于事务中,则返回true:inTransaction();
  • 设置事务标志:setTransactionSuccessful();
  • 将记录指针移到下一行,如果成功则返回ture:boolean moveToNext();

4.SQLiteOpenHelper类

  Android提供的一个管理数据库的工具类,可用于管理数据库的创建和版本更新。一般用法是创建SQLiteOpenHelper的子类,并扩展它的onCreate()和onUpgrade()方法。
  方法解析:

  • onCreate(database): 首次使用软件时生成数据库表
  • onUpgrade(database,oldVersion,newVersion): 在数据库的版本发生变化时会被调用, 一般在软件升级时才需改变版本号,而数据库的版本是由程序员控制的。

代码示例:

public class MyDBOpenHelper extends SQLiteOpenHelper {
    public MyDBOpenHelper(Context context, String name, CursorFactory factory,
            int version) {super(context, "my.db", null, 1); }
    @Override
    //数据库第一次创建时被调用
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE person(personid INTEGER PRIMARY KEY AUTOINCREMENT,name VARCHAR(20))");
        
    }
    //软件版本号发生改变时调用
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("ALTER TABLE person ADD phone VARCHAR(12) NULL");
    }
}

流程小结:

  1. 自定义一个类继承SQLiteOpenHelper类;
  2. 在该类的构造方法的super中设置好要创建的数据库名和版本号;
  3. 重写onCreate( )方法创建表结构;
  4. 重写onUpgrade( )方法定义版本号发生改变后执行的操作。

5.sqlite3工具

  在Android SDK的platform-tools目录下踢欧冠难过了一个sqlite3.exe文件,它是一个简单的SQLite数据库管理工具,类似于MySQL提供的命令行窗口。开发者可以利用该工具来查询、管理数据库。

  • sqlite3 my.db :打开数据库文件
  • .table 查看数据库中有哪些表
  • .schema:查看建表语句
  • .quit:退出数据库的编辑
  • .exit:退出设备控制台
  • .help:查看sqlite3支持的命令

6.使用SQL语句操作数据库

  如果不想用Android提供的这些API,使用SQL语句操作, 可以直接使用SQLiteDatabase给我们提供的相关方法:

  • execSQL(SQL,Object[]):使用带占位符的SQL语句,这个是执行修改数据库内容的sql语句用的
  • rawQuery(SQL,Object[]):使用带占位符的SQL查询操作
  • move(offset):指定向上或者向下移动的行数,整数表示向下移动;负数表示向上移动
  • moveToFirst():指针移动到第一行,成功返回true,也说明有数据
  • moveToLast():指针移动到最后一样,成功返回true
  • moveToNext():指针移动到下一行,成功返回true,表明还有元素
  • moveToPrevious():移动到上一条记录
  • getCount( ):获得总得数据条数
  • isFirst():是否为第一条记录
  • isLast():是否为最后一项
  • moveToPosition(int):移动到指定行
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值