1、概述

  Android提供了5种方式来让用户保存持久化应用程序数据。根据自己的需求来做选择,比如数据是否是应用程序私有的,是否能被其他程序访问,需要多少数据存储空间等,分别是: 
  
① 使用SharedPreferences存储数据 

② 文件存储数据

③  SQLite数据库存储数据

④ 使用ContentProvider存储数据

⑤ 网络存储数据 

Android提供了一种方式来暴露你的数据(甚至是私有数据)给其他应用程序 - ContentProvider。它是一个可选组件,可公开读写你应用程序数据。

2、SharedPreferences存储

  SharedPreference类提供了一个总体框架,使您可以保存和检索的任何基本数据类型( boolean, float, int, long, string)的持久键-值对(基于XML文件存储的“key-value”键值对数据)。

  通常用来存储程序的一些配置信息。其存储在“data/data/程序包名/shared_prefs目录下。

  xml 处理时Dalvik会通过自带底层的本地XML Parser解析,比如XMLpull方式,这样对于内存资源占用比较好。 

2.1  我们可以通过以下两种方法获取SharedPreferences对象(通过Context):

  1. ① getSharedPreferences (String name, int mode)

当我们有多个SharedPreferences的时候,根据第一个参数name获得相应的SharedPreferences对象。

  1. ② getPreferences (int mode)

 如果你的Activity中只需要一个SharedPreferences的时候使用。

这里的mode有四个选项:

  1. Context.MODE_PRIVATE

该SharedPreferences数据只能被本应用程序读、写。

  1. Context.MODE_WORLD_READABLE

该SharedPreferences数据能被其他应用程序读,但不能写。

  1. Context.MODE_WORLD_WRITEABLE

该SharedPreferences数据能被其他应用程序读和写。

  1. Context.MODE_MULTI_PROCESS

sdk2.3后添加的选项,当多个进程同时读写同一个SharedPreferences时它会检查文件是否修改。

2.2  向Shared Preferences中写入值
 
首先要通过 SharedPreferences.Editor获取到Editor对象;

然后通过Editor的putBoolean() 或 putString()等方法存入值;

最后调用Editor的commit()方法提交;

  1. //Use 0 or MODE_PRIVATE for the default operation
  2. SharedPreferences settings = getSharedPreferences("fanrunqi", 0);
  3. SharedPreferences.Editor editor = settings.edit();
  4. editor.putBoolean("isAmazing", true);
  5.  
  6. // 提交本次编辑
  7. editor.commit();

同时Edit还有两个常用的方法:

  1. editor.remove(String key) :下一次commit的时候会移除key对应的键值对
  2.  
  3. editor.clear():移除所有键值对

2.3  从Shared Preferences中读取值

  读取值使用 SharedPreference对象的getBoolean()或getString()等方法就行了(没Editor 啥子事)。

  1. SharedPreferences settings = getSharedPreferences("fanrunqi", 0);
  2. boolean isAmazing= settings.getBoolean("isAmazing",true);

2.4  Shared Preferences的优缺点

  可以看出来Preferences是很轻量级的应用,使用起来也很方便,简洁。但存储数据类型比较单一(只有基本数据类型),无法进行条件查询,只能在不复杂的存储需求下使用,比如保存配置信息等。

3、文件数据存储

3.1 使用内部存储

  当文件被保存在内部存储中时,默认情况下,文件是应用程序私有的,其他应用不能访问。当用户卸载应用程序时这些文件也跟着被删除。

  文件默认存储位置:/data/data/包名/files/文件名。

3.1.1 创建和写入一个内部存储的私有文件:

① 调用Context的openFileOutput()函数,填入文件名和操作模式,它会返回一个FileOutputStream对象。

② 通过FileOutputStream对象的write()函数写入数据。

③  FileOutputStream对象的close ()函数关闭流。

例如:

  1. String FILENAME = "a.txt";
  2. String string = "fanrunqi";
  3.  
  4. try {
  5. FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
  6. fos.write(string.getBytes());
  7. fos.close();
  8. } catch (Exception e) {
  9. e.printStackTrace();
  10. }

