热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

Android系统的五种数据存储形式实例(一)

Android系统有五种数据存储形式,分别是文件存储、SP存储、数据库存储、contentprovider内容提供者、网络存储。本篇文章详解的介绍了每种数据存储的用法,有兴趣的可以了解一下。

Android系统有五种数据存储形式,分别是文件存储、SP存储、数据库存储、contentprovider 内容提供者、网络存储。其中,前四个是本地存储。存储的类型包括简单文本、窗口状态存储、音频视频数据、XML注册文件的各种数据。各种存储形式的特点不尽相同,因此对于不同的数据类型有着固定的存储形式,本文为演示方便给出的案例基本相同,都是是采用账号登录来演示数据存储,保存账号和密码信息,下次登录时记住账号和密码。重在说明各种存储形式的原理。

文件存储:

以I/O流的形式把数据存入手机内存或SD卡,可以存储大数据,如音乐、图片或视频等。对于手机内存来说系统会根据每个应用的包名创建一个/data/data/包名/的文件夹,访问自己包名下的目录是不需要权限的,并且 Android 已经提供了非常简便的 API 可以直接去访问该文件夹。访问时可以用getFilesDir()和getCacheDir(),两个的区别是系统会自动清理后者中的内容。

SD卡中的文件通常位于mnt/sdcard目录下,不同生产商生产的手机这个路径可能不同。操作sd卡的时通常要判断下sd卡是否可用以及剩余空间是否足够,因为部分手机的SD卡可卸载,SD卡处于非挂载状态时,无法进行读写操作。另外一点,对SD卡的读取和写入操作均需要相应的权限,否则无法完成。获取SD卡路径的方法是Environment.getExternalStorageDirectory(),其余操作与文件存储基本类似。

文件存储位置:

SD卡存储路径:

数据存储在手机内存的实现方法:

package com.example.qqload;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;

import com.example.qqload_sp.R;

import android.os.Bundle;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.text.TextUtils;
import android.view.Menu;
import android.view.TextureView;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {
 private EditText et_qq;
 private EditText et_password;
 private CheckBox cb_remenber;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  et_qq = (EditText) findViewById(R.id.et_qq);
  et_password = (EditText) findViewById(R.id.et_password);
  cb_remenber = (CheckBox) findViewById(R.id.cb_remenber);
  File file = new File(getFilesDir(), "info.txt");
//  File file = new File(getCacheDir(), "info.txt"); 缓存中存放数据
  if (file.exists() && file.length() > 0) {
   try {
    FileInputStream fis = new FileInputStream(file);
    BufferedReader br = new BufferedReader(new InputStreamReader(
      fis));
    String line = br.readLine();
    String qq = line.split("##")[0];
    String password = line.split("##")[1];
    et_qq.setText(qq);
    et_password.setText(password);
    fis.close();
   } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
 }

 public void login(View view) {
  String qq = et_qq.getText().toString().trim();
  String password = et_password.getText().toString().trim();
  if (TextUtils.isEmpty(qq) || TextUtils.isEmpty(password)) {
   Toast.makeText(this, "密码或者用户名不能为空", 0).show();
   return;
  }
  if (cb_remenber.isChecked()) {
   File file = new File(getFilesDir(), "info.txt");
   try {
    FileOutputStream fos = new FileOutputStream(file);
    fos.write((qq + "##" + password).getBytes());
    fos.close();
    Toast.makeText(MainActivity.this, "保存成功", 0).show();
   } catch (Exception e) {
    Toast.makeText(MainActivity.this, "保存失败", 0).show();
    e.printStackTrace();
   }
  }
 }
} 

数据存储在SD卡中的实现方法:     

package com.example.qqload;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.text.Format;

import com.example.qqload_sp.R;

