• ContentProvider中的数据库的生成时机以及ContentResolver的insert()方法总结


      经过几天的总结,以及结合一些代码的实际测试,终于算是明白了ContentProvider中的数据的生成时机了。

    目录结构:

    MainActivity.java

     1 package com.wyl.contentprovidermine2;
     2 
     3 
     4 import android.app.Activity;
     5 import android.content.ContentResolver;
     6 import android.content.ContentValues;
     7 import android.os.Bundle;
     8 import android.view.View;
     9 import android.view.View.OnClickListener;
    10 import android.widget.Button;
    11 public class MainActivity extends Activity implements OnClickListener{
    12     Button btn_insert;
    13     Button btn_select;
    14     @Override
    15     protected void onCreate(Bundle savedInstanceState) {
    16         super.onCreate(savedInstanceState);
    17         setContentView(R.layout.activity_main);
    18         System.out.println("MainActivity.onCreate().....1");
    19         btn_insert = (Button) findViewById(R.id.btn_insert);
    20         btn_select = (Button) findViewById(R.id.btn_select);
    21         System.out.println("MainActivity.onCreate().....2");
    22         btn_insert.setOnClickListener(this);
    23     }
    24     @Override
    25     public void onClick(View v) {
    26         switch (v.getId()) {
    27         case R.id.btn_insert:
    28             ContentResolver cr = getContentResolver();
    29             ContentValues values = new ContentValues();
    30             values.put(MyMetaData.MyTableData.COLUMN_NAME, "wyl");
    31             values.put(MyMetaData.MyTableData.COLUMN_SEX, "男");
    32 //            values.put(MyMetaData.MyTableData.COLUMN_AGE, 24);
    33             System.out.println("111 ==================");
    34             if(cr!=null){
    35                 System.out.println("33333333333333");
    36                 cr.insert(MyMetaData.MyTableData.CONTENT_URI, values);
    37             }
    38             System.out.println("2222 ==================");
    39             break;
    40 
    41         case R.id.btn_select:
    42             System.out.println("查询数据......");
    43             break;
    44         }
    45     }
    46 }

    MyContentProvider.java

     1 package com.wyl.contentprovidermine2;
     2 
     3 
     4 import android.content.ContentProvider;
     5 import android.content.ContentValues;
     6 import android.database.Cursor;
     7 import android.database.sqlite.SQLiteDatabase;
     8 import android.net.Uri;
     9 
    10 public class MyContentProvider extends ContentProvider{
    11     MySqliteHelper helper;
    12     static{
    13         System.out.println("我就是看看到底是先执行MyContentProvider.static{},");
    14     }
    15     
    16     public MyContentProvider(){
    17         System.out.println("我是MyContentProvider()构造器,看看是否真的是自动实例化");
    18     }
    19     
    20     @Override
    21     public boolean onCreate() {
    22         System.out.println("MyContentProvider.onCreate()方法begins-----------");
    23         helper = new MySqliteHelper(getContext(), "zhangyl.db");
    24         System.out.println("下面开始真正建立数据库");
    25         SQLiteDatabase db = helper.getWritableDatabase();//建数据库
    26         System.out.println("MyContentProvider.onCreate()开始建表。。。。。。。。。。");
    27         db.execSQL(MyMetaData.MyTableData.SQL_CREATE_TABLE);//建表
    28         System.out.println("jianli le zhangyl.db");
    29         return true;
    30     }
    31 
    32     @Override
    33     public Cursor query(Uri uri, String[] projection, String selection,
    34             String[] selectionArgs, String sortOrder) {
    35         // TODO Auto-generated method stub
    36         return null;
    37     }
    38 
    39     @Override
    40     public String getType(Uri uri) {
    41         // TODO Auto-generated method stub
    42         return null;
    43     }
    44 
    45     @Override
    46     public Uri insert(Uri uri, ContentValues values) {
    47         // TODO Auto-generated method stub
    48         return null;
    49     }
    50 
    51     @Override
    52     public int delete(Uri uri, String selection, String[] selectionArgs) {
    53         // TODO Auto-generated method stub
    54         return 0;
    55     }
    56 
    57     @Override
    58     public int update(Uri uri, ContentValues values, String selection,
    59             String[] selectionArgs) {
    60         // TODO Auto-generated method stub
    61         return 0;
    62     }
    63 
    64 }

    MySqliteHelper.java

     1 package com.wyl.contentprovidermine2;
     2 
     3 import android.content.Context;
     4 import android.database.sqlite.SQLiteDatabase;
     5 import android.database.sqlite.SQLiteDatabase.CursorFactory;
     6 import android.database.sqlite.SQLiteOpenHelper;
     7 
     8 public class MySqliteHelper extends SQLiteOpenHelper{
     9     
    10     static{
    11         System.out.println("我是MySqliteHelper.static{},");
    12     }
    13     
    14     public MySqliteHelper(Context context, String name, CursorFactory factory,
    15             int version) {
    16         super(context, name, factory, version);
    17     }
    18     public MySqliteHelper(Context context, String name, 
    19             int version) {
    20         this(context, name,null, version);
    21     }
    22     /**
    23      * 用来创建数据库
    24      * @param context  activity
    25      * @param name          数据库名
    26      */
    27     public MySqliteHelper(Context context, String name) {
    28         this(context, name, 1);
    29         System.out.println("MySqliteHelper()构造器,我是来市里花的。");
    30     }
    31     
    32     /**
    33      *  这个方法主要是用来创建 表的,
    34      *  现在的疑问是 数据库是是什么时候创建的:实际上数据库是实例化该MySqliteHelper的时候
    35      *  创建,
    36      */
    37     @Override
    38     public void onCreate(SQLiteDatabase db) {
    39 //        db = getWritableDatabase();
    40         
    41         System.out.println("MySqliteHelper.onCreate()方法,这里建表");
    42         db.execSQL(MyMetaData.MyTableData.SQL_CREATE_TABLE);
    43         System.out.println("MySqliteHelper.onCreate()方法,表已经建立好");
    44     }
    45 
    46     @Override
    47     public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    48         
    49     }
    50 
    51 }

    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

     1 <?xml version="1.0" encoding="utf-8"?>
     2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     3     package="com.wyl.contentprovidermine2"
     4     android:versionCode="1"
     5     android:versionName="1.0" >
     6 
     7     <uses-sdk
     8         android:minSdkVersion="16"
     9         android:targetSdkVersion="19" />
    10 
    11     <application
    12         android:allowBackup="true"
    13         android:icon="@drawable/ic_launcher"
    14         android:label="@string/app_name"
    15         android:theme="@style/AppTheme" >
    16         <activity
    17             android:name="com.wyl.contentprovidermine2.MainActivity"
    18             android:label="@string/app_name" >
    19             <intent-filter>
    20                 <action android:name="android.intent.action.MAIN" />
    21 
    22                 <category android:name="android.intent.category.LAUNCHER" />
    23             </intent-filter>
    24         </activity>
    25 
    26         <provider
    27             android:name=".MyContentProvider"
    28             android:authorities="com.wyl.contentprovidermine2" >
    29         </provider>
    30     </application>
    31 
    32 </manifest>

    activity_main.xml:

     1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     2     xmlns:tools="http://schemas.android.com/tools"
     3     android:id="@+id/container"
     4     android:layout_width="match_parent"
     5     android:layout_height="match_parent"
     6     android:orientation="vertical"
     7     tools:context="com.wyl.contentprovidermine.MainActivity"
     8     tools:ignore="MergeRootFrame" >
     9 
    10     <Button
    11         android:id="@+id/btn_insert"
    12         android:layout_width="match_parent"
    13         android:layout_height="wrap_content"
    14         android:text="insert data" >
    15     </Button>
    16 
    17     <Button
    18         android:id="@+id/btn_select"
    19         android:layout_width="match_parent"
    20         android:layout_height="wrap_content"
    21         android:text="select data" >
    22     </Button>
    23 
    24 </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行的代码

    1 cr.insert(MyMetaData.MyTableData.CONTENT_URI, values);

    调用的是MyContentProvider.java 的insert()方法,即

    1 ContentResolver cr = getContentResolver();
    2             ContentValues values = new ContentValues();
    3             values.put(myMetaData.UserTableMetaData.NAME, "zyl");
    4             values.put(myMetaData.UserTableMetaData.AGE, 21);
    5             values.put(myMetaData.UserTableMetaData.SEX, "女");
    6             System.out.println("点了insert按钮......");
    7             cr.insert(myMetaData.UserTableMetaData.CONTENT_URI, values);//实际上调用的是myContentProvider.insert()方法

    contentResolver.insert()执行的时候,是通过调用 ContentProvider.insert()方法来实现插入数据的。因此生成数据库的时机也可以在ContentProvider的onCreate()方法里获取SqliteDataBase,下面的例子是ContentProvider的onCreate()方法,例如:

     1 @Override
     2     public Uri insert(Uri uri, ContentValues values) {
     3         System.out.println("myContentProvider.insert()......1 ");
     4         db = helper.getWritableDatabase();//在myContentProvider.insert()的方法里真正生成数据库
     5         System.out.println("myContentProvider.insert()......2 ");
     6         long rowId = db.insert(myMetaData.UserTableMetaData.TABLE_NAME, null, values);
     7         if(rowId>0){
     8             Uri rtnUri = ContentUris.withAppendedId(uri, rowId);
     9             System.out.println("myContentProvider.insert()......3 ");
    10             return rtnUri;
    11         }
    12         System.out.println("myContentProvider.insert()......4 ");
    13         return null;
    14     }

    补充的内容里的代码放在文件管理里,名称:ContentProviderMine3.rar。

    LogCat里的sysout如下:

  • 相关阅读:
    HDU2159 二维完全背包
    HDU1401 BFS
    HDU2842 矩阵乘法
    CF2.E
    CF2.D
    *HDU2254 矩阵乘法
    CF2.C
    *HDU1907 博弈
    博弈
    *HDU2147 博弈
  • 原文地址:https://www.cnblogs.com/Sunnor/p/4796244.html
Copyright © 2020-2023  润新知