ContentProvider中的数据库的生成时机以及ContentResolver的insert()方法总结
经过几天的总结,以及结合一些代码的实际测试,终于算是明白了ContentProvider中的数据的生成时机了。
目录结构:
MainActivity.java
package com.wyl.contentprovidermine2; 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);
System.out.println("MainActivity.onCreate().....1");
btn_insert = (Button) findViewById(R.id.btn_insert);
btn_select = (Button) findViewById(R.id.btn_select);
System.out.println("MainActivity.onCreate().....2");
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.MyTableData.COLUMN_NAME, "wyl");
values.put(MyMetaData.MyTableData.COLUMN_SEX, "男");
// values.put(MyMetaData.MyTableData.COLUMN_AGE, 24);
System.out.println("111 ==================");
if(cr!=null){
System.out.println("33333333333333");
cr.insert(MyMetaData.MyTableData.CONTENT_URI, values);
}
System.out.println("2222 ==================");
break; case R.id.btn_select:
System.out.println("查询数据......");
break;
}
}
}
MyContentProvider.java
package com.wyl.contentprovidermine2; import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri; public class MyContentProvider extends ContentProvider{
MySqliteHelper helper;
static{
System.out.println("我就是看看到底是先执行MyContentProvider.static{},");
} public MyContentProvider(){
System.out.println("我是MyContentProvider()构造器,看看是否真的是自动实例化");
} @Override
public boolean onCreate() {
System.out.println("MyContentProvider.onCreate()方法begins-----------");
helper = new MySqliteHelper(getContext(), "zhangyl.db");
System.out.println("下面开始真正建立数据库");
SQLiteDatabase db = helper.getWritableDatabase();//建数据库
System.out.println("MyContentProvider.onCreate()开始建表。。。。。。。。。。");
db.execSQL(MyMetaData.MyTableData.SQL_CREATE_TABLE);//建表
System.out.println("jianli le zhangyl.db");
return true;
} @Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO Auto-generated method stub
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;
} }
MySqliteHelper.java
package com.wyl.contentprovidermine2; 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("我是MySqliteHelper.static{},");
} public MySqliteHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
}
public MySqliteHelper(Context context, String name,
int version) {
this(context, name,null, version);
}
/**
* 用来创建数据库
* @param context activity
* @param name 数据库名
*/
public MySqliteHelper(Context context, String name) {
this(context, name, 1);
System.out.println("MySqliteHelper()构造器,我是来市里花的。");
} /**
* 这个方法主要是用来创建 表的,
* 现在的疑问是 数据库是是什么时候创建的:实际上数据库是实例化该MySqliteHelper的时候
* 创建,
*/
@Override
public void onCreate(SQLiteDatabase db) {
// db = getWritableDatabase(); System.out.println("MySqliteHelper.onCreate()方法,这里建表");
db.execSQL(MyMetaData.MyTableData.SQL_CREATE_TABLE);
System.out.println("MySqliteHelper.onCreate()方法,表已经建立好");
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
MyMetaData.java
package com.wyl.contentprovidermine2; import android.net.Uri;
import android.provider.BaseColumns; public class MyMetaData {
public static final String AUTHORITY = "com.wyl.contentprovidermine2";
public static final class MyTableData implements BaseColumns{
// 1.相当于http 2.provider所在的包名 3.表名
public static final Uri CONTENT_URI = Uri.parse("content://"+AUTHORITY+"/yonghu"); public static final String TABLE_NAME = "yonghu";
public static final String COLUMN_NAME = "name";
public static final String COLUMN_SEX = "sex";
public static final String COLUMN_AGE = "age";
public static final String COLUMN_SORT = "_id desc";
//create table if not exists yonghu (_id integer primary key autoincrement,name text not null,sex text not null,age integer not null);
public static final String SQL_CREATE_TABLE = "create table if not exists "+TABLE_NAME+" (_id integer primary key autoincrement,"+COLUMN_NAME+" text not null,"+COLUMN_SEX+" text not null, "+COLUMN_AGE+" integer not null)";
public static final String SQL_CREATE_TABLE2 = "create table if not exists "+TABLE_NAME+" (_id integer primary key autoincrement,"+COLUMN_NAME+" text not null,"+COLUMN_SEX+" text not null, "+COLUMN_AGE+" integer not null)"; }
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.wyl.contentprovidermine2"
android:versionCode="1"
android:versionName="1.0" > <uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="19" /> <application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.wyl.contentprovidermine2.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <provider
android:name=".MyContentProvider"
android:authorities="com.wyl.contentprovidermine2" >
</provider>
</application> </manifest>
activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.wyl.contentprovidermine.MainActivity"
tools:ignore="MergeRootFrame" > <Button
android:id="@+id/btn_insert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="insert data" >
</Button> <Button
android:id="@+id/btn_select"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="select data" >
</Button> </LinearLayout>
总结:
含有ContentProvider
组件的app安装的时候的执行顺序,
安装的时候,系统就会自动实例化继承了ContentProvider类的类(我这里使用的是MyContentProvider 这个类继承了ContentProvider),这一步是系统自动实例化(这是我的理解,用代码测试出的这个结论)
实例化MyContentProvider,当然会遵循实例化的顺序,即
a 先执行MyContentProvider内的static{},即静态代码块,
b 然后{},即普通代码块,
c 然后才生成MyContentProvider对象,即执行构造器内的代码
d 这个时候才真正自动执行MyContentProvider里的onCreate()方法,
结合本例子中的时机代码,执行上面onCreate()方法的整个过程中实际上又可以分为以下几个过程,具体如下,
其中 1 对应着:实例化MySqliteHelper(),至于静态代码等的执行顺序类同于上面的abcd四个步骤。不细说。刚开始我以为实例化MySqliteHelper这个类的时候,就会建立数据库,其实不然。而是到了上图中的第二个步骤的时候才真正创建数据库,即调用了helper的getWritableDatabase()方法的时候才会真正创建数据库。实际上调用helper.getReadableDatabase()也同样会真正创建数据库。
其中2对应着: 这个时候真正的创建数据库,1中已经讲了。
其中3对应着:真正创建表,这个很简单没必要讲。
20150910补充:
实际上上面MainActivity.java 36行的代码
cr.insert(MyMetaData.MyTableData.CONTENT_URI, values);
调用的是MyContentProvider.java 的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, "女");
System.out.println("点了insert按钮......");
cr.insert(myMetaData.UserTableMetaData.CONTENT_URI, values);//实际上调用的是myContentProvider.insert()方法
contentResolver.insert()执行的时候,是通过调用 ContentProvider.insert()方法来实现插入数据的。因此生成数据库的时机也可以在ContentProvider的onCreate()方法里获取SqliteDataBase,下面的例子是ContentProvider的onCreate()方法,例如:
@Override
public Uri insert(Uri uri, ContentValues values) {
System.out.println("myContentProvider.insert()......1 ");
db = helper.getWritableDatabase();//在myContentProvider.insert()的方法里真正生成数据库
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;
}
补充的内容里的代码放在文件管理里,名称:ContentProviderMine3.rar。
LogCat里的sysout如下:
ContentProvider中的数据库的生成时机以及ContentResolver的insert()方法总结的更多相关文章
- 用C#从数据库动态生成AdminLTE菜单的一种方法
当前的应用设计风格趋于Flat扁平化,很多基于BootStrap实现了很多UI非常漂亮的管理界面(Bootstrap admin template). 此核心文件开源在Github:https://g ...
- springboot 中根据数据库表生成所有表的model,mapper和xml文件
参考文件:https://blog.csdn.net/shenmoren6/article/details/80337662?utm_source=blogxgwz1 详细信息:https://blo ...
- Delphi中根据分类数据生成树形结构的最优方法
一. 引言: TreeView控件适合于表示具有多层次关系的数据.它以简洁的界面,表现形式清晰.形象,操作简单而深受用户喜爱.而且用它可以实现ListView.ListBox所无法实现的很多功能 ...
- ContentProvider中的数据生成时机
目录结构: , 先给个结论: 仅仅是实例化mySqliteHelper()这个类的时候是不会创建数据库的,实际上数据库的真正创建是在helper.getWritableDatabase()的方法执行后 ...
- 在MVC3中使用code first生成数据局库并操作数据库
1.建立Users和UserInfos两个实体类 对应的是数据库中的表 public class User { //类名+Id(User+Id)组成的字符串在数据库表中会设置该字段是主键且是按1的增量 ...
- EF Core 2.0中怎么用DB First通过数据库来生成实体
要在EF Core使用DB First首先要下载三个Nuget包,在Nuget的Package Manager Console窗口中依次敲入下面三个命令即可: Microsoft.EntityFram ...
- (3)PyCharm中Flask工程逆向生成数据库表
一.创建数据库 在mysql数据库中创建名为"movie"的数据库. 二.安装SQLAlchemy 三.安装PyMySQL 四.创建数据模型 在app/models.py中编写数据 ...
- eclipse中从数据库生成hibernate实体类
为什么写这篇BLOG,是因为经常有同事或网友问起我hiberante实体类的生成问题.所以下次再有人问我可以省一堆的话了,其实这个真的是很简单. 现在hibernate在项目中的应用是越 ...
- SQL C# nvarchar类型转换为int类型 多表查询的问题,查询结果到新表,TXT数据读取到控件和数据库,生成在控件中的数据如何存到TXT文件中
在数据库时候我设计了学生的分数为nvarchar(50),是为了在从TXT文件中读取数据插入到数据库表时候方便,但是在后期由于涉及到统计问题,比如求平均值等,需要int类型才可以,方法是:Conver ...
随机推荐
- Android 开发笔记 “Sqlite Cursor 使用”
使用过 SQLite 数据库的童鞋对 Cursor 应该不陌生,如果你是搞.net 开发你大可以把Cursor理解成 Ado.net 中的数据集合相当于dataReader.今天特地将它单独拿出来谈, ...
- CDOJ 1259 昊昊爱运动 II bitset+线段树
题目链接 昊昊喜欢运动 他N天内会参加M种运动(每种运动用一个[1,m]的整数表示) 现在有Q个操作,操作描述如下 昊昊把第l天到第r天的运动全部换成了x(x∈[1,m]) 问昊昊第l天到第r天参加了 ...
- 07-C语言流程控制if、switch
目录: 一.流程控制 条件分支 if else 二.流程控制 开关分支 switch 回到顶部 一.流程控制 条件分支 1.语法格式:if(表达式1){ //表达式1为真(非0时),执行的语句部分. ...
- eclipse设置web项目发布到tomcat根目录下
如果已经将项目绑定到服务器了,那就先删除服务器. 重新添加项目进服务器,双击 修改下面Server Locations到tomcat目录下 顺带可以修改下右上角的超时设置 再点击下方 这样就可以了.
- 【转】C++ stringstream介绍,使用方法与例子
原文来自:http://www.cnblogs.com/lancidie/archive/2010/12/03/1895161.html C++引入了ostringstream.istringstre ...
- JetBrains IntelliJ IDEA for Mac 15.0 破解版 – Mac 上强大的 Java 集成开发工具
应网友要求更新. IntelliJ IDEA 是最强大的 Java IDE 之一,由知名的Jetbrainsg公司出品,最新版本增加了大量强大易用的特性,比如 Java 8 的Lambda 表达式调试 ...
- perl5 第十一章 文件系统
第十一章 文件系统 by flamephoenix 一.文件输入/输出函数 1.基本I/O函数 1)open函数 2)用open重定向输入 3)文件重定向 4)指定读写权限 ...
- HDU 3398 String
题目大意:一个长为n的01字符串,使前缀任意0的数量不大于1的数量,求方案数…… 题解:高一模拟赛时做过,是卡特兰数的几何意义,将字符串变为矩阵寻路,不可越过对角线,那么就是卡特兰数了,C(n+m, ...
- Mysql5.6.24 zip解压缩版配置及修改默认编码方法
win64位下载地址: http://dev.mysql.com/downloads/file.php?id=456319 下载完毕后解压 配置环境变量 在Path后加上mysql解压后bin文件夹所 ...
- 淘特房产CMS系统 7.5
资源描写叙述: 淘特房产CMS系统採用淘特AspCms开发,全部前台信息生成静态HTM,提供了楼盘.二手房.房产中介.房产经济人.业主社区等管理模块,集成了淘特CMS与动网论坛,Discuz,Oblo ...