1. 程式人生 > >4類Storage方案(AS開發實戰第四章學習筆記)

4類Storage方案(AS開發實戰第四章學習筆記)

uil sed base 改變 查詢語句 class getc tex dcim

4.1 共享參數SharedPreferences

SharedPreferences按照key-value對的方式把數據保存在配置文件中,該配置文件符合XML規範,文件路徑是/data/data/應用包名/shared_prefs/文件名.xml,下面是一個共享參數的XML文件示例:

<?xml verson=’1.0’ encoding=’utf-8’ standalone=’yes’?>

<map>

<string name=”name”>Mr Lee</string>

<int name=”age” value=”30” />

<boolean name=”married” value=”true” />

<float name=”weight” value=”100.0” />

</map>

示例代碼:

private SharedPreferences sps;

sps = getSharedPreferences(“share”, Context.MODE_PRIVATE);

getSharedPreferences的第一個參數是文件名,上面的share表示當前使用的共享文件名是share.xml,第二個參數是操作模式,一般都填MODE_PRIVATE表示私有模式

SharedPreferences.Editor editor = sps.edit();

editor.putString(“name”, “Mr Lee”);

editor.putInt(“age”, “30”);

editor.putBoolean(“married”, “true”);

editor.putFloat(“weight”, “100f”);

editor.commit();

String name = sps.getString(“name”, “”);

int age = sps.getInt(“age”, 0);

boolean married = sps.getBoolean(“married”, false);

float weight = sps.getFloat(“weight”, 0);

共享參數的get方法第二個參數表示默認值

(這裏例程用了map,有待研究)

4.2 數據庫SQLite

SQLite的基本用法:

(1)建表時為避免重復操作,應加上IF NOT EXISTS關鍵詞,例如CREATE TABLE IF NOT EXISTS table_name

(2)刪表時為避免重復操作,應加上IF EXISTS關鍵詞,例如DROP TABLE IF EXISTS table_name

(3)添加新列時使用ALTER TABLE table_name ADD COLUMN …

(4)在SQLite中,ALTER語句每次只能添加一列,如果要添加多列,就只能分多次添加

(5)SQLite支持整型INTEGER,字符串VARCHAR,浮點數FLOAT,但不支持布爾類型,布爾類型數要使用整型保存,如果直接保存布爾數據,在入庫時SQLite就會自動將其轉為0或1

(6)SQLite建表時需要一個唯一標識字段,字段名為_id,每建一張新表都要例行公事加上該字段定義,具體屬性定義為_id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL

(7)條件語句等號後面的字符串值要用單引號括起來,如果沒有使用單引號括起來,在運行時就會報錯

SQLiteDatabase是SQLite的數據庫管理類,我們可以在活動頁面代碼或任何能取到Context的地方獲取數據庫示例,參考代碼如下:

//創建數據庫,如果已存在就打開

SQLiteDatabase db = getApplicationContext().openOrCreateDatabase(“test.db”, Context.MODE_PRIVATE, null);

//刪除數據庫

getApplicationContext().deleteDatabase(“test.db”);

SQLiteDatabase提供了若幹操作數據表的API,常用的方法有3類,列舉如下:

1.管理類,用於數據庫層面的操作
openDatabase:打開指定路徑的數據庫

isOpen:判斷數據庫是否已打開

close:關閉數據庫

getVersion:獲取數據庫的版本號

setVersion:設置數據庫的版本號

2.事務類,用於事務層面的操作

beginTransaction:開始事務

setTransactionSuccessful:設置事務的成功標誌

endTransaction:結束事務,執行本方法時,系統會判斷是否已執行setTransactionSuccessful,如果之前已設置就提交,如果沒有設置就回滾

3.數據處理類,用於數據表層面的操作

execSQL:執行拼接好的SQLite控制語句,一般用於建表、刪表、變更表結構

delete:刪除符合條件的記錄

update:更新符合條件的記錄

insert:插入一條記錄

query:執行查詢操作,返回結果集的遊標

rawQuery:執行拼接好的SQL查詢語句,返回結果集的遊標

SQLiteOpenHelper

具體使用步驟如下:

(1)新建一個繼承自SQLiteOpenHelper的數據庫操作類,提示重寫onCreate和 OnUpgrade兩個方法,其中onCreate方法只在第一次打開數據庫時執行,在此可進行表結構創建的操作;onUpgrade方法在數據庫版本升高時執行,因此我們可以在onUpgrade函數內部根據新舊版本號進行表結構變更處理