import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.text.TextUtils;
import android.text.format.Formatter;
import android.view.Menu;
import android.view.TextureView;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {
 private EditText et_qq;
 private EditText et_password;
 private CheckBox cb_remenber;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  et_qq = (EditText) findViewById(R.id.et_qq);
  et_password = (EditText) findViewById(R.id.et_password);
  cb_remenber = (CheckBox) findViewById(R.id.cb_remenber);
  File file = new File(Environment.getExternalStorageDirectory(), "info.txt");
  if (file.exists() && file.length() > 0) {
   try {
    FileInputStream fis = new FileInputStream(file);
    BufferedReader br = new BufferedReader(new InputStreamReader(
      fis));
    String line = br.readLine();
    String qq = line.split("##")[0];
    String password = line.split("##")[1];
    et_qq.setText(qq);
    et_password.setText(password);
    fis.close();
   } catch (Exception e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }
 }

 public void login(View view) {
  String qq = et_qq.getText().toString().trim();
  String password = et_password.getText().toString().trim();
  if (TextUtils.isEmpty(qq) || TextUtils.isEmpty(password)) {
   Toast.makeText(this, "密码或者用户名不能为空", 0).show();
   return;
  }
  if (cb_remenber.isChecked()) {
   File file = new File(Environment.getExternalStorageDirectory(), "info.txt");
   //判断SD卡是否挂载
   if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
    Toast.makeText(MainActivity.this, "SD卡不可用", 0).show();
    return;
   }
   //判断SD卡大小是否充足
   long size = Environment.getExternalStorageDirectory().getFreeSpace();
   String info = Formatter.formatFileSize(this, size);
   //此处存储数据较小就不进行判断
   Toast.makeText(this, "可用空间" + info, 0).show();
   
   try {
    FileOutputStream fos = new FileOutputStream(file);
    fos.write((qq + "##" + password).getBytes());
    fos.close();
    Toast.makeText(MainActivity.this, "保存成功", 0).show();
   } catch (Exception e) {
    Toast.makeText(MainActivity.this, "保存失败", 0).show();
    e.printStackTrace();
   }
  }
 }
}

SP存储:

SP存储本质上是一个XML文件,以键值对的形式存入手机内存中。常用于存储简单的参数设置,如登陆账号密码的存储,窗口功能状态的存储等,该存储文件位于:data/data/包名/shared_prefs文件夹中。使用的时候,首先需要通过context.getSharedPrefrences(String name,int mode)获取SharedPrefrences的实例对象,存储数据时,用SharedPrefrences的实例对象得到SharedPrefrences文件的编辑器,在编辑器中用putXxx()添加数据,之后务必用commit提交数据,否则无法获取数据。取数据时,直接用getXxx()方法。

sp存储自动生成xml文件,其的路径如下:

sp存储的实现方法:

package com.example.qqload;
import com.example.qqload_sp.R;

import android.os.Bundle;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.text.TextUtils;
import android.view.Menu;
import android.view.TextureView;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends Activity {
 private EditText et_qq;
 private EditText et_password;
 private CheckBox cb_remenber;
  private SharedPreferences sp;
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  et_qq = (EditText) findViewById(R.id.et_qq);
  et_password = (EditText) findViewById(R.id.et_password);
  cb_remenber = (CheckBox) findViewById(R.id.cb_remenber);
  sp = this.getSharedPreferences("config", 0);
  String qq = sp.getString("qq","");
  String password = sp.getString("password","");
  et_qq.setText(qq);
  et_password.setText(password);
 }
 public void login(View view){
  String qq = et_qq.getText().toString().trim();
  String password = et_password.getText().toString().trim();
  if(TextUtils.isEmpty(qq)||TextUtils.isEmpty(password)){
   Toast.makeText(this,"密码或者用户名不能为空",0).show();
   return;
  }
  if(cb_remenber.isChecked()){
   Editor edit = sp.edit();
   edit.putString("qq",qq);
   edit.putString("password",password);
   edit.commit();
  }
 }
}

 数据库存储:

数据库所有信息都存储在单一文件内,占用内存小,并且支持基本SQL语法,是项目中经常被采用的一种数据存储方式,通常用于存储用户信息等,例如在手机上做一个学生信息管理系统。SQLite 是一款内置到移动设备上的轻量型的数据库,SQLiteOpenHelper 是Android 提供的一个抽象工具类,负责管理数据库的创建、升级工作。数据库的路径为:/data/data/应用包名/databases/数据库。如果想创建数据库,就需要自定义一个类继承SQLiteOpenHelper,然后覆写其中的抽象方法,指定数据库名、版本号。在onCreate() 方法中通过执行sql 语句实现表的创建。如果只是创建出来该类并不会真正的去创建数据库,而是需要通过执行helper.getWritableDatabase()或者hepler.getReadableDatabase()。另外想要对创建的数据库进行增删改查的操作可以单独定义一个类实现。增删改查操作有两种方式,一是直接执行sql语句,另一个是Android自身的API实现。用数据库实现账号登录显得有些大材小用,为演示数据库的原理本文给出的案例是用数据库记录多个用户的账号和密码信息,并把最后一个账号信息回显在界面。但实际应用中很少这样做。

从手机文件中导出数据库文件并不可以直接打开,因此可以用可视化工具和sqlite3操作工具进行查看。这里介绍sqlite3工具的使用。具体需要的步骤如下:

1. 执行adb shell命令进入Linuxne内核;

2. 使用cd进入数据库所在的路径 cd: /data/data/应用包名/databases;

