当前位置: 移动技术网 > IT编程>移动开发>Android > 实例讲解Android中ContentProvider组件的使用方法

实例讲解Android中ContentProvider组件的使用方法

2019年07月24日  | 移动技术网IT编程  | 我要评论

江油市招聘,陕西中考成绩查询2014,俄罗斯功夫熊走红

contentprovider基本使用
为了在应用程序之间交换数据,android提供了contentprovider,contentprovider是不同应用程序之间进行数据交换的标准api,当一个应用程序需要把自己的数据暴露给其他程序使用时,该应用程序就可以通过提供contentprovider来实现,其他应用程序就可以通过contentresolver来操作contentprovider暴露的数据。

实现contentprovider的步骤:

1)编写一个类,继承contentprovider,并且重写里面的crud方法。

2)在androidmanifest.xml文件中注册provider。

在androidmanifest.xml中注册provider需要以下3个属性:

             android:name              provider的实现类。

             android:authorities       provider的uri。

             android:exported          provider是否暴露给其他程序。


contentresovler操作contentprovider:

1)获取contentresolver,getcontentresovler()方法来自于contextwrapper,所以activity和service中都可以使用。

2)调用curd方法,通过参数url,调用指定的contentprovider的方法。


下面是一个demo,向contentprovider中插入一条数据,并且返回到listview中。

main.xml:

<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".main" >
 
  <listview
    android:id="@+id/listview"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />
 
</relativelayout>

mysqliteopenhelper类

package com.app.dao;
 
import android.content.context;
import android.database.sqlite.sqlitedatabase;
import android.database.sqlite.sqlitedatabase.cursorfactory;
import android.database.sqlite.sqliteopenhelper;
 
public class mysqliteopenhelper extends sqliteopenhelper {
 
  public mysqliteopenhelper(context context, string name,
      cursorfactory factory, int version) {
    super(context, name, factory, version);
 
  }
 
  @override
  public void oncreate(sqlitedatabase db) {
 
    string create_sql = "create table tb_test(_id integer primary key autoincrement,name,gender,age)";
     
    db.execsql(create_sql);
  }
 
  @override
  public void onupgrade(sqlitedatabase db, int oldversion, int newversion) {
 
  }
 
}

mycontentprovider类

package com.app.dao;
 
import android.content.contentprovider;
import android.content.contentvalues;
import android.database.cursor;
import android.net.uri;
 
public class mycontentprovider extends contentprovider{
 
  mysqliteopenhelper helper=null;
  @override
  public int delete(uri arg0, string arg1, string[] arg2) {
     
    return 0;
  }
 
  @override
  public string gettype(uri arg0) {
    // todo auto-generated method stub
    return null;
  }
 
  @override
  public uri insert(uri arg0, contentvalues values) {
     
    string insert_sql="insert into tb_test values(null,'wx','boy',17)";
     
    helper.getreadabledatabase().execsql(insert_sql);
     
    return null;
  }
 
  @override
  public boolean oncreate() {
     
    helper=new mysqliteopenhelper(this.getcontext(),"test.db3",null,1);
     
    return true;
  }
 
  @override
  public cursor query(uri arg0, string[] arg1, string arg2, string[] arg3,
      string arg4) {
     
    string query_sql="select * from tb_test";
     
    cursor cursor=helper.getreadabledatabase().rawquery(query_sql, null);
     
    return cursor;
  }
 
  @override
  public int update(uri arg0, contentvalues arg1, string arg2, string[] arg3) {
    // todo auto-generated method stub
    return 0;
  }
 
}

listview的显示界面show.xml

<?xml version="1.0" encoding="utf-8"?>
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="horizontal" >
 
  <textview
    android:id="@+id/name"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
 
  <textview
    android:id="@+id/gender"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginleft="60dp" />
 
  <textview
    android:id="@+id/age"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginleft="60dp" />
 
</linearlayout>

main.java

package com.app.main;
 
import android.annotation.suppresslint;
import android.app.activity;
import android.content.contentresolver;
import android.database.cursor;
import android.net.uri;
import android.os.bundle;
import android.support.v4.widget.cursoradapter;
import android.widget.listview;
import android.widget.simplecursoradapter;
 