在 openFileOutput(String name, int mode)方法中

  • name参数: 用于指定文件名称,不能包含路径分隔符“/” ,如果文件不存在,Android 会自动创建它。

  • mode参数:用于指定操作模式,分为四种:

  1. Context.MODE_PRIVATE = 0

为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容。

  1. Context.MODE_APPEND = 32768

该模式会检查文件是否存在,存在就往文件追加内容,否则就创建新文件。

  1. Context.MODE_WORLD_READABLE = 1

表示当前文件可以被其他应用读取。

  1. MODE_WORLD_WRITEABLE

表示当前文件可以被其他应用写入。

3.1.2 读取一个内部存储的私有文件:

① 调用openFileInput( ),参数中填入文件名,会返回一个FileInputStream对象。

② 使用流对象的 read()方法读取字节

③ 调用流的close()方法关闭流

例如:

  1. String FILENAME = "a.txt";
  2. try {
  3. FileInputStream inStream = openFileInput(FILENAME);
  4. int len = 0;
  5. byte[] buf = new byte[1024];
  6. StringBuilder sb = new StringBuilder();
  7. while ((len = inStream.read(buf)) != -1) {
  8. sb.append(new String(buf, 0, len));
  9. }
  10. inStream.close();
  11. } catch (Exception e) {
  12. e.printStackTrace();
  13. }

其他一些经常用到的方法:

  • getFilesDir(): 得到内存储文件的绝对路径

  • getDir(): 在内存储空间中创建打开一个已经存在的目录

  • deleteFile(): 删除保存在内部存储的文件。  

  • fileList(): 返回当前由应用程序保存的文件的数组(内存储目录下的全部文件)。 

3.1.3 保存编译时的静态文件

  如果你想在应用编译时保存静态文件,应该把文件保存在项目的 res/raw/ 目录下,你可以通过 openRawResource()方法去打开它(传入参数R.raw.filename),这个方法返回一个 InputStream流对象你可以读取文件但是不能修改原始文件。

  1. InputStream is = this.getResources().openRawResource(R.raw.filename);

3.1.4 保存内存缓存文件

  有时候我们只想缓存一些数据而不是持久化保存,可以使用getCacheDir()去打开一个文件,文件的存储目录( /data/data/包名/cache )是一个应用专门来保存临时缓存文件的内存目录。

  当设备的内部存储空间比较低的时候,Android可能会删除这些缓存文件来恢复空间,但是你不应该依赖系统来回收,要自己维护这些缓存文件把它们的大小限制在一个合理的范围内,比如1MB.当你卸载应用的时候这些缓存文件也会被移除

3.2 使用外部存储(sdcard)

  因为内部存储容量限制,有时候需要存储数据比较大的时候需要用到外部存储,使用外部存储分为以下几个步骤:

3.2.1 添加外部存储访问限权

 
  首先,要在AndroidManifest.xml中加入访问SDCard的权限,如下:

  1. <!-- 在SDCard中创建与删除文件权限 -->
  2. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
  3.  
  4. <!-- 往SDCard写入数据权限 -->
  5. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

3.2.2 检测外部存储的可用性

  在使用外部存储时我们需要检测其状态,它可能被连接到计算机、丢失或者只读等。下面代码将说明如何检查状态:

  1. //获取外存储的状态
  2. String state = Environment.getExternalStorageState();
  3. if (Environment.MEDIA_MOUNTED.equals(state)) {
  4. // 可读可写
  5. mExternalStorageAvailable = mExternalStorageWriteable = true;
  6. } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
  7. // 可读
  8. } else {
  9. // 可能有很多其他的状态,但是我们只需要知道,不能读也不能写
  10. }

3.2.3 访问外部存储器中的文件

1、如果 API 版本大于或等于8,使用

  1. getExternalFilesDir (String type)

该方法打开一个外存储目录,此方法需要一个类型,指定你想要的子目录,如类型参数DIRECTORY_MUSIC和 DIRECTORY_RINGTONES(传null就是你应用程序的文件目录的根目录)。通过指定目录的类型,确保Android的媒体扫描仪将扫描分类系统中的文件(例如,铃声被确定为铃声)。如果用户卸载应用程序,这个目录及其所有内容将被删除。

