一、ContentProvider保存数据介绍

一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据完全暴露出去,而且ContentProvider是以类似数据库中表的方式将数据暴露的。那么外界获取其提供的数据,也就应该与从数据库中获取数据的操作基本一样,只不过是采用URL来表示外界需要访问的“数据库”。

ContentProvider提供了一种多应用间数据共享的方式。

ContentProvider是个实现了一组用于提供其他应用程序存取数据的标准方法的类。应用程序可以在ContentProvider中执行如下操作:查询数据、修改数据、添加数据、删除数据。

标准的ContentProvider:Android提供了一些已经在系统中实现的标准ContentProvider,比如联系人信息,图片库等等,可以用这些ContentProvider来访问设备上存储的联系人信息、图片等等。

在ContentProvider中使用的查询字符串有别于标准的SQL查询,很多诸如select、add、delete、modify等操作都使用一种特殊的URL进行,这种URL由3部分组成,“content://”,代表数据的路径和一个可选的表示数据的ID。

content://media/internal/images 这个URL将返回设备上存储的所有图片

content://contacts/people/ 这个URL将返回设备上的所有联系人信息

content://contacts/people/45 这个URL返回单个结果(联系人信息中ID为45的联系人记录)

如果想要存储字节型数据,比如位图文件等,那保存该数据的数据列其实是一个表示实际保存保存文件的URL字符串,客户端通过它来读取对应的文件数据,处理这种数据类型的ContentProvider需要实现一个名为_data的字段,_data字段列出了该文件在Android文件系统上的精确路径。这个字段不仅是供客户端使用,而且也可以供ContentResolver使用。客户端可以调用ContentResolver.openOutputStream()方法来处理该URL指向的文件资源,如果是ContentResolver本身的话,由于其持有的权限比客户端要高,所以它能直接访问该数据文件。

二、使用方法

大多数ContentProvider使用Android文件系统或者SQLite数据库来保持数据,但是也可以以任何方式来存储。本例用SQLite数据库来保持数据。

1.创建一个接口,定义了一个名为CONTENT_URL,并且是public static final的Uri类型的类变量,必须为其指定一个唯一的字符串值,最好的方案是类的全称,和数据列的名称。

  1. public interface IProivderMetaData {
  2.  
  3. public static final String AUTHORITY = "com.zhangmiao.datastoragedemo";
  4.  
  5. public static final String DB_NAME = "book.db";
  6.  
  7. public static final int VERSION = 1;
  8.  
  9. public interface BookTableMetaData extends BaseColumns {
  10. public static final String TABLE_NAME = "book";
  11. public static final Uri CONTENT_URI = Uri.parse("content://"
  12. + AUTHORITY + "/" + TABLE_NAME);
  13.  
  14. public static final String BOOK_ID = "_id";
  15. public static final String BOOK_NAME = "name";
  16. public static final String BOOK_PUBLISHER = "publisher";
  17.  
  18. public static final String SORT_ORDER = "_id desc";
  19. public static final String CONTENT_LIST = "vnd.android.cursor.dir/vnd.bookprovider.book";
  20. public static final String CONTENT_ITEM = "vnd.android.cursor.item/vnd.bookprovider.book";
  21. }
  22. }

2.实现SQLiteOpenHelper

  1. public class ContentProviderDBHelper extends SQLiteOpenHelper implements IProivderMetaData {
  2.  
  3. private static final String TAG = "ContentProviderDBHelper";
  4.  
  5. public ContentProviderDBHelper(Context context) {
  6. super(context, DB_NAME, null, VERSION);
  7. }
  8.  
  9. @Override
  10. public void onCreate(SQLiteDatabase db) {
  11. ...
  12. }
  13.  
  14. @Override
  15. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  16. ...
  17. }
  18. }

3.创建一个继承了ContentProvider父类的类

  1. public class ContentProviderDBHelper extends SQLiteOpenHelper implements IProivderMetaData {
  2. public ContentProviderDBHelper(Context context) {
  3. super(context, DB_NAME, null, VERSION);
  4. }
  5.  
  6. @Override
  7. public void onCreate(SQLiteDatabase db) {
  8. ...
  9. }
  10.  
  11. @Override
  12. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  13. ...
  14. }
  15. }

