关于 SQLiteOpenHelper 的自创建数据库目录文件

来源:互联网 发布:电子书阅读器 知乎 编辑:程序博客网 时间:2024/06/05 15:27
在 android 中有个类可方便的直接创建数据库,自己写一个类继承 SQLiteOpenHelper
package com.wangban.yzbbanban.test_mysqlite;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;import android.widget.Toast;/** * Created by YZBbanban on 16/7/27. */public class MySQLiteHelper extends SQLiteOpenHelper {    private Context context;    public MySQLiteHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {        super(context, name, factory, version);        this.context = context;    }    @Override    public void onCreate(SQLiteDatabase sqLiteDatabase) {        sqLiteDatabase.execSQL("create table Book(id integer primary key autoincrement,name text,price real)");        Toast.makeText(context, "创建完成", Toast.LENGTH_SHORT).show();    }    @Override    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {    }}

代码很简单,传入一个 Context(此 Context 很重要),创建一个对象,传入参数:上下文对象,数据库文件名,游标工厂(一般不用,为 null),数据库版本号(可自定义),

重写 onCreate 的方法,方法的参数即为数据库引用,可用此引用创建数据库中的表单:exeSQL()方法创建表单数据,创建成功,Toast 提示一下,onUpgrade 表示,若版本号与之前的老版本号不一致,则执行此方法(在此不需要用)。至此一个 MySQLiteHelper类完成,用于创建数据库文件,以及表单。

现在进入正题,之前提到过构造方法的一个传入值Context,我们可以在源码中找到一个这样的类:ContextWrapper (继承自 Context)通过此类我们可以获得应用程序的资源和类,包括对Activity,Broadcast,Intent等的操做,比如 startActivity(),sendBroadcast()等,还有些设置方法,像是setWallpaper(),当然最主要是有关于数据存储的一切方法:文件存储(File),个性化存储(sharedPreferances),数据库 (SQLite)等,对于数据库的操作直接看源码:

  public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {        throw new RuntimeException("Stub!");    }    public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory, DatabaseErrorHandler errorHandler) {        throw new RuntimeException("Stub!");    }    public boolean moveDatabaseFrom(Context sourceContext, String name) {        throw new RuntimeException("Stub!");    }    public boolean deleteDatabase(String name) {        throw new RuntimeException("Stub!");    }    public File getDatabasePath(String name) {        throw new RuntimeException("Stub!");    }    public String[] databaseList() {        throw new RuntimeException("Stub!");    }

构造方法:

