【精華】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):移動到指定行
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章