4.在AndroidManifest.xml中使用标签来设置调用ContentProvider。

  1. <provider
  2. android:authorities="com.zhangmiao.datastoragedemo"
  3. android:name=".BookContentProvider"/>

5.增加数据

  1. mContentResolver = getContentResolver();
  2. String[] bookNames = new String[]{"Chinese", "Math", "English", "Sports"};
  3. String[] bookPublishers = new String[]{"XinHua", "GongXin", "DianZi", "YouDian"};
  4. for (int i = 0; i < bookNames.length; i++) {
  5. ContentValues values = new ContentValues();
  6. values.put(IProivderMetaData.BookTableMetaData.BOOK_NAME, bookNames[i]);
  7. values.put(IProivderMetaData.BookTableMetaData.BOOK_PUBLISHER, bookPublishers[i]);
  8. mContentResolver.insert(IProivderMetaData.BookTableMetaData.CONTENT_URI, values);
  9. }

6.删除数据

  1. String bookId = "1";
  2. if (!"".equals(bookId)) {
  3. ContentValues values1 = new ContentValues();
  4. values1.put(IProivderMetaData.BookTableMetaData.BOOK_ID,bookId);
  5. mContentResolver.delete(Uri.withAppendedPath(
    IProivderMetaData.BookTableMetaData.CONTENT_URI,
  6. bookId),
               "_id = ?",
  7. new String[]{bookId}
    );
  8. } else {
  9. mContentResolver.delete(
  10. IProivderMetaData.BookTableMetaData.CONTENT_URI,
  11. null,
  12. null
    );
  13. }

7.查询数据

  1. Cursor cursor = mContentResolver.query(IProivderMetaData.BookTableMetaData.CONTENT_URI,
    null, null, null, null);
  2. String text = "";
  3. if (cursor != null) {
  4. while (cursor.moveToNext()) {
  5. String bookIdText =
    cursor.getString(cursor.getColumnIndex(IProivderMetaData.BookTableMetaData.BOOK_ID));
  6. String bookNameText =
    cursor.getString(cursor.getColumnIndex(IProivderMetaData.BookTableMetaData.BOOK_NAME));
  7. String bookPublisherText =
  8.  
  9. cursor.getString(cursor.getColumnIndex(IProivderMetaData.BookTableMetaData.BOOK_PUBLISHER));
  10. text += "id = " + bookIdText + ",name = " + bookNameText +
    ",publisher = " + bookPublisherText + "\n";
  11. }
  12. cursor.close();
  13. mTableInfo.setText(text);
  14. }

8.更新数据

  1. String bookId1 = "2";
  2. String bookName = "Art";
  3. String bookPublisher = "TieDao";
  4. ContentValues values2 = new ContentValues();
  5. values2.put(IProivderMetaData.BookTableMetaData.BOOK_NAME,bookName);
  6. values2.put(IProivderMetaData.BookTableMetaData.BOOK_PUBLISHER,bookPublisher);
  7. if ("".equals(bookId1)) {
  8. mContentResolver.update(IProivderMetaData.BookTableMetaData.CONTENT_URI,
  9. values2, null, null);
  10. } else {
  11. mContentResolver.update(Uri.withAppendedPath(IProivderMetaData.BookTableMetaData.CONTENT_URI, bookId1),
  12. values2, "_id = ? ", new String[]{bookId1}
    );
  13. }

三、小案例

1.添加strings.xml文件

  1. <string name="content_provider">ContentProvider</string>
  2. <string name="add_data">增加数据</string>
  3. <string name="delete_data">删除数据</string>
  4. <string name="update_data">更改数据</string>
  5. <string name="query_data">查询数据</string>