例如:

  1. File file = new File(getExternalFilesDir(null), "fanrunqi.jpg");

2、如果API 版本小于 8 (7或者更低)

  1. getExternalStorageDirectory ()

通过该方法打开外存储的根目录,你应该在以下目录下写入你的应用数据,这样当卸载应用程序时该目录及其所有内容也将被删除

  1. /Android/data/<package_name>/files/

读写数据:

  1. if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
  2. File sdCardDir = Environment.getExternalStorageDirectory();//获取SDCard目录 "/sdcard"
  3.  
  4. File saveFile = new File(sdCardDir,"a.txt");
  5.  
  6. //写数据
  7. try {
  8. FileOutputStream fos= new FileOutputStream(saveFile);
  9. fos.write("fanrunqi".getBytes());
  10. fos.close();
  11. } catch (Exception e) {
  12. e.printStackTrace();
  13. }
  14.  
  15. //读数据
  16. try {
  17. FileInputStream fis= new FileInputStream(saveFile);
  18. int len =0;
  19. byte[] buf = new byte[1024];
  20. StringBuffer sb = new StringBuffer();
  21. while((len=fis.read(buf))!=-1){
  22. sb.append(new String(buf, 0, len));
  23. }
  24. fis.close();
  25. } catch (Exception e) {
  26. e.printStackTrace();
  27. }
  28. }

我们也可以在 /Android/data/package_name/cache/目录下做外部缓存。

4、 网络存储数据

HttpUrlConnection

HttpUrlConnection是Java.NET包中提供的API,我们知道Android SDK是基于Java的,所以当然优先考虑HttpUrlConnection这种最原始最基本的API,其实大多数开源的联网框架基本上也是基于JDK的HttpUrlConnection进行的封装罢了,掌握HttpUrlConnection需要以下几个步骤:

1、将访问的路径转换成URL。

  1. URL url = new URL(path);

2、通过URL获取连接

  1. HttpURLConnection conn = (HttpURLConnection) url.openConnection();

3、设置请求方式。

  1. conn.setRequestMethod(GET);

4、设置连接超时时间。

  1. conn.setConnectTimeout(5000);

5、设置请求头的信息。

  1. conn.setRequestProperty(User-Agent, Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0));

7、针对不同的响应码,做不同的操作(请求码200,表明请求成功,获取返回内容的输入流)

工具类:

  1. public class StreamTools {
  2. /**
  3. * 将输入流转换成字符串
  4. *
  5. * @param is
  6. * 从网络获取的输入流
  7. * @return
  8. */
  9. public static String streamToString(InputStream is) {
  10. try {
  11. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  12. byte[] buffer = new byte[1024];
  13. int len = 0;
  14. while ((len = is.read(buffer)) != -1) {
  15. baos.write(buffer, 0, len);
  16. }
  17. baos.close();
  18. is.close();
  19. byte[] byteArray = baos.toByteArray();
  20. return new String(byteArray);
  21. } catch (Exception e) {
  22. Log.e(tag, e.toString());
  23. return null;
  24. }
  25. }
  26. }

HttpUrlConnection发送GET请求

  1. public static String loginByGet(String username, String password) {
  2. String path = http://192.168.0.107:8080/WebTest/LoginServerlet?username= + username + &password= + password;
  3. try {
  4. URL url = new URL(path);
  5. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  6. conn.setConnectTimeout(5000);
  7. conn.setRequestMethod(GET);
  8. int code = conn.getResponseCode();
  9. if (code == 200) {
  10. InputStream is = conn.getInputStream(); // 字节流转换成字符串
  11. return StreamTools.streamToString(is);
  12. } else {
  13. return 网络访问失败;
  14. }
  15. } catch (Exception e) {
  16. e.printStackTrace();
  17. return 网络访问失败;
  18. }
  19. }

