1

我的 DBHelper 类是一个资产数据库。我在写它时遇到问题没有这样的文件或目录资产我有名为 dbm.db 的特定于打印机的文件(这是数据库)这是类:

package com.example.dbt7;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
public class AssetDatabaseOpenHelper {
    private static final String DB_NAME = "dbm.db";
    private Context context;
    public AssetDatabaseOpenHelper(Context context) {
        this.context = context;
    }
    public SQLiteDatabase openDatabase() {
        File dbFile = context.getDatabasePath(DB_NAME);
        if (!dbFile.exists()) {
           try {
                copyDatabase(dbFile);
            } catch (IOException e) {
                throw new RuntimeException("Error creating source database", e);
            }
        }
        return SQLiteDatabase.openDatabase(dbFile.getPath(), null, SQLiteDatabase.OPEN_READONLY);
    }
    private void copyDatabase(File dbFile) throws IOException {
        InputStream is = context.getAssets().open(DB_NAME);
        OutputStream os = new FileOutputStream(dbFile);

        byte[] buffer = new byte[1024];
        while (is.read(buffer) > 0) {
            os.write(buffer);
        }

        os.flush();
        os.close();
        is.close();
    } 
}

好的,它不报告任何错误...

现在当我想在这个活动中打开时出现问题现在当我转动它时它会掉下来

   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);



      AssetDatabaseOpenHelper otevreno = new AssetDatabaseOpenHelper(this);
      otevreno.openDatabase();
   }

它抛出的这个问题

07-01 01:25:15.517: E/AndroidRuntime(32039): FATAL EXCEPTION: main
07-01 01:25:15.517: E/AndroidRuntime(32039): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.dbt7/com.example.dbt7.MainActivity}: java.lang.RuntimeException: Error creating source database
07-01 01:25:15.517: E/AndroidRuntime(32039):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at android.app.ActivityThread.access$2300(ActivityThread.java:125)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at android.os.Handler.dispatchMessage(Handler.java:99)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at android.os.Looper.loop(Looper.java:123)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at android.app.ActivityThread.main(ActivityThread.java:4627)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at java.lang.reflect.Method.invokeNative(Native Method)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at java.lang.reflect.Method.invoke(Method.java:521)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at dalvik.system.NativeStart.main(Native Method)
07-01 01:25:15.517: E/AndroidRuntime(32039): Caused by: java.lang.RuntimeException: Error creating source database
07-01 01:25:15.517: E/AndroidRuntime(32039):    at com.example.dbt7.AssetDatabaseOpenHelper.openDatabase(AssetDatabaseOpenHelper.java:29)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at com.example.dbt7.MainActivity.onCreate(MainActivity.java:17)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
07-01 01:25:15.517: E/AndroidRuntime(32039):    ... 11 more
07-01 01:25:15.517: E/AndroidRuntime(32039): Caused by: java.io.FileNotFoundException: /data/data/com.example.dbt7/databases/dbm.db (No such file or directory)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at org.apache.harmony.luni.platform.OSFileSystem.openImpl(Native Method)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at org.apache.harmony.luni.platform.OSFileSystem.open(OSFileSystem.java:152)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at java.io.FileOutputStream.<init>(FileOutputStream.java:97)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at java.io.FileOutputStream.<init>(FileOutputStream.java:69)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at com.example.dbt7.AssetDatabaseOpenHelper.copyDatabase(AssetDatabaseOpenHelper.java:38)
07-01 01:25:15.517: E/AndroidRuntime(32039):    at com.example.dbt7.AssetDatabaseOpenHelper.openDatabase(AssetDatabaseOpenHelper.java:27)
07-01 01:25:15.517: E/AndroidRuntime(32039):    ... 14 more

问题出在哪里?我没有坏 DB_NAME?当我有一个 db jmenom dbm 时会发生什么。资产中的数据库?

4

1 回答 1

2

AssetDatabaseOpenHelper的构造不正确!如果你打算使用这个类来管理应用程序中数据库的所有进程,你应该以另一种方式构建它。这是一个如何从资产文件夹初始化数据库并在整个应用程序中使用它的示例:

public class AssetDatabaseOpenHelper extends SQLiteOpenHelper {

    // DATABASE
    private static SQLiteDatabase mSqliteDb;
    private static AssetDatabaseOpenHelper mInstance;
    public static final int DATABASE_VERSION = 1;
    private static final String DB_PATH_SUFFIX = "/databases/";
    private static final String DATABASE_NAME = "your.db";
    private static Context mContext;

    public AssetDatabaseOpenHelper(Context context, CursorFactory factory, int version) {
        super(context, DATABASE_NAME, factory, version);
        mContext = context;
    }

    public void initialise() {
        if (mInstance == null) {
            if (!checkDatabase()) {
                copyDataBase();
            }
            mInstance = new AssetDatabaseOpenHelper(mContext, null, DATABASE_VERSION);
            mSqliteDb = mInstance.getWritableDatabase();
        }
    }

    public AssetDatabaseOpenHelper getInstance(){
        return mInstance;
    }

    public SQLiteDatabase getDatabase() {
        return mSqliteDb;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    private static void copyDataBase() {

        try {
            // Open your local db as the input stream
            InputStream myInput = mContext.getAssets().open(DATABASE_NAME);

            // Path to the just created empty db
            String outFileName = getDatabasePath(mContext);

            // if the path doesn't exist first, create it
            File f = new File(mContext.getApplicationInfo().dataDir + DB_PATH_SUFFIX);
            if (!f.exists())
                f.mkdir();

            // Open the empty db as the output stream
            OutputStream myOutput = new FileOutputStream(outFileName);

            // transfer bytes from the inputfile to the outputfile
            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }

            // Close the streams
            myOutput.flush();
            myOutput.close();
            myInput.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static boolean checkDatabase() {
        SQLiteDatabase checkDB = null;

        try {
            try {
                String myPath = getDatabasePath();
                checkDB = SQLiteDatabase.openDatabase(myPath, null,
                        SQLiteDatabase.OPEN_READONLY);
                checkDB.close();
            } catch (Exception e) { }
        } catch (Throwable ex) {
        }
        return checkDB != null ? true : false;
    }

    private static String getDatabasePath() {
        return mContext.getApplicationInfo().dataDir + DB_PATH_SUFFIX
                + DATABASE_NAME;
    }

}

在您的 MainActivity 中,您应该像这样初始化数据库:

AssetDatabaseOpenHelper mDbHelper = new AssetDatabaseOpenHelper(this, null, 1);
mDbHelper.initialise();
于 2013-07-01T10:26:22.890 回答