ContentProvider中的数据库的生成时机以及ContentResolver的insert()方法总结
2015-09-09 22:48
609 查看
经过几天的总结,以及结合一些代码的实际测试,终于算是明白了ContentProvider中的数据的生成时机了。
目录结构:
![](http://images2015.cnblogs.com/blog/627552/201509/627552-20150909224124419-1544055836.png)
![](http://images2015.cnblogs.com/blog/627552/201509/627552-20150909224559622-1045152247.png)
MainActivity.java
MyContentProvider.java
MySqliteHelper.java
MyMetaData.java
AndroidManifest.xml
activity_main.xml:
![](http://images2015.cnblogs.com/blog/627552/201509/627552-20150909224710044-730141702.png)
总结:
含有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行的代码
调用的是MyContentProvider.java 的insert()方法,即
contentResolver.insert()执行的时候,是通过调用 ContentProvider.insert()方法来实现插入数据的。因此生成数据库的时机也可以在ContentProvider的onCreate()方法里获取SqliteDataBase,下面的例子是ContentProvider的onCreate()方法,例如:
补充的内容里的代码放在文件管理里,名称:ContentProviderMine3.rar。
LogCat里的sysout如下:
目录结构:
![](http://images2015.cnblogs.com/blog/627552/201509/627552-20150909224124419-1544055836.png)
![](http://images2015.cnblogs.com/blog/627552/201509/627552-20150909224559622-1045152247.png)
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>
![](http://images2015.cnblogs.com/blog/627552/201509/627552-20150909224710044-730141702.png)
总结:
含有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如下:
![](http://images2015.cnblogs.com/blog/627552/201509/627552-20150910111537278-489267529.png)
相关文章推荐
- 对数据库管理员和数据库用户的认识
- mysql简单的单表查询详解
- 对数据库语言的简单认识
- 对数据库中数据库系统的结构的认识
- 黑马程序员_Oracle 数据库分页功能原理
- Redis学习2之redis-benchmark使用方法总结
- sqlite的优缺点
- 数据库
- 学习MySQL之数据类型(四)
- MySQL多表查询之外键、表连接、子查询、索引
- MySQL多表查询之外键、表连接、子查询、索引
- MySQL字符串函数、日期时间函数
- MySQL字符串函数、日期时间函数
- mysql_proxy实现读写分离
- JDBC增删改数据库的操作
- JDBC增删改数据库的操作
- 用sql语句写排名
- 开源工具DbUtils的使用(数据库的增删改查)
- 开源工具DbUtils的使用(数据库的增删改查)
- DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)