public class ContextWrapper extends Context {    public ContextWrapper(Context base) {        throw new RuntimeException("Stub!");    }

可以知道构造方法只有一个参数 Context,而且,在 SQLiteOpenHelper 中传入的 Context,也是在此调用的,其中的具体方法被SDK 隐藏了,所以看不到,只有抛出异常,但是可以了解到:所以在创建数据库时需要传入一个参数:Context, 其中getDatabasePath() 为创建数据库路径,OpenOrCreateDatebase ()为创建数据库,所以也可以确认的是,在 SQLiteOpenHelper 中的子类,调用getReadableDatabase()生成数据库文件表单时也调用了OpenOrCreateDatebase (),同样传入参数也是 Context,(只是默认路径在该程序的数据库文件夹里(data/data/~~)),所以我们只要重写了 ContextWrapper 方法,并重写其中的 OpenCreateDatebase(),与 getDatabasePath()方法即可创建所需要的数据库目录与数据库表单,下面是代码:
package com.wangban.yzbbanban.test_mysqlite;import android.content.Context;import android.content.ContextWrapper;import android.database.DatabaseErrorHandler;import android.database.sqlite.SQLiteDatabase;import android.util.Log;import java.io.File;import java.io.IOException;/** * Created by YZBbanban on 16/7/27. */public class MyContextWrapper extends ContextWrapper {    private Context mContext;    private String dirName;    /**     * 构造函数     *     * @param base     *上下文环境     */    public MyContextWrapper(Context base) {        super(base);        this.mContext = base;    }    /**     * 构造函数     * @param base     * @param dirName     */    public MyContextWrapper(Context base, String dirName) {        super(base);        this.mContext = base;        this.dirName = dirName;    }    /**     * 获得数据库路径,如果不存在,则创建对象对象     *     * @param name     */    @Override    public File getDatabasePath(String name) {        // 判断是否存在sd卡        boolean sdExist = android.os.Environment.MEDIA_MOUNTED                .equals(android.os.Environment.getExternalStorageState());        if (!sdExist) {// 如果不存在,            Log.e("SD卡管理:", "SD卡不存在,请加载SD卡");            return null;        } else {// 如果存在            // 获取sd卡路径            String dbDir = android.os.Environment.getExternalStorageDirectory()                    .getAbsolutePath();            dbDir += "/" + ((dirName == null || "".equals(dirName)) ?                    mContext.getPackageName() : dirName);// 数据库所在目录            String dbPath = dbDir + "/" + name;// 数据库路径            // 判断目录是否存在,不存在则创建该目录            File dirFile = new File(dbDir);            if (!dirFile.exists())                dirFile.mkdirs();            // 数据库文件是否创建成功            boolean isFileCreateSuccess = false;            // 判断文件是否存在,不存在则创建该文件            File dbFile = new File(dbPath);            if (!dbFile.exists()) {                try {                    isFileCreateSuccess = dbFile.createNewFile();// 创建文件                } catch (IOException e) {                    // TODO Auto-generated catch block                    e.printStackTrace();                }            } else                isFileCreateSuccess = true;            // 返回数据库文件对象            if (isFileCreateSuccess)                return dbFile;            else                return null;        }    }    /**     * 重载这个方法,是用来打开SD卡上的数据库的,android 2.3及以下会调用这个方法。     *     * @param name     * @param mode     * @param factory     */    @Override    public SQLiteDatabase openOrCreateDatabase(String name, int mode,                                               SQLiteDatabase.CursorFactory factory) {        SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(                getDatabasePath(name), null);        return result;    }    /**     * Android 4.0会调用此方法获取数据库。     *     * @see android.content.ContextWrapper#openOrCreateDatabase(java.lang.String,     *  int, android.database.sqlite.SQLiteDatabase.CursorFactory,     *  android.database.DatabaseErrorHandler)     * @param name     * @param mode     * @param factory     * @param errorHandler     */    @Override    public SQLiteDatabase openOrCreateDatabase(String name, int mode,                                               SQLiteDatabase.CursorFactory factory, DatabaseErrorHandler errorHandler) {        SQLiteDatabase result = SQLiteDatabase.openOrCreateDatabase(                getDatabasePath(name), null);        return result;    }}
在 Activity 中创建 MySQLiteHelper()对象,并使用新的 Context 对象传入MySQLiteHelper的 onCreate() 方法中即可,下面是 Activity 代码:
package com.wangban.yzbbanban.test_mysqlite;import android.database.sqlite.SQLiteDatabase;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.view.View;import android.widget.Button;public class MainActivity extends AppCompatActivity {    private Button btnCreate;    private MySQLiteHelper helper;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        btnCreate = (Button) findViewById(R.id.btn_create);        MyContextWrapper mContext = new MyContextWrapper(this, "Run");        helper = new MySQLiteHelper(mContext, "Book.db", null, 2);        setListeners();    }    private void setListeners() {        btnCreate.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View view) {                SQLiteDatabase db = helper.getWritableDatabase();            }        });    }}
布局文件:

<?xml version="1.0" encoding="utf-8"?><android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.wangban.yzbbanban.test_mysqlite.MainActivity">    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="Hello World!"        app:layout_constraintLeft_toLeftOf="@+id/activity_main"        app:layout_constraintTop_toTopOf="@+id/activity_main"        app:layout_constraintRight_toRightOf="@+id/activity_main"        app:layout_constraintBottom_toBottomOf="@+id/activity_main" />    <Button        android:text="创建"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/btn_create"        app:layout_constraintLeft_toLeftOf="@+id/activity_main"        android:layout_marginLeft="16dp"        android:layout_marginStart="16dp"        app:layout_constraintTop_toTopOf="@+id/activity_main"        android:layout_marginTop="16dp"        app:layout_constraintRight_toRightOf="@+id/activity_main"        android:layout_marginRight="16dp"        android:layout_marginEnd="16dp" /></android.support.constraint.ConstraintLayout>


0 0
原创粉丝点击