ContentProvider中的数据生成时机
目录结构:
,
先给个结论:
仅仅是实例化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) ";
} }
ContentProvider中的数据生成时机的更多相关文章
- java中json数据生成和解析(复杂对象演示)
1.json简单介绍 1.1 json是最流行和广泛通用的数据传输格式,简称JavaScript Object Notation,最早在JavaScript中使用. 1.2 举个例子,下面是一个jso ...
- loadrunner之Paramater在负载测试中的数据生成规则
前段时间在做性能测试的时候,基于业务的需求,使用到了Unique Number的参数类型. 脚本的业务是注册以alien开头,后面接数字的用户帐号,填写相关帐号信息.提交企业信息进行审核. 其中用户帐 ...
- 利用存储过程将表中的数据生成Insert语句
1.创建存储过程 CREATE PROC [dbo].[sp_get_InsertSql] @dbName VARCHAR ( )= '' , -- 数据库名称 @tabList VARCHAR ( ...
- 将excle表中得数据生成insert语句插入到数据库中
第一步:输入公式 第二步:拽住右下角得+往下拖拽
- ContentProvider中的数据库的生成时机以及ContentResolver的insert()方法总结
经过几天的总结,以及结合一些代码的实际测试,终于算是明白了ContentProvider中的数据的生成时机了. 目录结构: MainActivity.java package com.wyl.cont ...
- 快速将一个表的数据生成SQL插入语句
将一个表中的数据生成SQL插入语句,方便系统快速初始化,在数据库中执行创建以下过程就可以了. ) Drop Procedure GenerateData go CREATE PROCEDURE Gen ...
- 安卓中的数据存储方式以及ContentProvider的简单介绍
1.介绍android的数据存储方式 File存储 sharedPrefrence存储方式 conmtentprovider sqlitedatabase 网络存储 2.请介绍下ContentPr ...
- 将表中数据生成SQL语句
在开发过程中,经常需要我们对表中的数据进行转移,如果在同台机器,可以使用SQL自带的导入数据,但是如果想让所有的数据生成可执行的SQL语句,它的移植性最强了.首先要设计一个存储过程.具体如下: CRE ...
- c#保存datagridview中的数据时报错 “动态SQL生成失败。找不到关键信息”
ilovejinglei 原文 C#中保存datagridview中的数据时报错"动态SQL生成失败.找不到关键信息" 问题描述 相关代码 using System; us ...
随机推荐
- (转)WIN2003服务器禁PING的方法
方法一:用windows系统自带的防火墙规则设置禁止别人Ping我的机器 win2003系统默认情况下,所有Internet控制消息协议(ICMP)选项均被禁用,也就是对客户机有反应,因而易于受到攻击 ...
- RAW模板开发必备知识
写这个主要是为了让已经熟练掌握PHP的人能够快速的掌握RAW模板开发,从而享受RAW的优越! (注:在实际开发中,最好注意RAW模板开发统一规范,那样可以增强用户体验) 废话不多说,进入正题. 需要记 ...
- linux技术框架
编程语言 一般使用c或者c++ linux使用 鸟哥私房菜 工具使用 代码编辑source insight,代码编译gcc,代码调试gdb,代码编译组织makefile,命令执行shell,文本编辑n ...
- jQuery.merge 源码阅读
jQuery.merge(first,second) 概述 合并两个数组 返回的结果会修改第一个数组的内容——第一个数组的元素后面跟着第二个数组的元素. 参数 first:第一个待处理数组,会改变其中 ...
- Linux内核启动代码分析二之开发板相关驱动程序加载分析
Linux内核启动代码分析二之开发板相关驱动程序加载分析 1 从linux开始启动的函数start_kernel开始分析,该函数位于linux-2.6.22/init/main.c start_ke ...
- [python网络编程]DNSserver
在上一篇中,使用scrapy改动源IP发送请求的最后我们提到因为hosts文件不支持正则,会导致我们的随机域名DNS查询失败. 使用DNS代理服务器能够解决问题, 以下是我用gevent写的小工具.非 ...
- asp.net js调用后台方法
先前网上百度了很多 ,大致都一样 但是不太详细,总是不成功,然后试了很多,把经验发给大家看看 前台js function aa() { //这里可以写你要带的参数用隐藏域放起来 __doPostBac ...
- Session、SessionId和Cookie的关系
Session是保存在服务器中的,SessionId是保存在Cookie中的. 当用户·登录时候,系统会将"用户名"和"密码"保存到Session中,系统会给每 ...
- md5 加密 swfit版
在swift工程中随便建一个objective-c类,会提示你生成一个Bridging-Header,点YES,然后删除刚才建立的objective-c类,只留下[工程名]-Bridging-Head ...
- Thread interrupt方法解析
初步理解 我们在看一些多线程代码的时候,有的时候会碰到使用interrupt()方法的时候.从字面的意思来理解,应该就是中断当前正在执行的线程.那么,对于一个我们设计的普通线程来说,如果我们在主线程里 ...