2.修改activity_main.xml文件

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:fitsSystemWindows="true"
  7. tools:context="com.zhangmiao.datastoragedemo.MainActivity">
  8.  
  9. <LinearLayout
  10. android:layout_width="match_parent"
  11. android:layout_height="match_parent"
  12. android:orientation="vertical">
  13.  
  14. <TextView
  15. android:layout_width="wrap_content"
  16. android:layout_height="wrap_content"
  17. android:layout_gravity="center_horizontal"
  18. android:text="@string/content_provider" />
  19.  
  20. <LinearLayout
  21. android:layout_width="match_parent"
  22. android:layout_height="wrap_content"
  23. android:layout_marginBottom="@dimen/fab_margin"
  24. android:layout_marginTop="@dimen/fab_margin"
  25. android:orientation="horizontal">
  26.  
  27. <Button
  28. android:id="@+id/provider_add"
  29. android:layout_width="0dp"
  30. android:layout_height="wrap_content"
  31. android:layout_weight="1"
  32. android:text="@string/add_data" />
  33.  
  34. <Button
  35. android:id="@+id/provider_delete"
  36. android:layout_width="0dp"
  37. android:layout_height="wrap_content"
  38. android:layout_weight="1"
  39. android:text="@string/delete_data" />
  40.  
  41. <Button
  42. android:id="@+id/provider_update"
  43. android:layout_width="0dp"
  44. android:layout_height="wrap_content"
  45. android:layout_weight="1"
  46. android:text="@string/update_data" />
  47.  
  48. <Button
  49. android:id="@+id/provider_query"
  50. android:layout_width="0dp"
  51. android:layout_height="wrap_content"
  52. android:layout_weight="1"
  53. android:text="@string/query_data" />
  54.  
  55. </LinearLayout>
  56.  
  57. <TextView
  58. android:id="@+id/table_info"
  59. android:layout_width="match_parent"
  60. android:layout_height="wrap_content"
  61. android:text="@string/app_name" />
  62. </LinearLayout>
  63. </android.support.design.widget.CoordinatorLayout>

3.添加IProviderMetaData接口

  1. package com.zhangmiao.datastoragedemo;
  2.  
  3. import android.net.Uri;
  4. import android.provider.BaseColumns;
  5.  
  6. /**
  7. * Created by zhangmiao on 2016/12/20.
  8. */
  9. public interface IProviderMetaData {
  10.  
  11. public static final String AUTHORITY = "com.zhangmiao.datastoragedemo";
  12.  
  13. public static final String DB_NAME = "book.db";
  14.  
  15. public static final int VERSION = 1;
  16.  
  17. public interface BookTableMetaData extends BaseColumns {
  18. public static final String TABLE_NAME = "book";
  19. public static final Uri CONTENT_URI = Uri.parse("content://"
  20. + AUTHORITY + "/" + TABLE_NAME);
  21.  
  22. public static final String BOOK_ID = "_id";
  23. public static final String BOOK_NAME = "name";
  24. public static final String BOOK_PUBLISHER = "publisher";
  25.  
  26. public static final String SORT_ORDER = "_id desc";
  27. public static final String CONTENT_LIST = "vnd.android.cursor.dir/vnd.bookprovider.book";
  28. public static final String CONTENT_ITEM = "vnd.android.cursor.item/vnd.bookprovider.book";
  29. }
  30. }

4.添加ContentProviderDBHelper类

  1. package com.zhangmiao.datastoragedemo;
  2.  
  3. import android.content.Context;
  4. import android.database.sqlite.SQLiteDatabase;
  5. import android.database.sqlite.SQLiteOpenHelper;
  6. import android.util.Log;
  7.  
  8. /**
  9. * Created by zhangmiao on 2016/12/20.
  10. */
  11. public class ContentProviderDBHelper extends SQLiteOpenHelper implements IProviderMetaData {
  12.  
  13. private static final String TAG = "ContentProviderDBHelper";
  14.  
  15. public ContentProviderDBHelper(Context context) {
  16. super(context, DB_NAME, null, VERSION);
  17. }
  18.  
  19. @Override
  20. public void onCreate(SQLiteDatabase db) {
  21. String TABLESQL = "CREATE TABLE IF NOT EXISTS "
  22. + BookTableMetaData.TABLE_NAME + " ("
  23. + BookTableMetaData.BOOK_ID + " INTEGER PRIMARY KEY AUTOINCREMENT,"
  24. + BookTableMetaData.BOOK_NAME + " VARCHAR,"
  25. + BookTableMetaData.BOOK_PUBLISHER + " VARCHAR)";
  26. db.execSQL(TABLESQL);
  27. }
  28.  
  29. @Override
  30. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  31. Log.w(TAG, "Upgrading database from version " + oldVersion + "to"
  32. + newVersion + ", which will destroy all old data");
  33. db.execSQL("DROP TABLE IF EXISTS " + DB_NAME);
  34. onCreate(db);
  35. }
  36. }