public class main extends activity {
 
  contentresolver resolver = null;
 
  listview lv = null;
 
  @suppresslint("newapi")
  @override
  protected void oncreate(bundle savedinstancestate) {
 
    super.oncreate(savedinstancestate);
 
    setcontentview(r.layout.main);
 
    lv = (listview) this.findviewbyid(r.id.listview);
 
    resolver = this.getcontentresolver();
 
    string str = "content://com.app.test.db/";
 
    uri uri = uri.parse(str);
 
    resolver.insert(uri, null);
 
    cursor cursor = resolver.query(uri, null, null, null, null);
 
    simplecursoradapter adapter = new simplecursoradapter(this,
        r.layout.show, cursor,
        new string[] { "name", "gender", "age" }, new int[] {
            r.id.name, r.id.gender, r.id.age },
        cursoradapter.flag_register_content_observer);
 
    lv.setadapter(adapter);
 
  }
 
}

实现效果:(执行了3次插入后的效果)

2016421160202125.png (720×1280)

contentprovider的单元测试
contentprovider是android的四大组件之一,在编写代码的时候最好是加上单元测试,这样可以确定对数据的crud的正确。本篇文章主要介绍contentprovider中两个主要辅助类的使用还有单元测试的在contentprovider中的使用。

需要用到的两个辅助类:urimatcher类和contenturis类。

urimatcher类:能够对输入的uri参数就行匹配,以确定对什么表执行什么样的操作。

contenturis类:有些方法需要返回uri,运用此类可以方便的生成uri类。

对于单元测试,个人觉得非常有必要在今后写代码的时候使用,这样可以非常准确的确定代码的正确性。

使用单元测试的步骤:

 1)加入instrumentation,这个部分的代码是固定,也可以完全在adt提供的向导中导入。

<instrumentation
    android:name="android.test.instrumentationtestrunner"
    android:targetpackage="com.example.android_contentprovider" >
  </instrumentation>

2)添加<uses-library>,这个部分的代码也是固定的写法。

 <uses-library android:name="android.test.runner" />


好了,必备的知识已经讲完了,现在上代码:

1)生成一个sqlitedatabase类,这个是必需的类mysqliteopenhelper类

package com.app.db;
 
import android.content.context;
import android.database.sqlite.sqlitedatabase;
import android.database.sqlite.sqlitedatabase.cursorfactory;
import android.database.sqlite.sqliteopenhelper;
 
public class mysqliteopenhelper extends sqliteopenhelper {
 
  private static string db_name = "test.db3";
  private static int version = 1;
 
  public mysqliteopenhelper(context context) {
    super(context, db_name, null, version);
 
  }
 
  @override
  public void oncreate(sqlitedatabase db) {
       //建表语句
    string create_student = "create table student(_id integer primary key autoincrement,name varchar(10),age integer,gender vachar(10))";
     
    db.execsql(create_student);
       //千万不能执行这句  // db.close();
 
  }
 
  @override
  public void onupgrade(sqlitedatabase arg0, int arg1, int arg2) {
 
  }
 
}

 
然后添加我们需要的mycontentprovider类:

package com.app.contentprovider;
 
import com.app.db.mysqliteopenhelper;
 
import android.content.contentprovider;
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;
import android.util.log;
 
public class mycontentprovider extends contentprovider {
 
  mysqliteopenhelper helper = null;
 
  private static urimatcher matcher = new urimatcher(urimatcher.no_match);
 
  // 匹配单条记录
  private static final int student = 1;
  // 匹配多条记录
  private static final int students = 2;
 
  static {
    matcher.adduri("com.app.wx", "student/#", student);
 
    matcher.adduri("com.app.wx", "student", students);
  }
 
  @override
  public int delete(uri uri, string selection, string[] selectionargs) {
 
    sqlitedatabase db = helper.getwritabledatabase();
 
    int action = matcher.match(uri);
 
    switch (action) {
     
    // 匹配单条记录
    case student:
 
      long id = contenturis.parseid(uri);
     //获取单条记录的id号
      string delete_id = "_id=" + id;
 
      if (selection != null) {
        delete_id += delete_id + " and " + selection;
      }
 
      db.delete("student", delete_id, selectionargs);
 
      break;
       
    // 匹配多条记录
    case students:
 
      db.delete("student", selection, selectionargs);
 
      break;
    }
     
    return 0;
  }
 
