Android應用處理數據的方法
幾種數據存儲方式
a. SQLiteDB
在Android中我們使用SQLiteDB作爲數據庫,它具有以下特點:
- Light : 輕量級
- Standard : 標準化
- Open-Src : 開源
- No Server : 沒有服務器
- Single-tier : 單層的
- Loose-type : 寬鬆類型
- App-process : 在應用程序的進程中進行調用
下面我們挑幾個SQLiteDB的特性進行介紹。
Standard :SQLite是標準兼容的,也就是說SQL語句在SQLite均可使用
Single-tier :是指SQLite是單層的,也就是不含中間層,不需要通過什麼工具訪問數據庫,可以直接訪問。
No Server :SQLite是自包含的數據庫,當你創建的數據庫的時候,這些數據會保存在應用中的某一個文件中
Loose-type :簡單來說就是同一列中的數據可以是不同類型
使用方法參考:https://blog.csdn.net/GUYIIT/article/details/100591538
b. Internal Storage (內部存儲)
用於存放應用程序的相關數據,在內部存儲中,每個應用對應一個文件夾,並且每個文件之間不可相互訪問,應用程序只能訪問與之對應的文件。
接下來我們示範一下在內部存儲文件中的讀寫操作。
設計思想:我們在頁面創建兩個按鈕,其中一個用於寫,另一個用於讀,並將最後從文件中讀出來的字符串在TextView中進行顯示。
首先在main_activity.xml文件中添加兩個Button控件。
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Write"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/button2"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Read"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toEndOf="@+id/button1"
app:layout_constraintTop_toBottomOf="@+id/textView" />
實現負責寫的bt1的監聽功能。
bt1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
PrintWriter pw = new PrintWriter(openFileOutput("test.txt", MODE_APPEND));
pw.println("This is internal storage");
pw.close();
} catch (Exception e) {
Log.e("io", "write error");
}
}
});
實現負責讀的bt2的監聽功能。
bt2.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
TextView tv = (TextView) findViewById(R.id.textView);
BufferedInputStream bis = new BufferedInputStream(openFileInput("test.txt"));
byte[] buffer = new byte[10000];
while (bis.read(buffer) != -1) {
tv.setText(new String(buffer));//將buffer轉化爲字符串
}
bis.close();
} catch (Exception e) {
Log.e("io", "read error");
}
}
});
結果演示:
點擊write按鈕,通過adb查看寫入情況,可以發現已經成功寫入。
點擊read按鈕。
c. External Storage(外部存儲)
一般用於存放較大的文件,如圖片、音頻等,在外部存儲中的文件,每個應用程序均可訪問。
接下來我們示範一下在外部存儲文件中的讀寫操作。
設計思想:我們在頁面創建一個按鈕,用於在SD卡中創建txt文件,寫入字符串並讀出該字符串的操作,並將最後從文件中讀出來的字符串在TextView中進行顯示。
首先在main_activity.xml文件中添加Button控件。
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="SD"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.503"
app:layout_constraintStart_toEndOf="@+id/button3"
app:layout_constraintTop_toBottomOf="@+id/button2"
app:layout_constraintVertical_bias="0.502" />
實現button的讀寫操作
bt4.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
//判斷SD卡是否已經掛載
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
PrintWriter pw = new PrintWriter(new FileOutputStream(Environment.getExternalStorageDirectory()
+ "//" + "ext.txt"));
pw.println("This is a test to write external.");
pw.close();
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(Environment.getExternalStorageDirectory()
+ "//" + "ext.txt"));
buf = new byte[bis.available()];
bis.read(buf);
h.sendEmptyMessage(0x001); //將信息發給handle進行處理
bis.close();
}
} catch (Exception e) {
Log.e("io", "write error");
}
}
});
由於在新版本中的安卓不允許在子進程中對父進程的UI進行修改,所以我們需要在onCreate方法中加入handle實現對UI界面的刷新功能。
h = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case 0x001:
// call update gui method.
tv.setText(new String(buf));
break;
default:
break;
}
}
};
並將使用到的變量作爲類的成員變量使用,在 MainActivity 函數中對這些屬性進行初始化.
Handler h = null;
byte[] buf;
TextView tv;
最後我們需要在 AndroidManifest.xml 文件中對開放對程序的讀寫 SD 能力。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
在運行虛擬機時,或者使用高版本的安卓手機時,即使是在清單文件中加了權限,向sd卡寫入數據時還是會報錯:
其實這個問題是由於Android6.0更新了權限機制,具體的解決方法參考:
https://blog.csdn.net/qq_34884729/article/details/53284274
d. shared preferences (偏好設置)
用於存儲應用程序的偏好設置,用key-value的形式存儲
e. remote storage (網絡存儲)
接下來我們示範一下在如何進行網絡存儲。
設計思想:我們在頁面創建一個按鈕,用於連接 www.sohu.com 網站並讀取該頁面的html文件,並在TextView中進行顯示。
首先在main_activity.xml文件中添加Button控件。
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Remote"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/button2"
app:layout_constraintHorizontal_bias="0.496"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button1"
app:layout_constraintVertical_bias="0.502" />
實現button的網絡訪問操作
bt3.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
new Thread() {
public void run() {
try {
URL url = new URL("https://www.sohu.com");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
BufferedInputStream bis = new BufferedInputStream((con.getInputStream()));
buf = new byte[10000];
bis.read(buf);
h.sendEmptyMessage(0x001);
} catch (Exception e) {
Log.e("io", e.getMessage());
}
}
}.start();
;
}
});
最後我們需要在 AndroidManifest.xml 文件中添加網絡訪問權限
<uses-permission android:name="android.permission.INTERNET" />
值得注意的是,在運行該程序之前,我們應該先把虛擬機上的網絡打開,纔可以正常的進行網絡訪問。
程序的源碼:https://github.com/xiaoGuyi/Android-code-segment/tree/master/Read_Write