5.添加BookContentProvider类

  1. package com.zhangmiao.datastoragedemo;
  2.  
  3. import android.content.ContentProvider;
  4. import android.content.ContentUris;
  5. import android.content.ContentValues;
  6. import android.content.UriMatcher;
  7. import android.database.Cursor;
  8. import android.database.sqlite.SQLiteDatabase;
  9. import android.net.Uri;
  10. import android.support.annotation.Nullable;
  11. import android.util.Log;
  12.  
  13. /**
  14. * Created by zhangmiao on 2016/12/21.
  15. */
  16. public class BookContentProvider extends ContentProvider {
  17.  
  18. private static final String TAG = "BookContentProvider";
  19. private static UriMatcher uriMatcher = null;
  20. private static final int BOOKS = 1;
  21. private static final int BOOK = 2;
  22.  
  23. private ContentProviderDBHelper dbHelper;
  24. private SQLiteDatabase db;
  25.  
  26. static {
  27. uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
  28. uriMatcher.addURI(IProviderMetaData.AUTHORITY,
  29. IProviderMetaData.BookTableMetaData.TABLE_NAME, BOOKS);
  30. uriMatcher.addURI(IProviderMetaData.AUTHORITY,
  31. IProviderMetaData.BookTableMetaData.TABLE_NAME + "/#",
  32. BOOK);
  33. }
  34.  
  35. @Override
  36. public boolean onCreate() {
  37. dbHelper = new ContentProviderDBHelper(getContext());
  38. return (dbHelper == null) ? false : true;
  39. }
  40.  
  41. @Nullable
  42. @Override
  43. public String getType(Uri uri) {
  44. switch (uriMatcher.match(uri)) {
  45. case BOOKS:
  46. return IProviderMetaData.BookTableMetaData.CONTENT_LIST;
  47. case BOOK:
  48. return IProviderMetaData.BookTableMetaData.CONTENT_ITEM;
  49. default:
  50. throw new IllegalArgumentException("This is a unKnow Uri"
  51. + uri.toString());
  52. }
  53. }
  54.  
  55. @Nullable
  56. @Override
  57. public Uri insert(Uri uri, ContentValues values) {
  58. switch (uriMatcher.match(uri)) {
  59. case BOOKS:
  60. db = dbHelper.getWritableDatabase();
  61. long rowId = db.insert(
  62. IProviderMetaData.BookTableMetaData.TABLE_NAME,
  63. IProviderMetaData.BookTableMetaData.BOOK_ID,
  64. values);
  65. Uri insertUri = Uri.withAppendedPath(uri, "/" + rowId);
  66. Log.i(TAG, "insertUri:" + insertUri.toString());
  67. getContext().getContentResolver().notifyChange(uri, null);
  68. return insertUri;
  69. case BOOK:
  70.  
  71. default:
  72. throw new IllegalArgumentException("This is a unKnow Uri"
  73. + uri.toString());
  74. }
  75. }
  76.  
  77. @Nullable
  78. @Override
  79. public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
  80. db = dbHelper.getReadableDatabase();
  81. switch (uriMatcher.match(uri)) {
  82. case BOOKS:
  83. return db.query(IProviderMetaData.BookTableMetaData.TABLE_NAME,
  84. projection, selection, selectionArgs, null, null,
  85. sortOrder);
  86. case BOOK:
  87. long id = ContentUris.parseId(uri);
  88. String where = "_id=" + id;
  89. if (selection != null && !"".equals(selection)) {
  90. where = selection + " and " + where;
  91. }
  92. return db.query(IProviderMetaData.BookTableMetaData.TABLE_NAME,
  93. projection, where, selectionArgs, null, null, sortOrder);
  94. default:
  95. throw new IllegalArgumentException("This is a unKnow Uri"
  96. + uri.toString());
  97. }
  98. }
  99.  
  100. @Override
  101. public int delete(Uri uri, String selection, String[] selectionArgs) {
  102. db = dbHelper.getWritableDatabase();
  103. switch (uriMatcher.match(uri)) {
  104. case BOOKS:
  105. return db.delete(IProviderMetaData.BookTableMetaData.TABLE_NAME,
  106. selection, selectionArgs);
  107. case BOOK:
  108. long id = ContentUris.parseId(uri);
  109. String where = "_id=" + id;
  110. if (selection != null && !"".equals(selection)) {
  111. where = selection + " and " + where;
  112. }
  113. return db.delete(IProviderMetaData.BookTableMetaData.TABLE_NAME,
  114. selection, selectionArgs);
  115. default:
  116. throw new IllegalArgumentException("This is a unKnow Uri"
  117. + uri.toString());
  118. }
  119. }
  120.  
  121. @Override
  122. public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
  123. db = dbHelper.getWritableDatabase();
  124. switch (uriMatcher.match(uri)) {
  125. case BOOKS:
  126. return db.update(IProviderMetaData.BookTableMetaData.TABLE_NAME,
  127. values, null, null);
  128. case BOOK:
  129. long id = ContentUris.parseId(uri);
  130. String where = "_id=" + id;
  131. if (selection != null && !"".equals(selection)) {
  132. where = selection + " and " + where;
  133. }
  134. return db.update(IProviderMetaData.BookTableMetaData.TABLE_NAME,
  135. values, selection, selectionArgs);
  136. default:
  137. throw new IllegalArgumentException("This is a unKnow Uri"
  138. + uri.toString());
  139. }
  140. }
  141. }