HttpUrlConnection发送POST请求

  1. public static String loginByPost(String username, String password) {
  2. String path = http://192.168.0.107:8080/WebTest/LoginServerlet;
  3. try {
  4. URL url = new URL(path);
  5. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  6. conn.setConnectTimeout(5000);
  7. conn.setRequestMethod(POST);
  8. conn.setRequestProperty(Content-Type, application/x-www-form-urlencoded);
  9. String data = username= + username + &password= + password;
  10. conn.setRequestProperty(Content-Length, data.length() + );
  11. // POST方式,其实就是浏览器把数据写给服务器
  12. conn.setDoOutput(true); // 设置可输出流
  13. OutputStream os = conn.getOutputStream(); // 获取输出流
  14. os.write(data.getBytes()); // 将数据写给服务器
  15. int code = conn.getResponseCode();
  16. if (code == 200) {
  17. InputStream is = conn.getInputStream();
  18. return StreamTools.streamToString(is);
  19. } else {
  20. return 网络访问失败;
  21. }
  22. } catch (Exception e) {
  23. e.printStackTrace();
  24. return 网络访问失败;
  25. }
  26. }

HttpClient

  HttpClient是开源组织Apache提供的Java请求网络框架,其最早是为了方便Java服务器开发而诞生的,是对JDK中的HttpUrlConnection各API进行了封装和简化,提高了性能并且降低了调用API的繁琐,Android因此也引进了这个联网框架,我们再不需要导入任何jar或者类库就可以直接使用,值得注意的是Android官方已经宣布不建议使用HttpClient了。

HttpClient发送GET请求

1、 创建HttpClient对象

2、创建HttpGet对象,指定请求地址(带参数)

3、使用HttpClient的execute(),方法执行HttpGet请求,得到HttpResponse对象

4、调用HttpResponse的getStatusLine().getStatusCode()方法得到响应码

5、调用的HttpResponse的getEntity().getContent()得到输入流,获取服务端写回的数据

  1. public static String loginByHttpClientGet(String username, String password) {
  2. String path = http://192.168.0.107:8080/WebTest/LoginServerlet?username=
  3. + username + &password= + password;
  4. HttpClient client = new DefaultHttpClient(); // 开启网络访问客户端
  5. HttpGet httpGet = new HttpGet(path); // 包装一个GET请求
  6. try {
  7. HttpResponse response = client.execute(httpGet); // 客户端执行请求
  8. int code = response.getStatusLine().getStatusCode(); // 获取响应码
  9. if (code == 200) {
  10. InputStream is = response.getEntity().getContent(); // 获取实体内容
  11. String result = StreamTools.streamToString(is); // 字节流转字符串
  12. return result;
  13. } else {
  14. return 网络访问失败;
  15. }
  16. } catch (Exception e) {
  17. e.printStackTrace();
  18. return 网络访问失败;
  19. }
  20. }

HttpClient发送POST请求

1,创建HttpClient对象

2,创建HttpPost对象,指定请求地址

3,创建List,用来装载参数

4,调用HttpPost对象的setEntity()方法,装入一个UrlEncodedFormEntity对象,携带之前封装好的参数

5,使用HttpClient的execute()方法执行HttpPost请求,得到HttpResponse对象

6, 调用HttpResponse的getStatusLine().getStatusCode()方法得到响应码

7, 调用的HttpResponse的getEntity().getContent()得到输入流,获取服务端写回的数据

  1. public static String loginByHttpClientPOST(String username, String password) {
  2. String path = http://192.168.0.107:8080/WebTest/LoginServerlet;
  3. try {
  4. HttpClient client = new DefaultHttpClient(); // 建立一个客户端
  5. HttpPost httpPost = new HttpPost(path); // 包装POST请求
  6. // 设置发送的实体参数
  7. List parameters = new ArrayList();
  8. parameters.add(new BasicNameValuePair(username, username));
  9. parameters.add(new BasicNameValuePair(password, password));
  10. httpPost.setEntity(new UrlEncodedFormEntity(parameters, UTF-8));
  11. HttpResponse response = client.execute(httpPost); // 执行POST请求
  12. int code = response.getStatusLine().getStatusCode();
  13. if (code == 200) {
  14. InputStream is = response.getEntity().getContent();
  15. String result = StreamTools.streamToString(is);
  16. return result;
  17. } else {
  18. return 网络访问失败;
  19. }
  20. } catch (Exception e) {
  21. e.printStackTrace();
  22. return 访问网络失败;
  23. }
  24. }