  //必需实现这个方法,这个方法与intent有关系,以后再讲
  @override
  public string gettype(uri uri) {
 
    int code = matcher.match(uri);
    switch (code) {
    case student:
      return "vnd.android.cursor.item/student_item";
    case students:
      return "vnd.android.cursor.dir/students";
    default:
      return null;
    }
  }
 
  @override
  public uri insert(uri uri, contentvalues values) {
 
    sqlitedatabase db = helper.getwritabledatabase();
 
    int action = matcher.match(uri);
 
    switch (action) {
 
    case students:
 
      long id1 = db.insert("student", "_id", values);
 
      log.i("--------", contenturis.withappendedid(uri, id1).tostring());
 
      return contenturis.withappendedid(uri, id1);
 
    }
 
    return null;
  }
 
  @override
  public boolean oncreate() {
 
    helper = new mysqliteopenhelper(this.getcontext());
 
    return true;
  }
 
  @override
  public cursor query(uri uri, string[] projection, string selection,
      string[] selectionargs, string orderby) {
 
    sqlitedatabase db = helper.getwritabledatabase();
 
    cursor cursor = null;
 
    int action = matcher.match(uri);
 
    switch (action) {
 
    case students:
 
      cursor = db.query("student", projection, selection, selectionargs,
          null, null, orderby);
 
      break;
 
    }
 
    system.out.println("-----------count:" + cursor.getcount());
 
    return cursor;
  }
 
  @override
  public int update(uri uri, contentvalues values, string selection,
      string[] arg3) {
 
    int count = -1;
 
    sqlitedatabase db = helper.getwritabledatabase();
 
    int action = matcher.match(uri);
 
    switch (action) {
 
    case student:
      // 以id来处理更新
      long id = contenturis.parseid(uri);
 
      string id_selection = "_id=" + id;
 
      if (selection != null && !selection.equals("")) {
 
        id_selection = id_selection + " and " + values;
 
      }
 
      count = db.update("student", values, id_selection, arg3);
 
      system.out.println("----------count:" + count);
 
      break;
    }
 
    return count;
  }
 
}

这个类很长,但是执行的方法都是比较常见的curd的方法,重要的是urimatcher和contenturis类的使用。

接着执行单元测试类:test

package com.app.contentprovider;
 
import android.content.contentresolver;
import android.content.contentvalues;
import android.database.cursor;
import android.net.uri;
import android.test.androidtestcase;
import android.util.log;
 
public class test extends androidtestcase {
 
  public void insert() {
 
    contentresolver resolver = this.getcontext().getcontentresolver();
 
    string str = "content://com.app.wx/student";
 
    contentvalues values = new contentvalues();
 
    values.put("name", "wzq");
 
    values.put("age", 18);
 
    values.put("gender", "boy");
 
    resolver.insert(uri.parse(str), values);
 
  }
 
  public void update() {
 
    contentresolver resolver = this.getcontext().getcontentresolver();
 
    string str = "content://com.app.wx/student/2";
 
    contentvalues values = new contentvalues();
 
    values.put("name", "哈哈");
 
    resolver.update(uri.parse(str), values, null, null);
 
  }
 
  public void query() {
 
    contentresolver resolver = this.getcontext().getcontentresolver();
 
    string str = "content://com.app.wx/student";
 
    uri uri = uri.parse(str);
 
    cursor cursor = resolver.query(uri, new string[] { "_id",
        "name,age,gender" }, null, null, "_id desc");
 
    log.d("------count",cursor.getcount()+"");
  }
 
  public void delete() {
    contentresolver resolver = this.getcontext().getcontentresolver();
 
    string str = "content://com.app.wx/student/2";
 
    uri uri = uri.parse(str);
 
    long id=resolver.delete(uri, null, null);
 
  }
 
}

执行insert方法之后(执行了三次):

2016421160332881.png (463×93)

执行了update方法之后:

2016421160354111.png (458×101)

执行了query方法之后:

2016421160411590.png (617×92)

执行了delete方法之后:

2016421160429449.png (513×79)

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网