6.修改AndroidManifest.xml文件

  1. <provider
  2. android:authorities="com.zhangmiao.datastoragedemo"
  3. android:name=".BookContentProvider"/>

7.修改MainActivity

  1. package com.zhangmiao.datastoragedemo;
  2.  
  3. import android.content.ContentResolver;
  4. import android.content.ContentValues;
  5. import android.database.Cursor;
  6. import android.net.*;
  7. import android.os.Bundle;
  8. import android.support.v7.app.AppCompatActivity;
  9. import android.util.Log;
  10. import android.view.View;
  11. import android.widget.Button;
  12. import android.widget.TextView;import java.util.ArrayList;
  13. import java.util.List;
  14.  
  15. public class MainActivity extends AppCompatActivity implements View.OnClickListener {private ContentResolver mContentResolver;
  16. private BookContentProvider mBookContentProvider;private TextView mTableInfo;
  17.  
  18. @Override
  19. protected void onCreate(Bundle savedInstanceState) {
  20. Log.v("MainActivity", "onCreate");
  21. super.onCreate(savedInstanceState);
  22. setContentView(R.layout.activity_main);
  23.  
  24. Button cpAdd = (Button) findViewById(R.id.provider_add);
  25. Button cpDelete = (Button) findViewById(R.id.provider_delete);
  26. Button cpUpdate = (Button) findViewById(R.id.provider_update);
  27. Button cpQuery = (Button) findViewById(R.id.provider_query);
  28.  
  29. mTableInfo = (TextView) findViewById(R.id.table_info);
  30.  
  31. cpAdd.setOnClickListener(this);
  32. cpDelete.setOnClickListener(this);
  33. cpQuery.setOnClickListener(this);
  34. cpUpdate.setOnClickListener(this);
  35. }
  36.  
  37. @Override
  38. public void onClick(View v) {
  39. switch (v.getId()) {case R.id.provider_add:
  40. mContentResolver = getContentResolver();
  41. String[] bookNames = new String[]{"Chinese", "Math", "English", "Sports"};
  42. String[] bookPublishers = new String[]{"XinHua", "GongXin", "DianZi", "YouDian"};
  43. for (int i = 0; i < bookNames.length; i++) {
  44. ContentValues values = new ContentValues();
  45. values.put(IProviderMetaData.BookTableMetaData.BOOK_NAME, bookNames[i]);
  46. values.put(IProviderMetaData.BookTableMetaData.BOOK_PUBLISHER, bookPublishers[i]);
  47. mContentResolver.insert(IProviderMetaData.BookTableMetaData.CONTENT_URI, values);
  48. }
  49. break;
  50. case R.id.provider_delete:
  51. String bookId = "1";
  52. if (!"".equals(bookId)) {
  53. ContentValues values1 = new ContentValues();
  54. values1.put(IProviderMetaData.BookTableMetaData.BOOK_ID,
  55. bookId);
  56. mContentResolver.delete(
  57. Uri.withAppendedPath(
  58. IProviderMetaData.BookTableMetaData.CONTENT_URI,
  59. bookId
  60. ), "_id = ?",
  61. new String[]{bookId}
  62. );
  63. } else {
  64. mContentResolver.delete(
  65. IProviderMetaData.BookTableMetaData.CONTENT_URI,
  66. null,
  67. null
  68. );
  69. }
  70. break;
  71. case R.id.provider_query:
  72. Cursor cursor = mContentResolver.query(IProviderMetaData.BookTableMetaData.CONTENT_URI, null, null, null, null);
  73. String text = "";
  74. if (cursor != null) {
  75. while (cursor.moveToNext()) {
  76. String bookIdText =
  77. cursor.getString(cursor.getColumnIndex(IProviderMetaData.BookTableMetaData.BOOK_ID));
  78. String bookNameText =
  79. cursor.getString(cursor.getColumnIndex(IProviderMetaData.BookTableMetaData.BOOK_NAME));
  80. String bookPublisherText =
  81. cursor.getString(cursor.getColumnIndex(IProviderMetaData.BookTableMetaData.BOOK_PUBLISHER));
  82. text += "id = " + bookIdText + ",name = " + bookNameText + ",publisher = " + bookPublisherText + "\n";
  83. }
  84. cursor.close();
  85. mTableInfo.setText(text);
  86. }
  87. break;
  88. case R.id.provider_update:
  89. String bookId1 = "2";
  90. String bookName = "Art";
  91. String bookPublisher = "TieDao";
  92. ContentValues values2 = new ContentValues();
  93. values2.put(IProviderMetaData.BookTableMetaData.BOOK_NAME,
  94. bookName);
  95. values2.put(IProviderMetaData.BookTableMetaData.BOOK_PUBLISHER,
  96. bookPublisher);
  97. if ("".equals(bookId1)) {
  98. mContentResolver.update(
  99. IProviderMetaData.BookTableMetaData.CONTENT_URI,
  100. values2, null, null);
  101. } else {
  102. mContentResolver.update(
  103. Uri.withAppendedPath(
  104. IProviderMetaData.BookTableMetaData.CONTENT_URI, bookId1),
  105. values2, "_id = ? ", new String[]{bookId1});
  106. }
  107. break;default:
  108. Log.v("MainActivity", "default");
  109. break;
  110. }
  111. }
  112. }

