Android开发之ContentProvider结合LoaderManager加载数据(图文源代码分享)

       ContentProvider作为Android的四大存储方式之一,有着广泛的应用性,它暴露了数据地址,可以让其他应用访问数据,可以用于存储图片、通讯录等信息,这篇博文将详细介绍ContentProvider、URIMatcher,LoaderManager,cursorAdapter的方法使用与介绍。使用ContentProvider的时候一定要注意在manifest清单文件中像Acticity文件一样,声明其属性。如图所示


此外因为我们是用loadermanager来加载数据,MainAcitivity类要实现LoaderCallback接口。按照惯例我们还是看下谷歌官方文档对contentprovider的解释,ContentProvider管理一个结构化的数据集。它封装了数据,并提供定义数据安全机制。ContentProvider的标准接口实现多线程机制来连接数据,一般是用loaderManager异步加载数据。当你想要访问数据在一个ContentProvider,我们使用ContentResolver对象在应用程序的上下文中作为沟通方法。ContentResolver用来解析请求码返还数据。

我们先看看一下本次介绍的工程的目录结构

Android开发之ContentProvider结合LoaderManager加载数据(图文源代码分享)_第1张图片

MainActivity的代码

package com.example.f14_contentprovider;

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

import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.app.LoaderManager;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;

public class MainActivity extends Activity implements LoaderCallbacks<Cursor> {
	private Button button;
	private ListView listView;
	private LoaderManager loaderManager;
	private SimpleCursorAdapter adapter;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		button = (Button) this.findViewById(R.id.button1);
		listView = (ListView) this.findViewById(R.id.listView1);
		button.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				ContentResolver resolver = getContentResolver();
				Uri uri = Uri
						.parse("content://com.example.f14_contentprovider.PersonContentProvider/person");
				ContentValues values = new ContentValues();
				values.put("name", "jack");
				values.put("address", "hangzhou");
				resolver.insert(uri, values);
				loaderManager.restartLoader(1001, null, MainActivity.this);
			}
		});
		loaderManager = getLoaderManager();
		loaderManager.initLoader(1001, null, this);
	}



	@Override
	public Loader<Cursor> onCreateLoader(int id, Bundle args) {
		// TODO Auto-generated method stub
		/**
		 * CursorLoader该类用于加载程序,查询ContentResolver并返回一个指针。这个类实现了装载机协议查询游标的标准方法,
		 * 基于AsyncTaskLoader执行游标查询在一个后台线程,以便它不会阻止应用程序的UI。
		 */
		CursorLoader loader = new CursorLoader(this);
		Uri uri = Uri
				.parse("content://com.example.f14_contentprovider.PersonContentProvider/person");
		loader.setUri(uri);
		loader.setProjection(new String[] { "name", "address" });
		return loader;
	}

	@SuppressWarnings("deprecation")
	@Override
	public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {
		// TODO Auto-generated method stub
		List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
		// 加载数据
		while (arg1.moveToNext()) {
			HashMap<String, String> map = new HashMap<String, String>();
			map.put("name", arg1.getString(arg1.getColumnIndex("name")));
			map.put("address", arg1.getString(arg1.getColumnIndex("address")));
			list.add(map);
		}
		adapter = new SimpleCursorAdapter(this, R.layout.item, arg1,
				new String[] { "name", "address" }, new int[] { R.id.textView1,
						R.id.textView2 });
		listView.setAdapter(adapter);
		adapter.notifyDataSetChanged();// 若内容发生变化 触发该方法
	}

	@Override
	public void onLoaderReset(Loader<Cursor> arg0) {
		// TODO Auto-generated method stub

	}

}
     如上所示,在MainAcitivity主方法中,大家可以看到第40-47行代码中,通过内容提供者contentProvider插入数据的时候,是通过contentResolver进行连接,通过其insert方法提供插入指定的数据表和数据完成操作。操作完成后还需要调用loadermanager的restart方法更新一次UI。
PersonContentProvider继承了ContentProvider的方法

package com.example.f14_contentprovider;

import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;

//要在manifest文件中注册provider
public class PersonContentProvider extends ContentProvider {
	private MyOpenHelper helper;
	private static final UriMatcher matcher = new UriMatcher(
			UriMatcher.NO_MATCH);// 专门用来匹配URI的类
	private static final int PERSONS = 1;
	private static final int PERSON = 2;
	private ContentResolver resolver;
	static {
		matcher.addURI("com.example.f14_contentprovider.PersonContentProvider",
				"person", PERSONS);
		matcher.addURI("com.example.f14_contentprovider.PersonContentProvider",
				"person/#", PERSON);
	}

	@Override
	public int delete(Uri uri, String selection, String[] selectionArgs) {
		// TODO Auto-generated method stub
		return 0;
	}

	// 当您需要匹配一个URI,调用匹配(URI),用来来建立一个查询,返回类型,插入或删除一行。
	@Override
	public String getType(Uri arg0) {
		// TODO Auto-generated method stub
		int match = matcher.match(arg0);
		switch (match) {
		case PERSONS:
			return "vnd.android.cursor.dir/person";
		case PERSON:
			return "vnd.android.cursor.item/person";
		default:
			return null;
		}

	}

	@Override
	public Uri insert(Uri uri, ContentValues values) {
		// TODO Auto-generated method stub
		SQLiteDatabase database = helper.getWritableDatabase();
		long id = database.insert("person", null, values);
		Uri rUri = ContentUris.withAppendedId(uri, id);
		resolver.notifyChange(rUri, null);
		return rUri;
	}

	@Override
	public boolean onCreate() {
		// TODO Auto-generated method stub
		helper = new MyOpenHelper(getContext());
		resolver = getContext().getContentResolver();
		return true;
	}

	@Override
	public Cursor query(Uri uri, String[] projection, String selection,
			String[] selectionArgs, String sortOrder) {
		// TODO Auto-generated method stub
		Cursor cursor = null;
		int flag = matcher.match(uri);
		SQLiteDatabase database = helper.getReadableDatabase();
		switch (flag) {
		case PERSONS:
            cursor=database.query("person", null, null, null,null, null, null);
			break;
		case PERSON:
			long _id = ContentUris.parseId(uri);
			String where_value = " _id  = " + _id;
			if (selection != null && !selection.equals("")) {
				where_value += selection;
			}
			cursor = database.query("person", projection, where_value,
					selectionArgs, null, null, sortOrder);
			break;

		default:
			break;
		}
		cursor.setNotificationUri(resolver, uri);
		return cursor;
	}

	@Override
	public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
		// TODO Auto-generated method stub
		return 0;
	}

}

数据库创建类MyopenHelper

package com.example.f14_contentprovider;

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

import android.database.sqlite.SQLiteOpenHelper;

public class MyOpenHelper extends SQLiteOpenHelper {
	private static final int DATABASE_VERSION = 1;
	private static final String PERSON_TABLE_NAME = "person";

	public MyOpenHelper(Context context) {
		super(context, PERSON_TABLE_NAME, null, DATABASE_VERSION);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		// TODO Auto-generated method stub
		db.execSQL("create table "
				+ PERSON_TABLE_NAME
				+ "(_id integer primary key autoincrement,name varchar(64),address varchar(64))");

	}

	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		// TODO Auto-generated method stub

	}

}


你可能感兴趣的:(android,ContentProvider,contentresolver,sqlitedatabase,loadermanager)