(2)封裝保證數據庫安全的必要方法,包括獲取單例對象,打開數據庫連接,關閉數據庫連接

(3)提供對表記錄進行增加、刪除、修改、查詢的操作方法

Cursor的常用方法:

1.遊標控制類方法,用於指定遊標的狀態

Close:關閉遊標

isClosed:判斷遊標是否關閉

isFirst:判斷遊標是否在開頭

isLast:判斷遊標是否在末尾

2.遊標移動類方法,把遊標移動到指定位置

moveToFirst:移動遊標到開頭

moveToLast:移動遊標到末尾

moveToNext:移動遊標到下一條記錄

moveToPrevious:移動遊標到上一條記錄

move:往後移動遊標若幹條記錄

moveToPosition:移動遊標到指定位置的記錄

3.獲取記錄類方法,可獲取記錄的數量、類型以及取值

getCount:獲取結果記錄的數值

getInt:獲取指定字段的整型值

getFloat:獲取指定字段的浮點數值

getString:獲取指定字段的字符串值

getType:獲取指定字段的字段類型

關於SQLiteOpenHelper的簡單“封裝”,見Database類的封裝.rar

優化記住密碼功能:

(1)聲明一個UserDBHelper對象,然後在活動頁面的OnResume方法中打開數據庫連接,在onPause方法中關閉數據庫連接,示例代碼如下:

@Override

protected void onResume() {

super.onResume();

mHelper = UserDBHelper.getInstance(this, 2);

mHelper.openWriteLink();

}

@Override

protected void onPause() {

super.onPause();

mHelper.closeLink();

}

(2)在登錄成功時,如果用戶勾選了“記住密碼”,就使用數據庫保存手機號碼與密碼在內的登錄信息,在loginSuccess函數中增加如下代碼:

if(bRemember) {

UserInfo info = new UserInfo();

info.phone = et_phone.getText().toString();

info.update_time = DateUtil.getNowDateTime(“yyyy-MM-dd HH:mm:ss”);

mHelper.insert(info);

}

(3)再次打開登錄頁面,用戶輸入手機號完畢後點擊密碼輸入框時,App到數據庫中根據手機號查找登錄記錄,並將記錄結果中的密碼填入密碼框

EditText比較特殊,點擊後只是讓其獲得焦點,再次點擊才會觸發點擊事件。也就是說,要連續點擊兩次EditText才會處理點擊事件,這裏提供一個解決辦法:先給密碼框註冊一個焦點變更監聽器,比如下面這行代碼:

et_password.setOnFocusChangeListener(this);

這個焦點變更監聽器要實現接口OnFocusChangeListener,對應的事件處理方法是onFocusChange,將數據庫查詢操作放在該方法中,詳細代碼如下:

@Override

public void onFocusChange(View v, boolean hasFocus) {

String phone = et_phone.getText().toString();

if(v.getId() == R.id.et_password) {

if(phone.length() > 0 && hasFocus == true) {

UserInfo info = mHelpler.queryByPhone(phone);

if(info != null) {

et_password.setText(info.password);

}

}

}

}

4.3 SD卡文件操作

獲取手機上的SD卡信息通過Environment類實現,該類是App獲取各種目錄信息的工具,主要方法有以下7種:

getRootDirectory:獲得系統根目錄的路徑

getDataDirectory:獲得系統數據目錄的路徑

getDownloadCacheDirectory獲得下載緩存目錄的路徑

getExternalStorageDirectory:獲得外部存儲(SD卡)的路徑

getExternalStorageState:獲得SD卡的狀態

SD卡的存儲狀態取值說明

Environment類的存儲狀態常量名

常量值

常量說明

MEDIA_UNKNOWN

unknown

未知

MEDIA_REMOVED

removed

已經移除

MEDIA_UNMOUNTED

unmounted

未掛載

MEDIA_CHECKING

checking

正在檢查

MEDIA_NOFS

nofs

不支持的文件系統

MEDIA_MOUNTED

mounted

已經掛載,且是可讀寫狀態

MEDIA_MOUNTED_READ_ONLY

mounted_ro

已經掛載,且是只讀狀態

MEDIA_SHARED

shared

當前未掛載,但通過USB共享

MEDIA_BAD_REMOVAL

bad_removal

未掛載就被移除

MEDIA_UNMOUNTABLE

unmountable

無法掛載

MEDIA_EJECTING

ejecting

正在彈出

getStorageState:獲得指定目錄的狀態