参考:

Android提供的其他网络访问框架

  HttpClient和HttpUrlConnection的两种网络访问方式编写网络代码,需要自己考虑很多,获取数据或许可以,但是如果要将手机本地数据上传至网络,根据不同的web端接口,需要组织不同的数据内容上传,给手机端造成了很大的工作量。
  
  目前有几种快捷的网络开发开源框架,给我们提供了非常大的便利。下面是这些项目Github地址,有文档和Api说明。
  
android-async-http 

http-request

okhttp

5、 SQLite数据库存储数据

Assets保存:用来存储一些只读数据,Assets是指那些在assets目录下的文件,这些文件在你将你的应用编译打包之前就要存在,并且可以在应用程序运行的时候被访问到。

  但有时候我们需要对保存的数据进行一些复杂的操作,或者数据量很大,超出了文本文件和Preference的性能能的范围,所以需要一些更加高效的方法来管理,从Android1.5开始,Android就自带SQLite数据库了。
  SQLite它是一个独立的,无需服务进程,支持事务处理,可以使用SQL语言的数据库。

SQLite的特性

1、 ACID事务

  1. ACID
  2.   指数据库事务正确执行的四个基本要素的缩写。包含:原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性(Durability)。
    一个支持事务(Transaction)的数据库,必需要具有这四种特性,否则在事务过程(Transaction processing)当中无法保证数据的正确性,交易过程极可能达不到交易方的要求。

2、 零配置 – 无需安装和管理配置  

3、储存在单一磁盘文件中的一个完整的数据库  

4、数据库文件可以在不同字节顺序的机器间自由的共享

5、支持数据库大小至2TB  

6、 足够小, 大致3万行C代码, 250K  

7、比一些流行的数据库在大部分普通数据库操作要快  

8、简单, 轻松的API  

9、 包含TCL绑定, 同时通过Wrapper支持其他语言的绑定  

  1. http://www.sqlite.org/tclsqlite.html

10、良好注释的源代码, 并且有着90%以上的测试覆盖率

11、 独立: 没有额外依赖

12、 Source完全的Open, 你可以用于任何用途, 包括出售它

13、支持多种开发语言,C,PHP,Perl,Java,ASP.NET,Python

Android 中使用 SQLite

  Activites 可以通过 Content Provider 或者 Service 访问一个数据库。

创建数据库

  Android 不自动提供数据库。在 Android 应用程序中使用 SQLite,必须自己创建数据库,然后创建表、索引,填充数据。Android 提供了 SQLiteOpenHelper 帮助你创建一个数据库,你只要继承 SQLiteOpenHelper 类根据开发应用程序的需要,封装创建和更新数据库使用的逻辑就行了。 

SQLiteOpenHelper 的子类,至少需要实现三个方法:

  1. public class DatabaseHelper extends SQLiteOpenHelper {
  2.  
  3. /**
  4. * @param context 上下文环境(例如,一个 Activity)
  5. * @param name 数据库名字
  6. * @param factory 一个可选的游标工厂(通常是 Null)
  7. * @param version 数据库模型版本的整数
  8. *
  9. * 会调用父类 SQLiteOpenHelper的构造函数
  10. */
  11. public DatabaseHelper(Context context, String name, CursorFactory factory, int version) {
  12. super(context, name, factory, version);
  13.  
  14. }
  15.  
  16. /**
  17. * 在数据库第一次创建的时候会调用这个方法
  18. *
  19. *根据需要对传入的SQLiteDatabase 对象填充表和初始化数据。
  20. */
  21. @Override
  22. public void onCreate(SQLiteDatabase db) {
  23.  
  24. }
  25.  
  26. /**
  27. * 当数据库需要修改的时候(两个数据库版本不同),Android系统会主动的调用这个方法。
  28. * 一般我们在这个方法里边删除数据库表,并建立新的数据库表.
  29. */
  30. @Override
  31. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  32. //三个参数,一个 SQLiteDatabase 对象,一个旧的版本号和一个新的版本号
  33.  
  34. }
  35.  
  36. @Override
  37. public void onOpen(SQLiteDatabase db) {
  38. // 每次成功打开数据库后首先被执行
  39. super.onOpen(db);
  40. }
  41. }