代码下载地址:https://github.com/ZhangMiao147/DataStorageDemo

参考文章:https://liuzhichao.com/p/562.html

Android之ContentProvider数据存储的更多相关文章

  1. Android五种数据存储方式

    android 五种数据存储 :SharePreferences.SQLite.Contert Provider.File.网络存储 Android系统提供了四种存储数据方式.分别为:SharePre ...

  2. Android——几种数据存储应用浅谈

    (1)android中的数据存储主要有五种方式: 第一种.sharedPreferences存储数据, 适用范围:保存少量的数据,且这些数据的格式非常简单:字符串型.基本类型的值.比如应用程序的各种配 ...

  3. 67.Android中的数据存储总结

    转载:http://mp.weixin.qq.com/s?__biz=MzIzMjE1Njg4Mw==&mid=2650117688&idx=1&sn=d6c73f9f04d0 ...

  4. Android Learning:数据存储方案归纳与总结

    前言 最近在学习<第一行android代码>和<疯狂android讲义>,我的感触是Android应用的本质其实就是数据的处理,包括数据的接收,存储,处理以及显示,我想针对这几 ...

  5. Android中的数据存储

    Android中的数据存储主要分为三种基本方法: 1.利用shared preferences存储一些轻量级的键值对数据. 2.传统文件系统. 3.利用SQLite的数据库管理系统. 对SharedP ...

  6. Android中的数据存储(二):文件存储 2017-05-25 08:16 35人阅读 评论(0) 收藏

    文件存储 这是本人(菜鸟)学习android数据存储时接触的有关文件存储的知识以及本人自己写的简单地demo,为初学者学习和使用文件存储提供一些帮助.. 如果有需要查看SharedPreference ...

  7. Android下的数据存储与訪问 --- 以文件的形式

    Android下的数据存储与訪问 --- 以文件的形式 1.1 储存文件存放在手机内存中: // *** 储存数据到 /data/data/包名/files/jxn.txt文件里 String dat ...

  8. Android开发8:数据存储(二)——SQLite数据库和ContentProvider的使用

    前言 啦啦啦各位小伙伴们许久不见了~学期末和过年期间自己忙着做其他事没能及时更新Android开发系列课程的博客,实在是罪过罪过~ 好啦~废话不多说,进入我们今天的主题.今天我们将和大家学习其他的数据 ...

  9. Android之网络数据存储

    一.网络保存数据介绍 可以使用网络来保存数据,在需要的时候从网络上获取数据,进而显示在App中. 用网络保存数据的方法有很多种,对于不同的网络数据采用不同的上传与获取方法. 本文利用LeanCloud ...

