zoukankan      html  css  js  c++  java
  • 使用ContentProvider进行应用程序间的数据交互

    什么是ContentProvider:

            ContentProvider用来管理数据的访问规则。它允许你的应用程序向外界暴露需要被访问的数据。

    是Android的四大组件之一。

            ContentProviders支持四种基本的操作,即我们平时所见到的CRUD操作(增删改查)。Android系统

    本身已经提供了一些内容提供者,它们允许我们查询联系人,媒体库,和短息消息等。

    基于Content Uri的查询:

          没有Uri,ContentProvider 类基本无法工作,就像我们上网没有网址。当我们要上网,就要在地址栏输入网址。

    因此,要了解ContentProvider,我们必须先了解 Content Uri

    下面是Uri的基本格式:

    content://authority/optionalPath/optionalId

    content://是内容提供者的标准前缀,而且它必须是content://。authority由我们自己定义,它必须具有唯一性,

    因此我们一般使用应用程序包名命名authority。optionalPath和optionalId是可选的。

    下面我们来看一下WordPress的文章地址格式:

    http://www.whathecode.com/archives/221

    http:// 是http协议的标准写法,它是规定的,没有为什么。

    www.whathecode.com可以理解为authority,因为域名是唯一的,它可以分辨我们要访问哪一个网站。

    arichives可以理解为文章的分类。

    最后的221就是文章的id,假如我们要查看第一遍文章,只要将221改成1就可以。

    这样理解Uri是不是简单了很多。

    建立自己的ContentProvider

    建立ContentProvider只需几部:

    1. 设计数据库的储存方式,因为ContentProvider提供的是数据,没有数据,ContentProvider就没有了用处。

    2. 定义自己的类,继承ContentProvider类,并实现基本的方法。

    3. 设计authority字符串。(要被人访问你的网站,你就需要一个网址,当然ip地址也可以)

    4. 在AndroidManifest中注册Provider

    我们先来研究一下代码:

    作为示例下面的代码只实现了query方法,而且只添加了一个Uri,

    一般应用程序都不只一个Uri

    package com.whathecode.provider;
    
    import android.content.ContentProvider;
    import android.content.ContentValues;
    import android.content.Context;
    import android.content.Intent;
    import android.content.UriMatcher;
    import android.database.Cursor;
    import android.database.sqlite.SQLiteDatabase;
    import android.database.sqlite.SQLiteDatabase.CursorFactory;
    import android.database.sqlite.SQLiteOpenHelper;
    import android.net.Uri;
    import android.util.Log;
    import android.widget.Toast;
    
    public class MemberProvider extends ContentProvider
    {
    	
    	private static final UriMatcher sMatcher;
    	private static final String MEMBER_NAME = "name";
    	private static final int QUERY_BY_NAME = 0;
    	private static final String DB_NAME = "member.db";
    	private static final String TAG = "MemberProvider";
    
    	
    	static
    	{
    		sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
    		/**
    		 * 添加需要匹配的Uri, 当这个Uri被匹配的时候返回第三个参数。
    		 * 得到这个参数之后就可以在query,insert,update,delete
    		 * 方法中做出相应的动作。
    		 */
    		sMatcher.addURI(Member.AUTHORITY, MEMBER_NAME, QUERY_BY_NAME);
    	}
    	
    	private static class DataBaseHelper extends SQLiteOpenHelper
    	{
    
    		public DataBaseHelper(Context context, String name,
    				CursorFactory factory, int version)
    		{
    			super(context, name, factory, version);
    		}
    
    		@Override
    		public void onCreate(SQLiteDatabase db)
    		{
    			//建立数据库表结构
    			db.execSQL("create table member(_id integer primary key," +
    					"name varchar(20)," +
    					"work varchar(20)," +
    					"age integer)");
    		}
    
    		@Override
    		public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
    		{
    			// TODO Auto-generated method stub
    
    		}
    
    	}
    
    	private DataBaseHelper mHelper;
    
    	@Override
    	public boolean onCreate()
    	{
    		mHelper = new DataBaseHelper(getContext(), DB_NAME, null, 2);
    		return true;
    	}
    
    	@Override
    	public Cursor query(Uri uri, String[] projection, String selection,
    			String[] selectionArgs, String sortOrder)
    	{
    
    		 /**
    		  * 前面我们在静态代码块中已添加了Uri库
    		  * 当每个Uri作为参数传进来的时候我们都先进行匹配
    		  * 
    		  */
    		switch (sMatcher.match(uri)) 
    		{
    		case QUERY_BY_NAME:
    			//第一次执行时生成数据库member.db
    			SQLiteDatabase readableDatabase = mHelper.getReadableDatabase();
    			/**
    			 * 当query方法执行的时候向外发送广播
    			 */
    			Intent intent = new Intent();
    			intent.setAction("com.contentprovider.execquery");
    			intent.putExtra("MemberProvider", "query方法执行了");
    			getContext().sendBroadcast(intent);
    			break;
    
    		default:
    			/**
    			 * 当Uri匹配失败的时候说明Uri参数错误,无法继续进行操作,
    			 * 因此程序抛出一个错误
    			 */
    			throw new IllegalArgumentException("Unknown URI " + uri);
    		}
    		return null;
    	}
    	
    	@Override
    	public String getType(Uri uri)
    	{
    		// TODO Auto-generated method stub
    		return null;
    	}
    
    	@Override
    	public Uri insert(Uri uri, ContentValues values)
    	{
    		// TODO Auto-generated method stub
    		return null;
    	}
    
    	@Override
    	public int delete(Uri uri, String selection, String[] selectionArgs)
    	{
    		// TODO Auto-generated method stub
    		return 0;
    	}
    
    	@Override
    	public int update(Uri uri, ContentValues values, String selection,
    			String[] selectionArgs)
    	{
    		// TODO Auto-generated method stub
    		return 0;
    	}
    
    }

    这样,一个虽简单但可行的内容提供者就创建好了,现在我们只需在AndroidManifest文件中注册它。

    <provider android:name="com.whathecode.provider.MemberProvider"
          android:authorities="com.whathecode.contentproviderdemo.member">
    </provider>

    接下来,运行这个程序,将我们刚才定义的ContentProvider部署到模拟器。

    然后,我们建立另外一个程序测试这个内容提供者是否真的工作正常。

    下面是另外一个程序的代码:

    我们需要另外一个类进行访问ContentProvider提供的数据。

    这个类就是ContentResolver,它提供了和ContentProvider一样的CRUD方法。

    方便我们查询数据。

    package com.whathecode.contentprovidertest;
    
    import android.app.Activity;
    import android.content.BroadcastReceiver;
    import android.content.ContentResolver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.net.Uri;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.Toast;
    
    public class MainActivity extends Activity
    {
    
    	private BroadcastReceiver receiver;
    	@Override
    	protected void onCreate(Bundle savedInstanceState)
    	{
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    		
    
    		//创建一个广播接受者用于接收MemberProvider发出的广播
    		receiver = new BroadcastReceiver()
    		{
    
    			@Override
    			public void onReceive(Context context, Intent intent)
    			{
    				/**
    				 * 当广播被接收到的时候Toast提示用户接收到的信息
    				 */
    				Toast.makeText(getBaseContext(),
    						"收到的信息" + intent.getStringExtra("MemberProvider"),
    						Toast.LENGTH_SHORT).show();
    			}
    		};
    	}
    	
    	@Override
    	protected void onResume()
    	{
    		super.onResume();
    		//注册广播接受者
    		registerReceiver(receiver, new IntentFilter("com.contentprovider.execquery"));
    	}
    
    	public void onClick(View view)
    	{
    		/**
    		 * 获取ContentResolver实例访问ContentProvider
    		 */
    		ContentResolver resolver = getContentResolver();
    		Uri uri = Uri
    				.parse("content://com.whathecode.contentproviderdemo.member/name");
    		resolver.query(uri, null, null, null, null);
    	}
    	
    	@Override
    	protected void onPause()
    	{
    		super.onPause();
    		//取消注册广播接受者
    		unregisterReceiver(receiver);
    	}
    }

    运行效果:

    如果Toast运行证明MemberProvider中的query方法被成功执行

    ContentProvider

  • 相关阅读:
    ES6 数值类型常用方法
    阿里云如何发布网站
    常用的网站推荐
    笔记一 sql 基础知识
    笔记一 MVC初识
    基础二 面向对象编程
    基础一
    css reset 样式
    CSS 嵌套绝对定位
    ADO
  • 原文地址:https://www.cnblogs.com/ai-developers/p/4267543.html
Copyright © 2011-2022 走看看