继承SQLiteOpenHelper之后就拥有了以下两个方法:

  • getReadableDatabase()  创建或者打开一个查询数据库

  • getWritableDatabase() 创建或者打开一个可写数据库

  1. DatabaseHelper database = new DatabaseHelper(context);//传入一个上下文参数
  2. SQLiteDatabase db = null;
  3. db = database.getWritableDatabase();

  上面这段代码会返回一个 SQLiteDatabase 类的实例,使用这个对象,你就可以查询或者修改数据库。 

SQLiteDatabase类为我们提供了很多种方法,而较常用的方法如下:

  1. (int) delete(String table,String whereClause,String[] whereArgs)

删除数据行

  1. (long) insert(String table,String nullColumnHack,ContentValues values)

添加数据行

  1. (int) update(String table, ContentValues values, String whereClause, String[] whereArgs)

更新数据行

  1. (void) execSQL(String sql)

执行一个SQL语句,可以是一个select或其他的sql语句

  1. (void) close()

关闭数据库

  1. (Cursor) query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)

查询指定的数据表返回一个带游标的数据集。

各参数说明:
table:表名称
colums:列名称数组
selection:条件子句,相当于where
selectionArgs:条件语句的参数数组
groupBy:分组
having:分组条件
orderBy:排序类
limit:分页查询的限制
Cursor:返回值,相当于结果集ResultSet

  1. (Cursor) rawQuery(String sql, String[] selectionArgs)

  运行一个预置的SQL语句,返回带游标的数据集(与上面的语句最大的区别就是防止SQL注入)

  当你完成了对数据库的操作(例如你的 Activity 已经关闭),需要调用 SQLiteDatabase 的 Close() 方法来释放掉数据库连接。

创建表和索引

  为了创建表和索引,需要调用 SQLiteDatabase 的 execSQL() 方法来执行 DDL 语句。如果没有异常,这个方法没有返回值。
  例如,你可以执行如下代码:

  1. db.execSQL("CREATE TABLE user(_id INTEGER PRIMARY KEY
  2. AUTOINCREMENT, username TEXT, password TEXT);");

这条语句会创建一个名为 user的表,表有一个列名为 _id,并且是主键,这列的值是会自动增长的整数。另外还有两列:username( 字符 ) 和 password( 字符 )。 SQLite        会自动为主键列创建索引。
通常情况下,第一次创建数据库时创建了表和索引。要 删除表和索引,需要使用 execSQL() 方法调用 DROP INDEX 和 DROP TABLE 语句。

添加数据 

  有两种方法可以给表添加数据。

①可以使用 execSQL() 方法执行 INSERT, UPDATE, DELETE 等语句来更新表的数据。execSQL() 方法适用于所有不返回结果的 SQL 语句。例如:

  1. String sql = "insert into user(username,password) values ('finch','123456');//插入操作的SQL语句
  2. db.execSQL(sql);//执行SQL语句

②使用 SQLiteDatabase 对象的 insert()。

  1. ContentValues cv = new ContentValues();
  2. cv.put("username","finch");//添加用户名
  3. cv.put("password","123456"); //添加密码
  4. db.insert("user",null,cv);//执行插入操作

更新数据(修改)

①使用SQLiteDatabase 对象的 update()方法。

  1. ContentValues cv = new ContentValues();
  2. cv.put("password","654321");//添加要更改的字段及内容
  3. String whereClause = "username=?";//修改条件
  4. String[] whereArgs = {"finch"};//修改条件的参数
  5. db.update("user",cv,whereClause,whereArgs);//执行修改