随机推荐

  1. JAVA语言中的修饰符

    JAVA语言中的修饰符 -----------------------------------------------01--------------------------------------- ...

  2. 07. Web大前端时代之:HTML5+CSS3入门系列~H5 地理位置

    Web大前端时代之:HTML5+CSS3入门系列:http://www.cnblogs.com/dunitian/p/5121725.html 源码:https://github.com/duniti ...

  3. 水印第三版 ~ 变态水印(这次用Magick.NET来实现,附需求分析和源码)

    技能 汇总:http://www.cnblogs.com/dunitian/p/4822808.html#skill 以前的水印,只是简单走起,用的是原生态的方法.现在各种变态水印,于是就不再用原生态 ...

  4. 23种设计模式--观察者模式-Observer Pattern

    一.观察者模式的介绍      观察者模式从字面的意思上理解,肯定有两个对象一个是观察者,另外一个是被观察者,观察者模式就是当被观察者发生改变得时候发送通知给观察者,当然这个观察者可以是多个对象,在项 ...

  5. ASP.NET MVC5+EF6+EasyUI 后台管理系统(81)-数据筛选(万能查询)

    系列目录 前言 听标题的名字似乎是一个非常牛X复杂的功能,但是实际上它确实是非常复杂的,我们本节将演示如何实现对数据,进行组合查询(数据筛选) 我们都知道Excel中是如何筛选数据的.就像下面一样 他 ...

  6. scala练习题1 基础知识

    1, 在scala REPL中输入3. 然后按下tab键,有哪些方法可以被调用? 24个方法可以被调用, 8个基本类型: 基本的操作符, 等:     2,在scala REPL中,计算3的平方根,然 ...

  7. Maven多模块,Dubbo分布式服务框架,SpringMVC,前后端分离项目,基础搭建,搭建过程出现的问题

    现互联网公司后端架构常用到Spring+SpringMVC+MyBatis,通过Maven来构建.通过学习,我已经掌握了基本的搭建过程,写下基础文章为而后的深入学习奠定基础. 首先说一下这篇文章的主要 ...

  8. 【干货分享】流程DEMO-补打卡

    流程名: 补打卡申请 业务描述: 当员工在该出勤的工作日出勤但漏打卡时,于一周内填写补打卡申请. 流程相关文件: 流程包.xml 流程说明: 直接导入流程包文件,即可使用本流程 表单:  流程: 图片 ...

  9. NV显卡Ubuntu14.04更新软件导致登录死循环,不过可以进入tty模式

    注意:此方法只适用于nv显卡的电脑! 在网上寻找各种方法无果的情况下,选择重新安装显卡驱动,成功登录进入图形界面. 一.首先需要在另外一台电脑(windows系统也可以)上下载NVIDIA相应显卡驱动 ...

  10. Jquery EasyUI 开发实录

    有好几年没有用过EasyUI了,最近在外包做的一个项目中新增功能时,又用到了,本以为和按照以前那样用就可以了,可当我真正用的时候,发现许多地方不一样了,就连官网的文档都更新了,最突出的就是不知道什么时 ...