getExternalStoragePublicDirectory:獲得SD卡指定類型目錄的路徑

SD卡的目錄類型取值說明

Environment類的目錄類型

常量值

常量說明

DIRECTORY_DCIM

DCIM

相片存放目錄(包括相機拍攝的圖片和視頻)

DIRECTORY_DOCUMENTS

Documents

文檔存放目錄

DIRECTORY_DOWNLOADS

Download

下載文件存放目錄

DIRECTORY_MOVIES

Movies

視頻存放目錄

DIRECTORY_MUSIC

Music

音樂存放目錄

DIRECTORY_PICTURES

Pictures

圖片存放目錄

為正常操作SD卡,需要在AndroidManifest.xml中聲明SD卡的權限,具體代碼如下:

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

<uses-permission android:name=”android.permission.READ_EXTERNAL_STORAGE”/>

<uses-permission android:name=”android:permission.MOUNT_UNMOUNT_FILESYSTEMS”>

示例:

desc = Environment.getRootDirectory().getAbsolutePath());
desc = Environment.getDataDirectory().getAbsolutePath());
desc = Environment.getDownloadCacheDirectory().getAbsolutePath());
desc = Environment.getExternalStorageDirectory().getAbsolutePath());
desc = Environment.getExternalStorageState());
desc = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM));
//DIRECTORY_DOCUMENTS是Android4.4.2(SDK19)及以上版本才有的常量
//如果不做SDK版本判斷,那麽在低版本Android(例如4.2.2)上運行會報錯
//java.lang.NoSuchFieldError: android.os.Environment.DIRECTORY_DOCUMENTS
//因此在獲取DIRECTORY_DOCUMENTS時要加上判斷條件if (VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) ,

其他的則不用,示例如下:

Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS));
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES));

文本文件讀寫&圖片文件讀寫:工具類FileUtil.java

文本文件的讀寫一般借助於FileOutputStream和FileInputStream

Android的圖片處理類是Bitmap,App讀寫Bitmap可以使用FileOutputStream和FileInputStream,不過在實際開發中,讀寫圖片文件一般用性能更好的BufferedOutputStream和BufferedInputStream,保存圖片文件時用到的Bitmap的compress方法,可指定圖片類型和壓縮質量,打開圖片文件時使用BitmapFactory的decodeStream方法。

事實上,BitmapFactory還提供了其他方法:

decodeFile:該方法直接傳文件路徑的字符串,即可將指定路徑的圖片讀取到Bitmap對象

decodeResource:該方法可從資源文件中讀取圖片信息,第一個參數一般傳getResources(),第二個參數傳drawable圖片的資源id,如R.drawable.phone

4.4 Application基礎

在App運行過程中有且僅有一個Application對象貫穿整個生命周期,activity節點的上級正是application

Application的生命周期覆蓋App運行的全過程,不像短暫的Activity生命周期,只要進入別的頁面,原頁面就被停止或銷毀,因此,通過利用Application的持久存在性可以在Application對象中保存全局變量,適合在Application中保存的全局變量主要有下面3類數據:

(1)會頻繁讀取的信息,如用戶名,手機號等

(2)從網絡上獲取的臨時數據,為節約流量、減少用戶等待時間,想暫時放在內存中供下次使用,如logo、商品圖片等

(3)容易因頻繁分配內存而導致內存泄漏的對象,如Handler對象

要想通過Application實現全局內存的讀寫,得完成以下3項工作:

(1)寫一個繼承自Application的類MainApplication,該類要采用單例模式,內部聲明自身類的一個靜態成員對象,在創建app時把自身賦值給這個靜態對象,然後提供該靜態對象的獲取方法getInstance

(2)在Activity中調用MainApplication的getInstance方法,獲得MainApplication的一個靜態對象,通過該對象訪問MainApplication的公共變量和公共方法

(3)不要忘了在AndroidManifest.xml中註冊新定義的Application類名,即在application節點中增加android:name屬性,值為.MainApplication

樣例類:MainApplication.java

(MainApplication類可以重寫的方法主要有以下4個:

onCreate:在App啟動時調用

onTerminate:在App退出時調用(該方法就是個擺設……)

onLowMemory:在低內存時調用

onConfigurationChanged:在配置改變時調用,例如從豎屏變為橫屏)

完成自定義MainApplication類的代碼後,Activity頁面代碼即可直接通過MainApplication.getInstance().mInfoMap對全局變量進行增刪改查操作

4類Storage方案(AS開發實戰第四章學習筆記)