该方法有四个参数: 
  表名;
  列名和值的 ContentValues 对象; 
  可选的 WHERE 条件; 
  可选的填充 WHERE 语句的字符串,这些字符串会替换 WHERE 条件中的“?”标记,update() 根据条件,更新指定列的值. 

②使用execSQL方式的实现

  1. String sql = "update [user] set password = '654321' where username="finch";//修改的SQL语句
  2. db.execSQL(sql);//执行修改

删除数据

①使用SQLiteDatabase 对象的delete()方法。

  1. String whereClause = "username=?";//删除的条件
  2. String[] whereArgs = {"finch"};//删除的条件参数
  3. db.delete("user",whereClause,whereArgs);//执行删除

②使用execSQL方式的实现

  1. String sql = "delete from user where username="finch";//删除操作的SQL语句
  2. db.execSQL(sql);//执行删除操作

查询数据

①使用 rawQuery() 直接调用 SELECT 语句

  1. Cursor c = db.rawQuery("select * from user where username=?",new Stirng[]{"finch"});
  2.  
  3. if(cursor.moveToFirst()) {
  4. String password = c.getString(c.getColumnIndex("password"));
  5. }

返回值是一个 cursor 对象,这个对象的方法可以迭代查询结果。
如果查询是动态的,使用这个方法就会非常复杂。例如,当你需要查询的列在程序编译的时候不能确定,这时候使用 query() 方法会方便很多。

