ContentProvider中的数据生成时机
2015-09-08 23:01
645 查看
目录结构:
,
先给个结论:
仅仅是实例化mySqliteHelper()这个类的时候是不会创建数据库的,实际上数据库的真正创建是在helper.getWritableDatabase()的方法执行后才会真正创建,或者执行helper.getReadableDatabase()也会创建数据库(如果没有数据库的话)
安卓好这个应用控制台的System.out.print()的所有输出内容为:
09-09 05:30:28.892: I/System.out(2764): myContentProvider.static{} 静态代码块。。。。
09-09 05:30:28.904: I/System.out(2764): ==看看实例化本类的时候,是否会执行到我.....==
09-09 05:30:28.912: I/System.out(2764): helper实际上已经实例化了。。。
09-09 05:30:29.096: I/System.out(2764): mySqliteHelper onCreate(SQLiteDatabase db)方法......
09-09 05:30:29.144: I/System.out(2764): myContentProvider.onCreate()方法,实际上应该已经创建了数据库
09-09 05:30:29.144: I/System.out(2764): myContentProvider.onCreate()方法, jianli le zhangyalan.db
MainActivity.java
myContentProvider.java
mySqliteHelper.java
myMetaData.java
,
先给个结论:
仅仅是实例化mySqliteHelper()这个类的时候是不会创建数据库的,实际上数据库的真正创建是在helper.getWritableDatabase()的方法执行后才会真正创建,或者执行helper.getReadableDatabase()也会创建数据库(如果没有数据库的话)
安卓好这个应用控制台的System.out.print()的所有输出内容为:
09-09 05:30:28.892: I/System.out(2764): myContentProvider.static{} 静态代码块。。。。
09-09 05:30:28.904: I/System.out(2764): ==看看实例化本类的时候,是否会执行到我.....==
09-09 05:30:28.912: I/System.out(2764): helper实际上已经实例化了。。。
09-09 05:30:29.096: I/System.out(2764): mySqliteHelper onCreate(SQLiteDatabase db)方法......
09-09 05:30:29.144: I/System.out(2764): myContentProvider.onCreate()方法,实际上应该已经创建了数据库
09-09 05:30:29.144: I/System.out(2764): myContentProvider.onCreate()方法, jianli le zhangyalan.db
MainActivity.java
package com.wyl.contentprovidermine; import android.app.Activity; import android.content.ContentResolver; import android.content.ContentValues; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity implements OnClickListener{ Button btn_insert; Button btn_select; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_insert = (Button) findViewById(R.id.btn_insert); btn_select = (Button) findViewById(R.id.btn_select); btn_insert.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_insert: ContentResolver cr = getContentResolver(); ContentValues values = new ContentValues(); values.put(myMetaData.UserTableMetaData.NAME, "zyl"); values.put(myMetaData.UserTableMetaData.AGE, 21); values.put(myMetaData.UserTableMetaData.SEX, "女"); // Uri uri = new URI() System.out.println("点了insert按钮......"); cr.insert(myMetaData.UserTableMetaData.CONTENT_URI, values); System.out.println("点了insert按钮------------------"); break; case R.id.btn_select: System.out.println("查询数据......"); break; } } }
myContentProvider.java
package com.wyl.contentprovidermine; 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; public class myContentProvider extends ContentProvider { mySqliteHelper helper; SQLiteDatabase db; private static final UriMatcher myUriMatcher = new UriMatcher( UriMatcher.NO_MATCH); public static final int USERS = 1;// 代表表名 public static final int USERS_NAME = 2; // 字段名 public static final int USERS_SEX = 3; // 字段名 ,性别 public static final int USERS_AGE = 4; // 字段名,年龄 public static final int USERS_SINGLE = 5; static { System.out.println("myContentProvider.static{} 静态代码块。。。。"); myUriMatcher.addURI(myMetaData.AUTHORITY, "/users", USERS);// 匹配表名 myUriMatcher.addURI(myMetaData.AUTHORITY, "/users/name", USERS_NAME); myUriMatcher.addURI(myMetaData.AUTHORITY, "/users/sex", USERS_SEX); myUriMatcher.addURI(myMetaData.AUTHORITY, "/users/age", USERS_AGE);// 只能匹配age这个字段 myUriMatcher.addURI(myMetaData.AUTHORITY, "/users/#", USERS_SINGLE);// 这个可以匹配任何字段名 } @Override public boolean onCreate() { // TODO Auto-generated method stub /* * 创建数据库,同时也会生成表,见mySqliteHelper的onCreate()方法, 这个方法里有创建表的代码 */ /* * 如果这行代码(helper = new mySqliteHelper(getContext(),"zhangyalan.db");)注释掉了,那么当 * 插入数据的时候执行下面的insert方法的时候就会空指针异常,因为在清单文件中配置了,所以这个android app * 安装的时候,就会执行这个类,即 myContentProvider.java ,而且 在这个类里,首先执行静态代码块里的代码, * 然后执行本方法myContentProvider.onCreate(),本类的其他方法,如insert(),query()等方法,只 * 有用户在手机界面进行操作的时候才会执行到。知道了这里的执行顺序那么就很容易理解为什么下面的这行代码注释掉了就会 * 导致用户插入数据的时候会导致空指针异常了(因为 helper没有实例化),自己写一个ContentProvider的时候要首 * 先实例化这里就提示了我们很重要的一点,即实例化SQLiteOpenHelper的时机一定要早,比如放到静态代码块 * 或者onCreate()方法里 */ helper = new mySqliteHelper(getContext(), "zhangyalan.db");// 这行代码千万要实例化 if (helper == null) { System.out.println("helper实际上还没实例化"); } else { System.out.println("helper实际上已经实例化了。。。"); } helper.getWritableDatabase(); System.out.println("myContentProvider.onCreate()方法,实际上应该已经创建了数据库"); System.out .println("myContentProvider.onCreate()方法, jianli le zhangyalan.db"); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub return null; } // 作用:根据传入的URI,返回该URI所表示的数据类型 @Override public String getType(Uri uri) { // TODO Auto-generated method stub System.out.println("public String getType(Uri uri) 开始了。。。。。。"); switch (myUriMatcher.match(uri)) { case USERS: return myMetaData.UserTableMetaData.CONTENT_TYPE; case USERS_SINGLE: return myMetaData.UserTableMetaData.CONTENT_TYPE_ITEM; default: throw new IllegalArgumentException("未知的uri,unknow URI..." + uri); } } @Override public Uri insert(Uri uri, ContentValues values) { System.out.println("myContentProvider.insert()......1 "); /* * 仅仅是实例化mySqliteHelper()这个类的时候是不会创建数据库的 * 实际上数据库的真正创建是在helper.getWritableDatabase()的方法执行后才会真正创建, * 或者执行helper.getReadableDatabase()也会创建数据库(如果没有数据库的话) */ db = helper.getWritableDatabase(); System.out.println("myContentProvider.insert()......2 "); long rowId = db.insert(myMetaData.UserTableMetaData.TABLE_NAME, null, values); if (rowId > 0) { Uri rtnUri = ContentUris.withAppendedId(uri, rowId); System.out.println("myContentProvider.insert()......3 "); return rtnUri; } System.out.println("myContentProvider.insert()......4 "); 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; } }
mySqliteHelper.java
package com.wyl.contentprovidermine; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; public class mySqliteHelper extends SQLiteOpenHelper { static { System.out.println("==看看实例化本类的时候,是否会执行到我.....=="); } public mySqliteHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); // TODO Auto-generated constructor stub } public mySqliteHelper(Context context, String name, int version) { super(context, name, null, version); // TODO Auto-generated constructor stub } /** * 两个参数的构造器,用来创建数据库 * * @param context * activity * @param name * 数据库名 */ public mySqliteHelper(Context context, String name) { this(context, name, 1); // TODO Auto-generated constructor stub } /** * 这个方法主要是用来创建 表的, 现在的疑问是 数据库是是什么时候创建的:实际上数据库是实例化该MySqliteHelper的时候 * 并没有创建数据库,数据库的真正创建是在helper.getWritableDatabase()的方法执 * 行后才会真正创建,或者执行helper.getReadableDatabase()也会创建数据库(如果没有数据库的话) */ @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub System.out .println("mySqliteHelper onCreate(SQLiteDatabase db)方法......"); db.execSQL(myMetaData.UserTableMetaData.CREATE_TABLE_SQL);// 创建表 } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub } }
myMetaData.java
package com.wyl.contentprovidermine; import android.net.Uri; import android.provider.BaseColumns; public class myMetaData { //AUTHORITY 是一个类名,即contentprovider的类名 public static final String AUTHORITY = "com.wyl.contentprovidermine"; //数据库名称 public static final String DATABASE_NAME = "wyl.db"; //表名 public static final String USER_TABLE_NAME = "users"; public static class UserTableMetaData implements BaseColumns{ //字表名称 public static final String TABLE_NAME = "users"; public static final Uri CONTENT_URI = Uri.parse("content://"+AUTHORITY+"/users"); //1 content 2 AUTHORITY 3.字标的名字 public static final String NAME = "name"; public static final String SEX = "sex"; public static final String AGE = "age"; public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.myprovider.users"; //上面的 CONTENT_TYPE: 其中的 vnd.android.cursor.dir/vnd 是固定的, 后面的 myprovider.users 自己随便定义 public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd.myprovider.users"; public static final String DEFAULT_SORT_ORDER = "_id desc"; public static final String CREATE_TABLE_SQL = "create table if not exists "+TABLE_NAME + " (_id integer primary key autoincrement,name text not null,sex text,age integer not null) "; } }
相关文章推荐
- 题目2:在斐波那契数列中,找出4百万以下的项中值为偶数的项之和。
- 1.1-php编译安装
- php 正则表达式
- lsgogroup_php_G1小组在这里起航啦!
- PHP面向对象的mysql数据库函数封装
- PHP实现留言本代码
- phpstorm php-cgi not found
- 一个超级简单的php框架
- [PHP自动化-进阶]005.Snoopy采集框架介绍
- PHPer 为什么会被 Javaer 鄙视?
- PHPer 为什么会被 Javaer 鄙视?
- PHP基础语法实例
- 解决vsftpd的530/227/500错误
- ContentProvider,BroadCastReceiver,Service
- hive 使用php脚本来完成map/reduce
- 【ThinkPHP】ThinkPHP下载、部署,Helloworld,消除难看的index.php
- [PHP自动化-进阶]004.Snoopy VS CURL 模拟Discuz.net登陆
- 数据存储:ContentProvider获取联系人
- [Swoole入门]-Ubuntu环境下安装Swoole扩展
- 数据存储详解(四)及四大组件之一 之--->ContentProvider(内容提供者)