zoukankan      html  css  js  c++  java
  • 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如下:

  • 相关阅读:
    deeplearning.ai 卷积神经网络 Week 1 卷积神经网络
    deeplearning.ai 构建机器学习项目 Week 2 机器学习策略 II
    deeplearning.ai 构建机器学习项目 Week 1 机器学习策略 I
    deeplearning.ai 改善深层神经网络 week3 超参数调试、Batch Normalization和程序框架
    deeplearning.ai 改善深层神经网络 week2 优化算法
    deeplearning.ai 改善深层神经网络 week1 深度学习的实用层面
    cs231n spring 2017 lecture8 Deep Learning Networks
    cs231n spring 2017 lecture7 Training Neural Networks II
    cs231n spring 2017 lecture6 Training Neural Networks I
    cs231n spring 2017 Python/Numpy基础
  • 原文地址:https://www.cnblogs.com/Sunnor/p/4796244.html
Copyright © 2011-2022 走看看