②通过query实现查询

  query() 方法用 SELECT 语句段构建查询。
  SELECT 语句内容作为 query() 方法的参数,比如:要查询的表名,要获取的字段名,WHERE 条件,包含可选的位置参数,去替代 WHERE 条件中位置参数的值,GROUP BY 条件,HAVING 条件。
  除了表名,其他参数可以是 null。所以代码可写成:

  1. Cursor c = db.query("user",null,null,null,null,null,null);//查询并获得游标
  2. if(c.moveToFirst()){//判断游标是否为空
  3. for(int i=0;i<c.getCount();i++){ 
  4. c.move(i);//移动到指定记录
  5. String username = c.getString(c.getColumnIndex("username");
  6. String password = c.getString(c.getColumnIndex("password"));
  7. }
  8. }

使用游标

  不管你如何执行查询,都会返回一个 Cursor,这是 Android 的 SQLite 数据库游标,使用游标,你可以:  

  • 通过使用 getCount() 方法得到结果集中有多少记录; 

  • 通过 moveToFirst(), moveToNext(), 和 isAfterLast() 方法遍历所有记录;

  • 通过 getColumnNames() 得到字段名;

  • 通过 getColumnIndex() 转换成字段号;

  • 通过 getString(),getInt() 等方法得到给定字段当前记录的值;

  • 通过 requery() 方法重新执行查询得到游标;

  • 通过 close() 方法释放游标资源;

例如,下面代码遍历 user表:

  1. Cursor result=db.rawQuery("SELECT _id, username, password FROM user");
  2. result.moveToFirst();
  3. while (!result.isAfterLast()) {
  4. int id=result.getInt(0);
  5. String name=result.getString(1);
  6. String password =result.getString(2);
  7. // do something useful with these
  8. result.moveToNext();
  9. }
  10. result.close();

Android 数据存储五种方式的更多相关文章

  1. Android数据存储五种方式总结

    本文介绍Android平台进行数据存储的五大方式,分别如下: 1 使用SharedPreferences存储数据     2 文件存储数据       3 SQLite数据库存储数据 4 使用Cont ...

  2. Android数据存储五种方式

    1 使用SharedPreferences存储数据:常用于做本地缓存 2 文件存储数据:(1)data/data/<package name>/files目录内   (2)SDCard内 ...

  3. Android(java)学习笔记191:Android数据存储5种方式总结

    1.使用文件(File)存储 存储一般的数据 2.使用sharedperference(xml) 存储设置信息.配置信息.密码 3.数据库Sqlite 开源的,嵌入式的数据库,轻量级 4.使用Cont ...

  4. Android(java)学习笔记134:Android数据存储5种方式总结

    1.使用文件(File)存储 存储一般的数据 2.使用sharedperference(xml) 存储设置信息.配置信息.密码 3.数据库Sqlite 开源的,嵌入式的数据库,轻量级 4.使用Cont ...

  5. MSSQLSERVER数据库- SQL删除重复数据的五种方式

    删除重复的数据,在平时的工作中还是会和碰到的,感觉挺有用,从网上摘录的,记在这里,以备需要时查阅 --方法一,IN方式,适合2000/2005/2008,6728 毫秒 DELETE [student ...

  6. jnhs-SpringMVC的controller向jsp传递数据的五种方式

    参考此文http://blog.sina.com.cn/s/blog_6d3c1ec601014h1h.html 1 使用ModelAndVoew 引入:org.springframework.web ...

  7. Android系统的五种数据存储形式(一)

    Android系统有五种数据存储形式,分别是文件存储.SP存储.数据库存储.contentprovider 内容提供者.网络存储.其中,前四个是本地存储.存储的类型包括简单文本.窗口状态存储.音频视频 ...

  8. android 数据存储的几种方式

    总体的来讲,数据存储方式有三种:一个是文件,一个是数据库,另一个则是网络.其中文件和数据库可能用的稍多一些,文件用起来较为方便,程序可以自己定义格式:数据库用起稍烦锁一些,但它有它的优点,比如在海量数 ...

  9. Android数据的四种存储方式SharedPreferences、SQLite、Content Provider和File (三) —— SharePreferences

    除了SQLite数据库外,SharedPreferences也是一种轻型的数据存储方式,它的本质是基于XML文件存储key-value键值对数据,通常用来存储一些简单的配置信息.其存储位置在/data ...

随机推荐

  1. Dev用于界面按选中列进行分组统计数据源(实用技巧)

    如果有用U8的可以明白这个功能就是模仿他的统计功能.我不过是把他造成通用的与适应于DEV的. (效率为6000条数据分组统计时间为3秒左右分组列过多5秒.1000条以下0.几秒,500条下0.00几秒 ...

  2. 【转】PowerShell入门(十):使用配置文件

    转至:http://www.cnblogs.com/ceachy/archive/2013/03/01/PowerShell_Profile.html 在命令行中定义别名.变量和函数,只是将它们添加在 ...

  3. Steve Loughran:Why not raid 0,its about time and snowflakes!!!

    与RAID-0阵列的同组管理相比,Hadoop更喜欢一组单独磁盘.在Hadoop集群中,读取速度是最能体现性能的重要指标.在Steve Loughran文章中,尤其强调了这一点,他还指出,由于驱动器速 ...

  4. Qt qml pageview 左右滑动分页组件

    [先看效果] [下载]http://download.csdn.net/detail/surfsky/8516949 [调用] 分页视图 左右分页滑动列表组件 示例 PageView{ id: pv ...

  5. redis.conf配置详细翻译解析

    # redis 配置文件示例 # 当你需要为某个配置项指定内存大小的时候,必须要带上单位, # 通常的格式就是 1k 5gb 4m 等酱紫: # # 1k => 1000 bytes # 1kb ...

  6. python 列表排序

    转自http://www.iplaypython.com/jinjie/jj114.html reverse()方法 将列表中元素反转排序,比如下面这样>>> x = [1,5,2, ...

  7. js使用模板快速填充数据

    1.html <!DOCTYPE html> <html> <head> <title>模板标签</title> </head> ...

  8. ubuntu下安装JDK并搭建activeMQ

    1.安装JDK,网上有人说activeMQ支持持JDK1.7及以上版本,未实际测试,保险起见我这里直接安装JDK1.7. #apt-get install openjdk--jdk 2.设置环境变量 ...

  9. asp.net timer viewstate

    using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...

  10. Java SE 基础:标识(zhì)符

    Java SE 基础:标识(zhì)符 一.标识符定义 标识符,就是给类.接口.方法.变量等起名字时的字符序列 二.组成规则与注意事项 1.组成规则 英文大小写字母 数组 $ 和 _ 2.注意事项 不 ...