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