3. 进入数据库模式: sqlite3 数据库名.db;

4. 执行SQL语句       

Sqlite3操作演示:

数据库存储路径:

数据库实现方法,先创建一个类继承SqliteOpenHelper,在类中创建数据库和表:

package com.example.qqload.db;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class UserDBOpenhelper extends SQLiteOpenHelper {
 public UserDBOpenhelper(Context context) {
  super(context, "user.db", null, 1);
  // TODO Auto-generated constructor stub
 }
 @Override
 public void onCreate(SQLiteDatabase arg0) {
  arg0.execSQL("create table user (_id integer primary key autoincrement,name vachar(20),password varchar(20))");
 }
 @Override
 public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
  // TODO Auto-generated method stub
 }
}

创建一个工具类实现对数据库的操作:

package com.example.qqload.db.dao;

import java.util.ArrayList;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.example.qqload.db.UserDBOpenhelper;

public class UserDao {
 private UserDBOpenhelper helper; 
 public UserDao(Context context){
  helper = new UserDBOpenhelper(context);
 }
 public long add(String name,String password){
  SQLiteDatabase db = helper.getWritableDatabase();
  //用SQL语句实现增加数据的功能
  //db.execSQL("insert into user (name,passeord) values (?,?)", new Object[]{name,password});
  //android自身API实现修改功能可以有返回值
  ContentValues values =new ContentValues();
  values.put("name", name);
  values.put("password", password);
  long result = db.insert("user", null, values); //带返回值,表示添加在哪一行
  db.close();
  return result;
 }
 public List findAll(){
  List list =new ArrayList();
  SQLiteDatabase db = helper.getReadableDatabase();
  //Cursor cursor = db.rawQuery("select name, password from user", null);
  Cursor cursor = db.query("user", new String[]{"name","password"}, null, null, null, null, null);
  while(cursor.moveToNext()){
   String name = cursor.getString(0);
   String password = cursor.getString(1);
   user us = new user();
   us.setName(name);
   us.setPassword(password);
   list.add(us);
  }
  cursor.close();
  db.close();
  return list;
 }
}

在主方法中实现账号登录和记录

package com.example.qqload;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.util.List;

import com.example.qqload.db.dao.UserDao;
import com.example.qqload.db.dao.user;
import com.example.qqload.R;

import android.os.Bundle;
import android.app.Activity;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.text.TextUtils;
import android.view.Menu;
import android.view.TextureView;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {
 private EditText et_qq;
 private EditText et_password;
 private CheckBox cb_remenber;
 private UserDao dao;
 private List list;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  et_qq = (EditText) findViewById(R.id.et_qq);
  et_password = (EditText) findViewById(R.id.et_password);
  cb_remenber = (CheckBox) findViewById(R.id.cb_remenber);
  user u = new user();
  dao = new UserDao(MainActivity.this);
  list = dao.findAll();
  if (list.size() == 0) {
   et_qq.setText("");
   et_password.setText("");
  } else {
   System.out.println("大小:" + list.size());
   for (int i = 0; i 

用数据库实现账号登录案例的目录结构如下所示:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • Android系统移植与调试之如何修改Android设备状态条上音量加减键在横竖屏切换的时候的显示于隐藏
    本文介绍了如何修改Android设备状态条上音量加减键在横竖屏切换时的显示与隐藏。通过修改系统文件system_bar.xml实现了该功能,并分享了解决思路和经验。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • 本文介绍了Android 7的学习笔记总结,包括最新的移动架构视频、大厂安卓面试真题和项目实战源码讲义。同时还分享了开源的完整内容,并提醒读者在使用FileProvider适配时要注意不同模块的AndroidManfiest.xml中配置的xml文件名必须不同,否则会出现问题。 ... [详细]
  • Android开发实现的计时器功能示例
    本文分享了Android开发实现的计时器功能示例,包括效果图、布局和按钮的使用。通过使用Chronometer控件,可以实现计时器功能。该示例适用于Android平台,供开发者参考。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 本文是关于自学Android的笔记,包括查看类的源码的方法,活动注册的必要性以及布局练习的重要性。通过学习本文,读者可以了解到在自学Android过程中的一些关键点和注意事项。 ... [详细]
  • Vagrant虚拟化工具的安装和使用教程
    本文介绍了Vagrant虚拟化工具的安装和使用教程。首先介绍了安装virtualBox和Vagrant的步骤。然后详细说明了Vagrant的安装和使用方法,包括如何检查安装是否成功。最后介绍了下载虚拟机镜像的步骤,以及Vagrant镜像网站的相关信息。 ... [详细]
author-avatar
散場偂爱的擁菢_257
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有