目录:
1.概述
2.SQLite
2.1 概述:
2.2 数据类型+存储位置
2.3 数据操作及其相关方法
2.4 代码示例
3.SharePreferences
3.1 概述
3.2 操作模式+存储位置
3.4 代码示例
4.File
4.1 概述
4.2 操作模式+存储位置
4.3 手机内存+sdcard保存
5.Content provider
6.网络存储
1.概述
数据存储在App开发和使用中是必不可少的,比如我们会从网络中保存图片、视频等到本地,同时我们的应用在用户使用过程中会
对用户的行为做一些记录,以此达到增加用户体验的效果,至于保存哪些用户数据需要由需求而定。
当然我们数据存储的方式也不止一种,在android平台下包含:SQLite,SharePreferences,File,Content provider,网络存储等5种
存储方式,至于选用哪一种存储方式比较合理,就需要我们在实际开发中综合考虑,当然,我们在后面也会对每一种存储方式适合存储
什么样的数据做一些简单的概述。
2.SQLite
2.1 概述:
SQLite属于轻型嵌入式关系型数据库,占用资源比较低,应用场景主要在存储一些需要具备一些保密性,数据量比较大,同时
逻辑关系比较复杂的数据,比如:在天气应用中记录用户时区与位置,在闹钟应用中存储一些用户定义任务等等。
2.2 数据类型+存储位置
(1)数据类型:NULL,INTEGER(整型),TEXT(字符串文本),REAL(浮点型),BLOB(二进制型)
(2)默认存储位置:/data/data/<packageName>/databases
2.3 数据操作及其相关方法
(1) 对于数据库的操作位于android.database.sqlite包下,主要的类有:SQLiteOpenHelper(数据库帮助类)和SQLiteDatabase(数据库
类),SQLiteOpenHelper类主要用户数据库创建于版本管理。而SQLiteDatabase类当然主要用于数据库的常规操作(增删改查)和数据库的维护
(2) SQLiteOpenHelper常用方法
(3) SQLiteDatabase常用方法
数据库操作型方法:
数据表与数据处理型方法:
事务处理型方法:
2.4 代码示例
(1) MySqliteOpenHelper.java
(2) SqliteActivity.java
(3) activity_sqlite.xml
(4) 操作和相应的Log打印(ps:之前添加过一条)
添加数据:
修改数据:
查询数据:
删除数据+查询数据:
3.SharePreferences
3.1 概述
SharePreferences是一种轻量级的存储数据方式,以xml键值对的形式存储数据,应用场景主要是存储应用的配置信息
3.2 操作模式+存储位置
(1)操作模式:
MODE_PRIVATE:文件仅应用程序自己能访问。
MODE_WORLD_READABLE:文件除了自己访问外还可以被其它应该程序读取(推荐使用Content provider)
MODE_WORLD_WRITEABLE:文件除了自己访问外还可以被其它应该程序读取和写入(推荐使用Content provider)
MODE_APPEND:在文件尾部追加
(2)默认存储位置:/data/data/<packageName>/shared_prefs
3.4 代码示例(实现登陆功能,将用户名、密码以及是否保存密码数据保存到SharePreferences文件中,当然实际开发为了账户安全
需慎重使用)
(1) MainActivity.java
(2) activity_main.xml
(3) 效果截图
(4) Log打印(点击登陆,再点击读取数据)
(5) DDMS查看手机文件截图
4.File
4.1 概述
File文件存储,在android应用做,我们除了一些简单的数据和关系型数据需要通过Sharepreference和sqlite存储以外,通常
还有大数据型文件存储的需求,比如文本文件、图片文件、视频文件等,这时候File文件存储就比较符合需求,当然默认存储位置在手机
内存中,由于内存有限,大多数情况会有存储到sdcard的需求。
4.2 操作模式+存储位置
MODE_PRIVATE:文件仅应用程序自己能访问(默认)。
MODE_WORLD_READABLE:文件除了自己访问外还可以被其它应该程序读取(推荐使用Content provider)
MODE_WORLD_WRITEABLE:文件除了自己访问外还可以被其它应该程序读取和写入(推荐使用Content provider)
MODE_APPEND:在文件尾部追加
(2)默认存储位置:/data/data/<packageName>/files
4.3 手机内存+sdcard保存文件
(1)MainActivity.java
(2)布局activity_main.xml
(3)访问sdcard需要注册权限
(4))手机内存和sdcard保存文件效果图+验证截图
Content provider也被封为四大组件之一,是一种应用之间提供数据共享的机制,其实他的存储方式也是通过数据库或者其他存储
方式实现的,他只是提供一个供外界访问的接口,方便外界访问而已。之前我写过一篇关于Content provider的文章,这里就不做总结了,需要的伙伴可以看看,比较基础。
http://blog.csdn.net/qq_28057577/article/details/51454326
6.网络存储
所谓的网络存储也就是通过网络请求获取数据,后面在网络部分进行学习,在此暂时就不学习了。
推荐文章:http://www.cnblogs.com/hanyonglu/archive/2012/03/01/2374894.html
1.概述
2.SQLite
2.1 概述:
2.2 数据类型+存储位置
2.3 数据操作及其相关方法
2.4 代码示例
3.SharePreferences
3.1 概述
3.2 操作模式+存储位置
3.4 代码示例
4.File
4.1 概述
4.2 操作模式+存储位置
4.3 手机内存+sdcard保存
5.Content provider
6.网络存储
1.概述
数据存储在App开发和使用中是必不可少的,比如我们会从网络中保存图片、视频等到本地,同时我们的应用在用户使用过程中会
对用户的行为做一些记录,以此达到增加用户体验的效果,至于保存哪些用户数据需要由需求而定。
当然我们数据存储的方式也不止一种,在android平台下包含:SQLite,SharePreferences,File,Content provider,网络存储等5种
存储方式,至于选用哪一种存储方式比较合理,就需要我们在实际开发中综合考虑,当然,我们在后面也会对每一种存储方式适合存储
什么样的数据做一些简单的概述。
2.SQLite
2.1 概述:
SQLite属于轻型嵌入式关系型数据库,占用资源比较低,应用场景主要在存储一些需要具备一些保密性,数据量比较大,同时
逻辑关系比较复杂的数据,比如:在天气应用中记录用户时区与位置,在闹钟应用中存储一些用户定义任务等等。
2.2 数据类型+存储位置
(1)数据类型:NULL,INTEGER(整型),TEXT(字符串文本),REAL(浮点型),BLOB(二进制型)
(2)默认存储位置:/data/data/<packageName>/databases
2.3 数据操作及其相关方法
(1) 对于数据库的操作位于android.database.sqlite包下,主要的类有:SQLiteOpenHelper(数据库帮助类)和SQLiteDatabase(数据库
类),SQLiteOpenHelper类主要用户数据库创建于版本管理。而SQLiteDatabase类当然主要用于数据库的常规操作(增删改查)和数据库的维护
(2) SQLiteOpenHelper常用方法
/*构造方法参数:
* 1.Context:上下文
* 2.name:需要创建的数据库名
* 3.SQLiteDatabase.CursorFactory:提供创建Cursor对象,默认为null
* 4.version:数据库版本
* 5.errorHandler:数据库中断时的错误报告处理,null,为默认处理方式
* */
public MySqliteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {}
public MySqliteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {}
//返回链接的数据库名
public String getDatabaseName() {}
//调用时间:在数据库需要onDowngrade的时候调用与onUpgrade类似
//方法在事务中执行,如果出现异常,数据会回滚
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
//数据库已经被打开的时候调用
public void onOpen(SQLiteDatabase db) {}
//在数据库链接正在配置是调用,用于开启也些相关配置
public void onConfigure(SQLiteDatabase db) {}
//关闭数据库链接
public synchronized void close() {}
//获取一个可读的数据库对象
public SQLiteDatabase getReadableDatabase() {}
//获取一个可读写的数据库对象
public SQLiteDatabase getWritableDatabase() {}
//数据库第一次创建时调用
public void onCreate(SQLiteDatabase db) {}
//调用时间:在数据库需要更新的时候调用
//方法在事务中执行,如果出现异常,数据会回滚
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
(3) SQLiteDatabase常用方法
数据库操作型方法:
//创建数据库,该数据库在关闭之后数据将消失
public static SQLiteDatabase create(CursorFactory factory) {}
//打开或者创建指定文件路径的数据库
public static SQLiteDatabase openOrCreateDatabase(File file, CursorFactory factory) {}
//打开指定文件路径的数据库
public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags) {}
//删除指定路径的数据库
public static boolean deleteDatabase(File file) {}
数据表与数据处理型方法:
//执行sql语句,可实现增删改查,与表的创建,删除
public void execSQL(String sql, Object[] bindArgs) throws SQLException {}
public void execSQL(String sql) throws SQLException {}
//删除指定数据
public int delete(String table, String whereClause, String[] whereArgs) {}
//查询数据
public Cursor query(boolean distinct, String table, String[] columns,
String selection, String[] selectionArgs, String groupBy,
String having, String orderBy, String limit) {}
//执行已定义的sql语句,返回结果Cursor
public Cursor rawQuery(String sql, String[] selectionArgs) {}
//插入数据
public long insert(String table, String nullColumnHack, ContentValues values) {}
//更新数据
public int update(String table, ContentValues values, String whereClause, String[] whereArgs) {}
事务处理型方法:
//表示事务执行成功
public void setTransactionSuccessful() {}
//结束某个事务
public void endTransaction() {}
//开启事务
private void beginTransaction(){}
2.4 代码示例
(1) MySqliteOpenHelper.java
package com.example.database;
import android.content.Context;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
/**
* Created by elimy on 2016-09-03.
*/
public class MySqliteOpenHelper extends SQLiteOpenHelper {
private final String DEBUG ="DEBUG";
//如果数据库名和版本固定,不需要改变可以如下设置,调用时只需要传入上下文即可
private static final String DEFULT_DB_NAME ="first.db";
private static final int DEFULT_VERSION = 1;
public MySqliteOpenHelper(Context context) {
super(context, DEFULT_DB_NAME, null, DEFULT_VERSION);
}
/*构造方法参数:
* 1.Context:上下文
* 2.name:需要创建的数据库名
* 3.SQLiteDatabase.CursorFactory:提供创建Cursor对象,默认为null
* 4.version:数据库版本
* 5.errorHandler:数据库中断时的错误报告处理,null,为默认处理方式
* */
public MySqliteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {
super(context, name, factory, version, errorHandler);
}
public MySqliteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
/*
* 作用:返回链接的数据库名
* */
@Override
public String getDatabaseName() {
return super.getDatabaseName();
}
/*
*调用时间:在数据库需要onDowngrade的时候调用与onUpgrade类似
* 方法在事务中执行,如果出现异常,数据会回滚
* */
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.d(DEBUG,"onDowngrade()");
super.onDowngrade(db, oldVersion, newVersion);
}
/*
*调用时间:数据库已经被打开的时候调用
* */
@Override
public void onOpen(SQLiteDatabase db) {
Log.d(DEBUG,"onOpen()");
super.onOpen(db);
}
/*
*在数据库链接正在配置是调用,用于开启也些相关配置
* */
@Override
public void onConfigure(SQLiteDatabase db) {
Log.d(DEBUG,"onConfigure()");
super.onConfigure(db);
}
/*
*关闭数据库链接
* */
@Override
public synchronized void close() {
Log.d(DEBUG,"close()");
super.close();
}
/*
* 获取一个可读的数据库对象
* */
@Override
public SQLiteDatabase getReadableDatabase() {
Log.d(DEBUG,"getReadableDatabase()");
return super.getReadableDatabase();
}
/*
* 获取一个可读写的数据库对象
* */
@Override
public SQLiteDatabase getWritableDatabase() {
Log.d(DEBUG,"getWritableDatabase()");
return super.getWritableDatabase();
}
/*
* 数据库第一次创建时调用
* */
@Override
public void onCreate(SQLiteDatabase db) {
//创建数据表users
db.execSQL("create table users(" +
"u_id INTEGER primary key autoincrement," +
"u_name TEXT," +
"u_password TEXT," +
"u_sex TEXT," +
"u_age INTEGER)");
Log.d(DEBUG,"onCreate()");
}
/*
*调用时间:在数据库需要更新的时候调用
* 方法在事务中执行,如果出现异常,数据会回滚
* */
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.d(DEBUG,"onUpgrade()");
}
}
(2) SqliteActivity.java
package com.example.database;
import android.content.ContentValues;
import android.content.DialogInterface;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class SqliteActivity extends AppCompatActivity implements View.OnClickListener {
private Button add,update,delete,select;
private MySqliteOpenHelper helper;
private SQLiteDatabase db;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sqlite);
//初始化数据
add = (Button) findViewById(R.id.add);
update = (Button) findViewById(R.id.update);
select = (Button) findViewById(R.id.select);
delete = (Button) findViewById(R.id.delete);
//注册监听器
add.setOnClickListener(this);
update.setOnClickListener(this);
select.setOnClickListener(this);
delete.setOnClickListener(this);
//通过MySqliteOpenHelper的带一个参数构造函数,初始化helper对象
helper = new MySqliteOpenHelper(SqliteActivity.this);
}
public void insertData(){
//开启一个可写的数据库对象
db = helper.getWritableDatabase();
//插入数据集(键值对)初始化
ContentValues values = new ContentValues();
values.put("u_name","Elimy");
values.put("u_password","456");
values.put("u_sex","男");
values.put("u_age",26);
//插入数据
//table:表名, nullColumnHack:如果可为空的字段未赋值则设置为空,
// ContentValues:数据集
long back = db.insert("users",null,values);
if (back !=-1){
Toast.makeText(SqliteActivity.this,"添加成功",Toast.LENGTH_SHORT).show();
Log.d("add","添加成功");
}else {
Log.d("add","添加失败");
}
//释放数据库连接对象
db.close();
}
/*
* 更新数据
* */
public void updateData(){
//开启一个可写的数据库对象
db = helper.getWritableDatabase();
//插入数据集(键值对)初始化
ContentValues values = new ContentValues();
values.put("u_name","Andy");
values.put("u_password","789");
values.put("u_sex","女");
values.put("u_age",26);
//更新数据
long back = db.update("users",values,"u_id=?",new String[]{"1"});
if (back !=0){
Toast.makeText(SqliteActivity.this,"修改成功",Toast.LENGTH_SHORT).show();
Log.d("update","修改成功");
}else {
Log.d("update","修改失败");
}
//释放数据库连接对象
db.close();
}
/*
* 查询数据
* */
public void selectData(){
//开启一个可写的数据库对象
db = helper.getReadableDatabase();
//查询
Cursor cursor = db.query("users",new String[]{"u_name","u_password","u_sex","u_age"},null,null,null,null,null);
while (cursor.moveToNext()){
Log.d("users",cursor.getString(cursor.getColumnIndex("u_name"))+"+"+cursor.getString(cursor.getColumnIndex("u_password"))+"+"+cursor.getString(cursor.getColumnIndex("u_sex"))+"+"+cursor.getString(cursor.getColumnIndex("u_age")));
}
//释放数据库连接对象
db.close();
}
/*
* 删除数据
* */
public void deleteData(){
//开启一个可写的数据库对象
db = helper.getWritableDatabase();
//删除数据
int back = db.delete("users","u_id=?",new String[]{"1"});
if (back == 0){
Log.d("delete","删除失败");
}else {
Log.d("delete","删除成功");
}
//释放数据库连接对象
db.close();
}
/*
* 点击事件监听方法
* */
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.add :
insertData();
break;
case R.id.update:
updateData();
break;
case R.id.select:
selectData();
break;
case R.id.delete:
deleteData();
break;
default:
break;
}
}
}
(3) activity_sqlite.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.database.SqliteActivity">
<Button
android:id="@+id/add"
android:text="插入数据"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/update"
android:layout_below="@+id/add"
android:text="修改数据"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/select"
android:text="查询数据"
android:layout_below="@+id/update"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/delete"
android:text="删除数据"
android:layout_below="@+id/select"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
(4) 操作和相应的Log打印(ps:之前添加过一条)
添加数据:
09-03 08:39:37.976 9594-9594/? D/DEBUG: getWritableDatabase()
09-03 08:39:37.980 9594-9594/? D/DEBUG: onConfigure()
09-03 08:39:37.980 9594-9594/? D/DEBUG: onOpen()
09-03 08:39:37.992 9594-9594/? D/add: 添加成功
修改数据:
09-03 08:40:45.972 9594-9594/? D/DEBUG: getWritableDatabase()
09-03 08:40:45.972 9594-9594/? D/DEBUG: onConfigure()
09-03 08:40:45.972 9594-9594/? D/DEBUG: onOpen()
09-03 08:40:45.980 9594-9594/? D/update: 修改成功
查询数据:
09-03 08:42:22.672 9594-9594/? D/DEBUG: getReadableDatabase()
09-03 08:42:22.676 9594-9594/? D/DEBUG: onConfigure()
09-03 08:42:22.676 9594-9594/? D/DEBUG: onOpen()
09-03 08:42:22.676 9594-9594/? D/users: Andy+789+女+26
09-03 08:42:22.676 9594-9594/? D/users: Elimy+456+男+26
删除数据+查询数据:
09-03 08:43:17.040 9594-9594/? D/DEBUG: getWritableDatabase()
09-03 08:43:17.040 9594-9594/? D/DEBUG: onConfigure()
09-03 08:43:17.044 9594-9594/? D/DEBUG: onOpen()
09-03 08:43:17.052 9594-9594/? D/delete: 删除成功
09-03 08:43:23.084 416-565/system_process W/ThrottleService: unable to find stats for iface rmnet0
09-03 08:43:23.496 9594-9594/? D/DEBUG: getReadableDatabase()
09-03 08:43:23.496 9594-9594/? D/DEBUG: onConfigure()
09-03 08:43:23.496 9594-9594/? D/DEBUG: onOpen()
09-03 08:43:23.496 9594-9594/? D/users: Elimy+456+男+26
3.SharePreferences
3.1 概述
SharePreferences是一种轻量级的存储数据方式,以xml键值对的形式存储数据,应用场景主要是存储应用的配置信息
3.2 操作模式+存储位置
(1)操作模式:
MODE_PRIVATE:文件仅应用程序自己能访问。
MODE_WORLD_READABLE:文件除了自己访问外还可以被其它应该程序读取(推荐使用Content provider)
MODE_WORLD_WRITEABLE:文件除了自己访问外还可以被其它应该程序读取和写入(推荐使用Content provider)
MODE_APPEND:在文件尾部追加
(2)默认存储位置:/data/data/<packageName>/shared_prefs
3.4 代码示例(实现登陆功能,将用户名、密码以及是否保存密码数据保存到SharePreferences文件中,当然实际开发为了账户安全
需慎重使用)
(1) MainActivity.java
package com.example.sharepreferences;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private EditText edit_userNmae,edit_password;
private Button cancel,login,read;
private CheckBox save;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化控件
edit_userNmae = (EditText) findViewById(R.id.editText_name);
edit_password = (EditText) findViewById(R.id.editText_pas);
cancel = (Button) findViewById(R.id.cancel);
login = (Button) findViewById(R.id.login);
save = (CheckBox) findViewById(R.id.check);
read = (Button) findViewById(R.id.read);
//注册监听
cancel.setOnClickListener(this);
login.setOnClickListener(this);
read.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.cancel:
Toast.makeText(MainActivity.this,"取消登录",Toast.LENGTH_SHORT).show();
break;
case R.id.login:
//获取用户输入数据
String user_name = edit_userNmae.getText().toString().trim();
String password = edit_password.getText().toString().trim();
Boolean isSavePas = save.isChecked();
//创建SharedPreferences对象,默认以应用程序包名为文件名
// SharedPreferences preferences = getPreferences(MODE_PRIVATE);
SharedPreferences preferences = getSharedPreferences("info",this.MODE_PRIVATE);
//PreferenceManager实例化,默认以应用程序包名为文件名
//SharedPreferences preferences2 = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
//获取编辑类实例
SharedPreferences.Editor editor = preferences.edit();
//put数据
editor.putString("username",user_name);
editor.putString("password",password);
editor.putBoolean("isSavePas",isSavePas);
//提交事务
editor.commit();
break;
case R.id.read:
//声明并初始化SharedPreferences
SharedPreferences backPreferences = getSharedPreferences("info",this.MODE_PRIVATE);
//获取preference中的数据
String backName = backPreferences.getString("username","");
String backPassword = backPreferences.getString("password","");
Boolean backChecked = backPreferences.getBoolean("isSavePas",false);
//打印显示
Log.d("back",backName+"+"+backPassword+"+"+backChecked);
break;
default:
break;
}
}
}
(2) activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.sharepreferences.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="登陆"
android:layout_centerHorizontal="true"
android:id="@+id/title"
android:layout_alignParentTop="true" />
<RelativeLayout
android:id="@+id/edit_layout"
android:layout_marginTop="10dp"
android:layout_below="@+id/title"
android:layout_centerHorizontal="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:layout_alignBaseline="@+id/editText_name"
android:text="用户名:"
android:id="@+id/user_name"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="密码:"
android:layout_alignBaseline="@+id/editText_pas"
android:id="@+id/password"
android:layout_below="@+id/user_name"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:hint="请输入用户名"
android:ems="10"
android:id="@+id/editText_name"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/user_name"
android:layout_toEndOf="@+id/user_name" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:ems="10"
android:layout_alignLeft="@+id/editText_name"
android:layout_toRightOf="@+id/password"
android:id="@+id/editText_pas"
android:layout_below="@+id/editText_name"
android:layout_centerHorizontal="true" />
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="保存密码"
android:id="@+id/check"
android:layout_below="@+id/password"
android:checked="false" />
</RelativeLayout>
<RelativeLayout
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
android:layout_below="@+id/edit_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/relativeLayout">
</RelativeLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="登陆"
android:id="@+id/login"
android:layout_below="@+id/relativeLayout"
android:layout_toRightOf="@+id/title"
android:layout_alignRight="@+id/edit_layout"
android:layout_alignEnd="@+id/edit_layout" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="取消"
android:id="@+id/cancel"
android:layout_alignTop="@+id/relativeLayout"
android:layout_alignLeft="@+id/edit_layout"
android:layout_alignStart="@+id/edit_layout"
android:layout_toStartOf="@+id/title"
android:layout_toLeftOf="@+id/title" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="读取数据"
android:id="@+id/read"
android:layout_below="@+id/cancel"
android:layout_marginTop="50dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
(3) 效果截图
(4) Log打印(点击登陆,再点击读取数据)
09-03 13:21:30.503 3745-3745/com.example.sharepreferences D/back: elimy+456+true
(5) DDMS查看手机文件截图
4.File
4.1 概述
File文件存储,在android应用做,我们除了一些简单的数据和关系型数据需要通过Sharepreference和sqlite存储以外,通常
还有大数据型文件存储的需求,比如文本文件、图片文件、视频文件等,这时候File文件存储就比较符合需求,当然默认存储位置在手机
内存中,由于内存有限,大多数情况会有存储到sdcard的需求。
4.2 操作模式+存储位置
MODE_PRIVATE:文件仅应用程序自己能访问(默认)。
MODE_WORLD_READABLE:文件除了自己访问外还可以被其它应该程序读取(推荐使用Content provider)
MODE_WORLD_WRITEABLE:文件除了自己访问外还可以被其它应该程序读取和写入(推荐使用Content provider)
MODE_APPEND:在文件尾部追加
(2)默认存储位置:/data/data/<packageName>/files
4.3 手机内存+sdcard保存文件
(1)MainActivity.java
package com.example.file;
import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private EditText editTitle,editContent;
private Button savePhone,saveSD;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//初始化控件
editTitle = (EditText) findViewById(R.id.edit_title);
editContent = (EditText) findViewById(R.id.edit_content);
savePhone = (Button) findViewById(R.id.phone_save);
saveSD = (Button) findViewById(R.id.sdcard_save);
//注册监听
savePhone.setOnClickListener(this);
saveSD.setOnClickListener(this);
}
@Override
public void onClick(View v) {
//获取用户输入数据
String title = editTitle.getText().toString().trim();
String content = editContent.getText().toString().trim();
switch (v.getId()){
case R.id.phone_save:
if (title != null && content!= null){
try {
//通过文件输出流写入文件到手机内存
//声明并初始化FileOutputStream
//参数:
// name:文件名
// mode:操作模式
FileOutputStream fos =this.openFileOutput("test.txt", Context.MODE_APPEND);
//写入title
fos.write(title.getBytes());
//写入换行符
fos.write("\n".getBytes());
//写入coontent
fos.write(content.getBytes());
//关闭文件流
fos.close();
Toast.makeText(MainActivity.this,"保存到手机默认地址成功!",Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}else {
Toast.makeText(MainActivity.this,"请填写内容再保存!",Toast.LENGTH_SHORT).show();
}
break;
case R.id.sdcard_save:
if (title !=null && content!= null){
//判断sdcard是否挂载
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
//获取sdcard根目录
File sdcard_dir = Environment.getExternalStorageDirectory();
Log.d("sdcard_dir",sdcard_dir.toString());
//实例化saveFile
File saveFile = new File(sdcard_dir,"test.txt");
try {
//实例化指向目的文件位置的FileOutputStream
FileOutputStream fos=new FileOutputStream(saveFile,true);
//写入内容
fos.write(title.getBytes());
fos.write("\n".getBytes());
fos.write(content.getBytes());
//关闭文件流
fos.close();
Toast.makeText(MainActivity.this,"保存sdcard成功!",Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}else {
Toast.makeText(MainActivity.this,"请填写内容再保存!",Toast.LENGTH_SHORT).show();
}
break;
default:
break;
}
}
}
(2)布局activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.file.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="标题:"
android:id="@+id/title"
android:layout_alignBaseline="@+id/edit_title"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/edit_title"
android:hint="请输入标题"
android:layout_toRightOf="@+id/title"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<RelativeLayout
android:layout_marginTop="20dp"
android:layout_below="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/Content_Layout">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="内容:"
android:layout_alignBaseline="@+id/edit_content"
android:id="@+id/content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:inputType="textMultiLine"
android:ems="10"
android:hint="请输入内容"
android:id="@+id/edit_content"
android:layout_toRightOf="@+id/content"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</RelativeLayout>
<LinearLayout
android:layout_marginTop="80dp"
android:layout_below="@+id/Content_Layout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="保存到手机"
android:id="@+id/phone_save" />
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:text="保存到sdcard"
android:id="@+id/sdcard_save" />
</LinearLayout>
</RelativeLayout>
(3)访问sdcard需要注册权限
<!--写文件到sdcard权限-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--在sdcard创建和删除文件的权限-->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
(4))手机内存和sdcard保存文件效果图+验证截图
(1)布局效果图 (2)sdcard验证保存成功截图
(3) 手机内存查看验证截图
Content provider也被封为四大组件之一,是一种应用之间提供数据共享的机制,其实他的存储方式也是通过数据库或者其他存储
方式实现的,他只是提供一个供外界访问的接口,方便外界访问而已。之前我写过一篇关于Content provider的文章,这里就不做总结了,需要的伙伴可以看看,比较基础。
http://blog.csdn.net/qq_28057577/article/details/51454326
6.网络存储
所谓的网络存储也就是通过网络请求获取数据,后面在网络部分进行学习,在此暂时就不学习了。
推荐文章:http://www.cnblogs.com/hanyonglu/archive/2012/03/01/2374894.html