目录:
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
作者:qq_28057577 发表于2016/9/4 17:36:50 原文链接
阅读:103 评论:0 查看评论