04_数据存储
Posted 渣爷
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了04_数据存储相关的知识,希望对你有一定的参考价值。
1. 理论概述
android数据存储方式:
-
SharedPreferences存储
-
手机内部文件存储
-
手机外部文件存储
-
sqlite数据库存储
-
远程服务器存储
2. 数据存储开发
2.1 SharedPreferences存储
说明
-
SP存储专门用来存储一些单一的小数据
-
存储数据的类型:boolean,float,int,long,String
-
数据保存的路径:/data/data/packageName/shared_prefs/yyy.xml
-
可以设置数据只能是当前应用读取,而别的应用不可以
-
应用卸载时会删除数据
相关API
-
SharedPrefences:对应sp文件的接口
-
context.getSharedPreferences(String name,int mode)
:得到SP对象-
name:文件名(不带.xml)
-
mode:生成的文件模式(是否是私有的,即其它应用是否可以访问)
-
-
Editor sp.edit()
:得到Editor对象 -
Xxx sp.getXxx(name, defaultValue)
:根据name得到对应的数据
-
-
Editor:能更新SP文件的接口
-
Editor put(name, value)
:保存一个键值对,没有真正保存到文件中 -
Editor remove(name)
-
commit()
:提交,数据真正保存到文件中
示例
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <EditText android:id="@+id/et_sp_key" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="存储的key" /> <EditText android:id="@+id/et_sp_value" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="存储的value" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="save" android:text="保 存" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="read" android:text="读 取" /> </LinearLayout> </LinearLayout>
/** * 测试sp存储的界面 */ public class SpActivity extends Activity { private EditText et_sp_key; private EditText et_sp_value; private SharedPreferences sp; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sp); et_sp_key = (EditText) findViewById(R.id.et_sp_key); et_sp_value = (EditText) findViewById(R.id.et_sp_value); //1. 得到sp对象 sp = getSharedPreferences("atguigu", Context.MODE_PRIVATE); } public void save(View v) { //2. 得到editor对象 SharedPreferences.Editor edit = sp.edit(); //3. 得到输入的key/value String key = et_sp_key.getText().toString(); String value = et_sp_value.getText().toString(); //4. 使用editor保存key-value edit.putString(key, value).commit(); //5. 提示 Toast.makeText(this, "保存完成!", 0).show(); } public void read(View v) { //1. 得到输入的key String key = et_sp_key.getText().toString(); //2. 根据key读取对应的value String value = sp.getString(key, null); //3. 显示 if(value==null) { Toast.makeText(this, "没有找到对应的value", 0).show(); } else { et_sp_value.setText(value); } } }
package com.atguigu.l04_datastorage; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } // 测试sp存储 public void onClickSP(View v) { startActivity(new Intent(this, SpActivity.class)); } // 测试手机内部文件存储 public void onClickIF(View v) { startActivity(new Intent(this, IFActivity.class)); } // 测试手机外部文件存储 public void onClickOF(View v) { startActivity(new Intent(this, OFActivity.class)); } public void onClickDB(View v) { } public void onClickNW(View v) { } }
说明
-
应用运行需要的一些较大的数据或图片可以用文件保存在手机内部
-
文件类型:任意
-
数据保存的路径:/data/data/projectPackage/files/
-
可以设置数据只能是当前应用读取,而别的应用不可以
-
应用卸载时会删除此数据
相关API
-
读取文件
-
FileInputStream fis = openFileInput("logo.png");
-
- 保存文件
FileOutputStream fos = openFileOutput("logo.png",MODE_PRIVATE);
- 得到files文件夹对象
File filesDir = getFilesDir();
- 操作asserts下的文件
-
- 得到Assetmanager:
context.getAssets();
- 得到Assetmanager:
-
- 读取文件:
InputStream open(filename);
- 读取文件:
- 加载图片文件
Bitmap BitmapFactory.decodeFile(String pathName)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:id="@+id/textView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="5dp" android:text="1. 将asserts下的logo.png保存到手机内部\\n2. 读取手机内部图片文件显示" android:textColor="#ff0000" android:textSize="15sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <Button android:id="@+id/btn_if_save" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="save" android:text="保 存" /> <Button android:id="@+id/btn_if_read" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="read" android:text="读 取" /> </LinearLayout> <ImageView android:id="@+id/iv_if" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/ic_launcher" /> </LinearLayout>
package com.atguigu.l04_datastorage; import android.app.Activity; import android.content.Context; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.view.View; import android.widget.ImageView; import android.widget.Toast; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; /** * 测试手机内部文件存储 */ public class IFActivity extends Activity { private ImageView iv_if; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_if); iv_if = findViewById(R.id.iv_if); } public void save(View view) throws IOException { //1.得到InputStream ->读取assets下的logo.png //得到AssetManager AssetManager manager = getAssets(); //读取文件 InputStream is = manager.open("logo.png"); //2.得到OutputStream->/data/data/packageName/files/logo.png FileOutputStream fos = openFileOutput("logo.png", Context.MODE_PRIVATE); //3.边读边写 byte[] buffer = new byte[1024]; int len = 1; while((len = is.read(buffer)) != -1){ fos.write(buffer,0,len); } fos.close(); is.close(); //4.提示 Toast.makeText(this,"保存完成",Toast.LENGTH_SHORT).show(); } // /data/data/packageName/files/logo.png public void read(View view){ //1. 得到图片文件的路径 /data/data/packageName/files String filesPath = getFilesDir().getAbsolutePath(); String imagePath = filesPath + "/logo.png"; //2.读取加载图片文件得到bitmap对象 Bitmap bitmap = BitmapFactory.decodeFile(imagePath); //3.将其设置到imageView中显示 iv_if.setImageBitmap(bitmap); } }
2.3 手机外部file存储
说明
-
应用运行用到的数据文件(如图片)可以保存到sd卡中
-
文件类型:任意
-
数据保存的路径:
-
路径1:/storage/sdcard/Android/data/packageName/files/
-
路径2:/storage/sdcard/xx/
-
-
路径1:其它应用可以访问,应用卸载时删除
-
路径2:共它应用可以访问,应用卸载时不会删除
-
必须保证sd卡挂载在手机上才能读写,否则不能操作
相关API
-
-
得到SD卡的状态:Environment.getExternalStorageState()
-
提到SD卡的路径:Environment.getExternalStorageDirectory()
-
SD卡可读写的挂载状态值:Enviroment.MEDIA_MOUNTED
-
-
context.getExternalFilesDir():
-
得到/mnt/sdcard/Android/data/package_name/files/xxx.txt
-
-
操作SD卡的权限:
-
android.permission.WRITE_EXTERNAL_STORAGE
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <EditText android:id="@+id/et_of_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="存储的文件名" /> <EditText android:id="@+id/et_of_content" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="存储的文件内容" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="save" android:text="保 存" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="read" android:text="读 取" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" > <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="save2" android:text="保 存2" /> <Button android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:onClick="read2" android:text="读 取2" /> </LinearLayout> </LinearLayout>
package com.atguigu.l04_datastorage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import android.app.Activity; import android.os.Bundle; import android.os.Environment; import android.view.View; import android.widget.EditText; import android.widget.Toast; /** * 测试手机外部文件存储 */ public class OFActivity extends Activity { private EditText et_of_name; private EditText et_of_content; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_of); et_of_name = (EditText) findViewById(R.id.et_of_name); et_of_content = (EditText) findViewById(R.id.et_of_content); } public void save(View v) throws IOException { //1. 判断sd卡状态, 如果是挂载的状态才继续, 否则提示 if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { //2. 读取输入的文件名/内容 String fileName = et_of_name.getText().toString(); String content = et_of_content.getText().toString(); //3. 得到指定文件的OutputStream //1).得到sd卡下的files路径 String filesPath = getExternalFilesDir(null).getAbsolutePath(); //2).组成完整路径 String filePath = filesPath+"/"+fileName; //3). 创建FileOutputStream FileOutputStream fos = new FileOutputStream(filePath); //4. 写数据 fos.write(content.getBytes("utf-8")); fos.close(); //5. 提示 Toast.makeText(this, "保存完成", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "sd卡没有挂载", Toast.LENGTH_SHORT).show(); } } public void read(View v) throws Exception { // 1. 判断sd卡状态, 如果是挂载的状态才继续, 否则提示 if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { // 2. 读取输入的文件名 String fileName = et_of_name.getText().toString(); // 3. 得到指定文件的InputStream // 1).得到sd卡下的files路径 String filesPath = getExternalFilesDir(null).getAbsolutePath(); // 2).组成完整路径 String filePath = filesPath + "/" + fileName; // 3). 创建FileInputStream FileInputStream fis = new FileInputStream(filePath); // 4. 读取数据, 成String ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = -1; while((len=fis.read(buffer))!=-1) { baos.write(buffer, 0, len); } String content = baos.toString(); // 5. 显示 et_of_content.setText(content); } else { Toast.makeText(this, "sd卡没有挂载", Toast.LENGTH_SHORT).show(); } } // /storage/sdcard/atguigu/xxx.txt public void save2(View v) throws IOException { //1. 判断sd卡状态, 如果是挂载的状态才继续, 否则提示 if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { //2. 读取输入的文件名/内容 String fileName = et_of_name.getText().toString(); String content = et_of_content.getText().toString(); //3. 得到指定文件的OutputStream //1). /storage/sdcard/ String sdPath = Environment.getExternalStorageDirectory().getAbsolutePath(); //2). /storage/sdcard/atguigu/(创建文件夹) File file = new File(sdPath+"/atguigu"); if(!file.exists()) { file.mkdirs();//创建文件夹 } //3). /storage/sdcard/atguigu/xxx.txt String filePath = sdPath+"/atguigu/"+fileName; //4). 创建输出流 FileOutputStream fos = new FileOutputStream(filePath); //4. 写数据 fos.write(content.getBytes("utf-8")); fos.close(); //5. 提示 Toast.makeText(this, "保存完成", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "sd卡没有挂载", Toast.LENGTH_SHORT).show(); } } public void read2(View v) throws Exception { // 1. 判断sd卡状态, 如果是挂载的状态才继续, 否则提示 if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { // 2. 读取输入的文件名 String fileName = et_of_name.getText().toString(); // 3. 得到指定文件的InputStream String sdPath = Environment.getExternalStorageDirectory().getAbsolutePath(); String filePath = sdPath+"/atguigu/"+fileName; FileInputStream fis = new FileInputStream(filePath); // 4. 读取数据, 成String ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = -1; while((len=fis.read(buffer))!=-1) { baos.write(buffer, 0, len); } String content = baos.toString(); fis.close(); // 5. 显示 et_of_content.setText(content); } else { Toast.makeText(this, "sd卡没有挂载", Toast.LENGTH_SHORT).show(); } } }
比较内部文件与外部文件存储?
-
-
是否是私有的
-
应用卸载是否自动删除
2.4 SQLite数据库存储
说明
-
应用运行需要保存一系列有一定结构的数据,比如说公司员工信息
-
文件类型:db
-
数据保存的路径 :/data/data/projectPackage/databases/xxx.db
-
默认情况下其它应用不能访问,当前应用可以通过ContentProvider提供其它应用操作
-
应用卸载时会删除此数据
SQLite数据库
SQLite(http://www.sqlite.org),是一款轻型的关系型数据库服务器,移动设备的数据库存储都使用SQLite,它的特点:
-
安装文件小:最小只有几百K,Android系统已经安装
-
支持多操作系统:Android,WP,ios,Windows,Linux等
-
支持多语言:比如Java、php、C#等
-
处理速度快:处理速度比mysql,Oracle,SQLServer都要快(数据量不是特别大)
-
SQLite中的一个数据库就是一个.db文件(本质上.db的后缀都可以不指定)
SQLite数据库命令行
-
adb shell 进入系统根目录
-
cd data/data/…/databases:进入包含数据库文件的文件夹下
-
sqlite3 contacts2.db:使用sqlite3命令连接指定的数据库文件,进入连接模式
-
help:查看命令列表
-
tables:查看所有表的列表
-
执行 insert/delete/update/select语句
-
exit:退出数据库连接模式
-
Ctrl+C:直接退出shell模式
数据类型
-
INT/INTEGER:整数
-
FLOAT/DOUBLE:小数
-
CHAR/VARCHAR/TEXT:字符串文本
-
BLOB:文件
-
DATE/DATETIME:日期/日期时间
SQLite建表
SQLite操作数据库的sql语句基本与mysql一样,但需要注意下面2点:
-
最大的不同在于创建表时可以不用指定字段类型,sqlite可以适时的自动转换,但除varchar类型外最好指定类型
-
sqlite中的主键名称建议使用_id
create table employee( _id integer primary key autoincrement,/*主键,自增长*/ name 从外部存储中检索 Relay 查询片段的变量ubuntu16.04 yum报错:There are no enabled repos. Run “yum repolist all“ to see the repos you have.(代码片段