문제

애플리케이션에 데이터베이스가 필요하고 데이터가 내장되어 있는 경우 해당 애플리케이션을 제공하는 가장 좋은 방법은 무엇입니까?내가해야합니까:

  1. SQLite 데이터베이스를 미리 생성하고 이를 .apk?

  2. 애플리케이션에 SQL 명령을 포함시키고 처음 사용할 때 데이터베이스를 생성하고 데이터를 삽입하도록 하시겠습니까?

제가 보는 단점은 다음과 같습니다.

  1. 가능한 SQLite 버전 불일치로 인해 문제가 발생할 수 있으며 현재 데이터베이스가 어디로 이동해야 하는지, 어떻게 액세스해야 하는지 모르겠습니다.

  2. 장치에서 데이터베이스를 생성하고 채우는 데는 정말 오랜 시간이 걸릴 수 있습니다.

어떤 제안이 있으십니까?모든 문제에 관한 문서에 대한 조언을 주시면 감사하겠습니다.

도움이 되었습니까?

해결책

방금이 작업을 수행하는 방법을 찾았습니다 ReignDesign blog 제목의 기사에서 Android 애플리케이션에서 자신의 SQLITE 데이터베이스 사용. 기본적으로 귀하는 데이터베이스를 사전에 대고 APK의 자산 디렉토리에 넣고 먼저 사본을 사용합니다. /data/data/YOUR_PACKAGE/databases/ 예배 규칙서.

다른 팁

데이터베이스를 작성하고 업데이트하는 두 가지 옵션이 있습니다.

하나는 데이터베이스를 외부로 만들고 프로젝트의 자산 폴더에 배치 한 다음 전체 데이터베이스를 거기에서 복사하는 것입니다. 데이터베이스에 테이블 및 기타 구성 요소가 많으면 훨씬 빠릅니다. RES/values/strings.xml 파일에서 데이터베이스 버전 번호를 변경하여 업그레이드가 트리거됩니다. 그런 다음 새로운 데이터베이스를 외부 적으로 만들어 자산 폴더의 이전 데이터베이스를 새 데이터베이스로 바꾸고 다른 이름으로 내부 스토리지의 이전 데이터베이스를 저장하여 자산 폴더에서 내부 스토리지로 복사하여 모든 업그레이드를 수행하여 업그레이드가 수행됩니다. 이전 데이터베이스의 데이터 (앞에서 이름이 바뀌 었음)의 데이터 중 새 데이터베이스로, 마지막으로 이전 데이터베이스를 삭제합니다. 원래 사용하여 데이터베이스를 만들 수 있습니다 SQLITE 관리자 Firefox 플러그인 생성 SQL 문을 실행합니다.

다른 옵션은 SQL 파일에서 내부적으로 데이터베이스를 만드는 것입니다. 이것은 빠르지 않지만 데이터베이스에 테이블이 몇 개 밖에 없으면 지연이 사용자에게 눈에 띄지 않을 것입니다. RES/values/strings.xml 파일에서 데이터베이스 버전 번호를 변경하여 업그레이드가 트리거됩니다. 그런 다음 업그레이드 SQL 파일을 처리하여 업그레이드를 수행합니다. 컨테이너가 제거 된 경우를 제외하고 데이터베이스의 데이터는 변경되지 않습니다 (예 : 테이블을 떨어 뜨리는 것).

아래의 예는 두 방법을 사용하는 방법을 보여줍니다.

다음은 샘플 create_database.sql 파일입니다. 내부 방법에 대한 프로젝트의 자산 폴더에 배치되거나 외부 메소드의 데이터베이스를 작성하기 위해 SQLITE Manager의 "SQL 실행"에 복사해야합니다. (참고 : Android가 요구하는 테이블에 대한 의견에 주목하십시오.)

--Android requires a table named 'android_metadata' with a 'locale' column
CREATE TABLE "android_metadata" ("locale" TEXT DEFAULT 'en_US');
INSERT INTO "android_metadata" VALUES ('en_US');

CREATE TABLE "kitchen_table";
CREATE TABLE "coffee_table";
CREATE TABLE "pool_table";
CREATE TABLE "dining_room_table";
CREATE TABLE "card_table"; 

다음은 샘플 update_database.sql 파일입니다. 내부 방법에 대한 프로젝트의 자산 폴더에 배치되거나 외부 메소드의 데이터베이스를 작성하기 위해 SQLITE Manager의 "SQL 실행"에 복사해야합니다. (참고 :이 예에 포함 된 SQL 파서에 의해 세 가지 유형의 SQL 주석을 모두 무시할 것입니다.)

--CREATE TABLE "kitchen_table";  This is one type of comment in sql.  It is ignored by parseSql.
/*
 * CREATE TABLE "coffee_table"; This is a second type of comment in sql.  It is ignored by parseSql.
 */
{
CREATE TABLE "pool_table";  This is a third type of comment in sql.  It is ignored by parseSql.
}
/* CREATE TABLE "dining_room_table"; This is a second type of comment in sql.  It is ignored by parseSql. */
{ CREATE TABLE "card_table"; This is a third type of comment in sql.  It is ignored by parseSql. }

--DROP TABLE "picnic_table"; Uncomment this if picnic table was previously created and now is being replaced.
CREATE TABLE "picnic_table" ("plates" TEXT);
INSERT INTO "picnic_table" VALUES ('paper');

다음은 데이터베이스 버전 번호에 대한 ress/values/strings.xml 파일에 추가 할 항목입니다.

<item type="string" name="databaseVersion" format="integer">1</item>

다음은 데이터베이스에 액세스 한 다음 사용하는 활동입니다. (참고 : 많은 리소스를 사용하는 경우 데이터베이스 코드를 별도의 스레드로 실행할 수 있습니다.)

package android.example;

import android.app.Activity;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;

/**
 * @author Danny Remington - MacroSolve
 * 
 *         Activity for demonstrating how to use a sqlite database.
 */
public class Database extends Activity {
     /** Called when the activity is first created. */
     @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        DatabaseHelper myDbHelper;
        SQLiteDatabase myDb = null;

        myDbHelper = new DatabaseHelper(this);
        /*
         * Database must be initialized before it can be used. This will ensure
         * that the database exists and is the current version.
         */
         myDbHelper.initializeDataBase();

         try {
            // A reference to the database can be obtained after initialization.
            myDb = myDbHelper.getWritableDatabase();
            /*
             * Place code to use database here.
             */
         } catch (Exception ex) {
            ex.printStackTrace();
         } finally {
            try {
                myDbHelper.close();
            } catch (Exception ex) {
                ex.printStackTrace();
            } finally {
                myDb.close();
            }
        }

    }
}

다음은 필요한 경우 데이터베이스가 생성되거나 업데이트되는 데이터베이스 헬퍼 클래스입니다. (참고 : Android는 SQLITE 데이터베이스와 함께 작업하기 위해 SQLITEOPENHELPER를 확장하는 클래스를 만들어야합니다.)

package android.example;

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;
import android.database.sqlite.SQLiteOpenHelper;

/**
 * @author Danny Remington - MacroSolve
 * 
 *         Helper class for sqlite database.
 */
public class DatabaseHelper extends SQLiteOpenHelper {

    /*
     * The Android's default system path of the application database in internal
     * storage. The package of the application is part of the path of the
     * directory.
     */
    private static String DB_DIR = "/data/data/android.example/databases/";
    private static String DB_NAME = "database.sqlite";
    private static String DB_PATH = DB_DIR + DB_NAME;
    private static String OLD_DB_PATH = DB_DIR + "old_" + DB_NAME;

    private final Context myContext;

    private boolean createDatabase = false;
    private boolean upgradeDatabase = false;

    /**
     * Constructor Takes and keeps a reference of the passed context in order to
     * access to the application assets and resources.
     * 
     * @param context
     */
    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, context.getResources().getInteger(
                R.string.databaseVersion));
        myContext = context;
        // Get the path of the database that is based on the context.
        DB_PATH = myContext.getDatabasePath(DB_NAME).getAbsolutePath();
    }

    /**
     * Upgrade the database in internal storage if it exists but is not current. 
     * Create a new empty database in internal storage if it does not exist.
     */
    public void initializeDataBase() {
        /*
         * Creates or updates the database in internal storage if it is needed
         * before opening the database. In all cases opening the database copies
         * the database in internal storage to the cache.
         */
        getWritableDatabase();

        if (createDatabase) {
            /*
             * If the database is created by the copy method, then the creation
             * code needs to go here. This method consists of copying the new
             * database from assets into internal storage and then caching it.
             */
            try {
                /*
                 * Write over the empty data that was created in internal
                 * storage with the one in assets and then cache it.
                 */
                copyDataBase();
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        } else if (upgradeDatabase) {
            /*
             * If the database is upgraded by the copy and reload method, then
             * the upgrade code needs to go here. This method consists of
             * renaming the old database in internal storage, create an empty
             * new database in internal storage, copying the database from
             * assets to the new database in internal storage, caching the new
             * database from internal storage, loading the data from the old
             * database into the new database in the cache and then deleting the
             * old database from internal storage.
             */
            try {
                FileHelper.copyFile(DB_PATH, OLD_DB_PATH);
                copyDataBase();
                SQLiteDatabase old_db = SQLiteDatabase.openDatabase(OLD_DB_PATH, null, SQLiteDatabase.OPEN_READWRITE);
                SQLiteDatabase new_db = SQLiteDatabase.openDatabase(DB_PATH,null, SQLiteDatabase.OPEN_READWRITE);
                /*
                 * Add code to load data into the new database from the old
                 * database and then delete the old database from internal
                 * storage after all data has been transferred.
                 */
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        }

    }

    /**
     * Copies your database from your local assets-folder to the just created
     * empty database in the system folder, from where it can be accessed and
     * handled. This is done by transfering bytestream.
     * */
    private void copyDataBase() throws IOException {
        /*
         * Close SQLiteOpenHelper so it will commit the created empty database
         * to internal storage.
         */
        close();

        /*
         * Open the database in the assets folder as the input stream.
         */
        InputStream myInput = myContext.getAssets().open(DB_NAME);

        /*
         * Open the empty db in interal storage as the output stream.
         */
        OutputStream myOutput = new FileOutputStream(DB_PATH);

        /*
         * Copy over the empty db in internal storage with the database in the
         * assets folder.
         */
        FileHelper.copyFile(myInput, myOutput);

        /*
         * Access the copied database so SQLiteHelper will cache it and mark it
         * as created.
         */
        getWritableDatabase().close();
    }

    /*
     * This is where the creation of tables and the initial population of the
     * tables should happen, if a database is being created from scratch instead
     * of being copied from the application package assets. Copying a database
     * from the application package assets to internal storage inside this
     * method will result in a corrupted database.
     * <P>
     * NOTE: This method is normally only called when a database has not already
     * been created. When the database has been copied, then this method is
     * called the first time a reference to the database is retrieved after the
     * database is copied since the database last cached by SQLiteOpenHelper is
     * different than the database in internal storage.
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
        /*
         * Signal that a new database needs to be copied. The copy process must
         * be performed after the database in the cache has been closed causing
         * it to be committed to internal storage. Otherwise the database in
         * internal storage will not have the same creation timestamp as the one
         * in the cache causing the database in internal storage to be marked as
         * corrupted.
         */
        createDatabase = true;

        /*
         * This will create by reading a sql file and executing the commands in
         * it.
         */
            // try {
            // InputStream is = myContext.getResources().getAssets().open(
            // "create_database.sql");
            //
            // String[] statements = FileHelper.parseSqlFile(is);
            //
            // for (String statement : statements) {
            // db.execSQL(statement);
            // }
            // } catch (Exception ex) {
            // ex.printStackTrace();
            // }
    }

    /**
     * Called only if version number was changed and the database has already
     * been created. Copying a database from the application package assets to
     * the internal data system inside this method will result in a corrupted
     * database in the internal data system.
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        /*
         * Signal that the database needs to be upgraded for the copy method of
         * creation. The copy process must be performed after the database has
         * been opened or the database will be corrupted.
         */
        upgradeDatabase = true;

        /*
         * Code to update the database via execution of sql statements goes
         * here.
         */

        /*
         * This will upgrade by reading a sql file and executing the commands in
         * it.
         */
        // try {
        // InputStream is = myContext.getResources().getAssets().open(
        // "upgrade_database.sql");
        //
        // String[] statements = FileHelper.parseSqlFile(is);
        //
        // for (String statement : statements) {
        // db.execSQL(statement);
        // }
        // } catch (Exception ex) {
        // ex.printStackTrace();
        // }
    }

    /**
     * Called everytime the database is opened by getReadableDatabase or
     * getWritableDatabase. This is called after onCreate or onUpgrade is
     * called.
     */
    @Override
    public void onOpen(SQLiteDatabase db) {
        super.onOpen(db);
    }

    /*
     * Add your public helper methods to access and get content from the
     * database. You could return cursors by doing
     * "return myDataBase.query(....)" so it'd be easy to you to create adapters
     * for your views.
     */

}

바이트 스트림 복사 파일 및 구문 분석 SQL 파일을위한 방법이 포함 된 FileHelper 클래스는 다음과 같습니다.

package android.example;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.Reader;
import java.nio.channels.FileChannel;

/**
 * @author Danny Remington - MacroSolve
 * 
 *         Helper class for common tasks using files.
 * 
 */
public class FileHelper {
    /**
     * Creates the specified <i><b>toFile</b></i> that is a byte for byte a copy
     * of <i><b>fromFile</b></i>. If <i><b>toFile</b></i> already existed, then
     * it will be replaced with a copy of <i><b>fromFile</b></i>. The name and
     * path of <i><b>toFile</b></i> will be that of <i><b>toFile</b></i>. Both
     * <i><b>fromFile</b></i> and <i><b>toFile</b></i> will be closed by this
     * operation.
     * 
     * @param fromFile
     *            - InputStream for the file to copy from.
     * @param toFile
     *            - InputStream for the file to copy to.
     */
    public static void copyFile(InputStream fromFile, OutputStream toFile) throws IOException {
        // transfer bytes from the inputfile to the outputfile
        byte[] buffer = new byte[1024];
        int length;

        try {
            while ((length = fromFile.read(buffer)) > 0) {
                toFile.write(buffer, 0, length);
            }
        }
        // Close the streams
        finally {
            try {
                if (toFile != null) {
                    try {
                        toFile.flush();
                    } finally {
                        toFile.close();
                    }
            }
            } finally {
                if (fromFile != null) {
                    fromFile.close();
                }
            }
        }
    }

    /**
     * Creates the specified <i><b>toFile</b></i> that is a byte for byte a copy
     * of <i><b>fromFile</b></i>. If <i><b>toFile</b></i> already existed, then
     * it will be replaced with a copy of <i><b>fromFile</b></i>. The name and
     * path of <i><b>toFile</b></i> will be that of <i><b>toFile</b></i>. Both
     * <i><b>fromFile</b></i> and <i><b>toFile</b></i> will be closed by this
     * operation.
     * 
     * @param fromFile
     *            - String specifying the path of the file to copy from.
     * @param toFile
     *            - String specifying the path of the file to copy to.
     */
    public static void copyFile(String fromFile, String toFile) throws IOException {
        copyFile(new FileInputStream(fromFile), new FileOutputStream(toFile));
    }

    /**
     * Creates the specified <i><b>toFile</b></i> that is a byte for byte a copy
     * of <i><b>fromFile</b></i>. If <i><b>toFile</b></i> already existed, then
     * it will be replaced with a copy of <i><b>fromFile</b></i>. The name and
     * path of <i><b>toFile</b></i> will be that of <i><b>toFile</b></i>. Both
     * <i><b>fromFile</b></i> and <i><b>toFile</b></i> will be closed by this
     * operation.
     * 
     * @param fromFile
     *            - File for the file to copy from.
     * @param toFile
     *            - File for the file to copy to.
     */
    public static void copyFile(File fromFile, File toFile) throws IOException {
        copyFile(new FileInputStream(fromFile), new FileOutputStream(toFile));
    }

    /**
     * Creates the specified <i><b>toFile</b></i> that is a byte for byte a copy
     * of <i><b>fromFile</b></i>. If <i><b>toFile</b></i> already existed, then
     * it will be replaced with a copy of <i><b>fromFile</b></i>. The name and
     * path of <i><b>toFile</b></i> will be that of <i><b>toFile</b></i>. Both
     * <i><b>fromFile</b></i> and <i><b>toFile</b></i> will be closed by this
     * operation.
     * 
     * @param fromFile
     *            - FileInputStream for the file to copy from.
     * @param toFile
     *            - FileInputStream for the file to copy to.
     */
    public static void copyFile(FileInputStream fromFile, FileOutputStream toFile) throws IOException {
        FileChannel fromChannel = fromFile.getChannel();
        FileChannel toChannel = toFile.getChannel();

        try {
            fromChannel.transferTo(0, fromChannel.size(), toChannel);
        } finally {
            try {
                if (fromChannel != null) {
                    fromChannel.close();
                }
            } finally {
                if (toChannel != null) {
                    toChannel.close();
                }
            }
        }
    }

    /**
     * Parses a file containing sql statements into a String array that contains
     * only the sql statements. Comments and white spaces in the file are not
     * parsed into the String array. Note the file must not contained malformed
     * comments and all sql statements must end with a semi-colon ";" in order
     * for the file to be parsed correctly. The sql statements in the String
     * array will not end with a semi-colon ";".
     * 
     * @param sqlFile
     *            - String containing the path for the file that contains sql
     *            statements.
     * 
     * @return String array containing the sql statements.
     */
    public static String[] parseSqlFile(String sqlFile) throws IOException {
        return parseSqlFile(new BufferedReader(new FileReader(sqlFile)));
    }

    /**
     * Parses a file containing sql statements into a String array that contains
     * only the sql statements. Comments and white spaces in the file are not
     * parsed into the String array. Note the file must not contained malformed
     * comments and all sql statements must end with a semi-colon ";" in order
     * for the file to be parsed correctly. The sql statements in the String
     * array will not end with a semi-colon ";".
     * 
     * @param sqlFile
     *            - InputStream for the file that contains sql statements.
     * 
     * @return String array containing the sql statements.
     */
    public static String[] parseSqlFile(InputStream sqlFile) throws IOException {
        return parseSqlFile(new BufferedReader(new InputStreamReader(sqlFile)));
    }

    /**
     * Parses a file containing sql statements into a String array that contains
     * only the sql statements. Comments and white spaces in the file are not
     * parsed into the String array. Note the file must not contained malformed
     * comments and all sql statements must end with a semi-colon ";" in order
     * for the file to be parsed correctly. The sql statements in the String
     * array will not end with a semi-colon ";".
     * 
     * @param sqlFile
     *            - Reader for the file that contains sql statements.
     * 
     * @return String array containing the sql statements.
     */
    public static String[] parseSqlFile(Reader sqlFile) throws IOException {
        return parseSqlFile(new BufferedReader(sqlFile));
    }

    /**
     * Parses a file containing sql statements into a String array that contains
     * only the sql statements. Comments and white spaces in the file are not
     * parsed into the String array. Note the file must not contained malformed
     * comments and all sql statements must end with a semi-colon ";" in order
     * for the file to be parsed correctly. The sql statements in the String
     * array will not end with a semi-colon ";".
     * 
     * @param sqlFile
     *            - BufferedReader for the file that contains sql statements.
     * 
     * @return String array containing the sql statements.
     */
    public static String[] parseSqlFile(BufferedReader sqlFile) throws IOException {
        String line;
        StringBuilder sql = new StringBuilder();
        String multiLineComment = null;

        while ((line = sqlFile.readLine()) != null) {
            line = line.trim();

            // Check for start of multi-line comment
            if (multiLineComment == null) {
                // Check for first multi-line comment type
                if (line.startsWith("/*")) {
                    if (!line.endsWith("}")) {
                        multiLineComment = "/*";
                    }
                // Check for second multi-line comment type
                } else if (line.startsWith("{")) {
                    if (!line.endsWith("}")) {
                        multiLineComment = "{";
                }
                // Append line if line is not empty or a single line comment
                } else if (!line.startsWith("--") && !line.equals("")) {
                    sql.append(line);
                } // Check for matching end comment
            } else if (multiLineComment.equals("/*")) {
                if (line.endsWith("*/")) {
                    multiLineComment = null;
                }
            // Check for matching end comment
            } else if (multiLineComment.equals("{")) {
                if (line.endsWith("}")) {
                    multiLineComment = null;
                }
            }

        }

        sqlFile.close();

        return sql.toString().split(";");
    }

}

그만큼 SQLiteAssetHelper 라이브러리는이 작업을 정말 간단하게 만듭니다.

Gradle 의존성으로 쉽게 추가 할 수 있지만 (Ant/Eclipse에도 JAR도 사용할 수 있음) 문서와 함께 다음에서 찾을 수 있습니다.
https://github.com/jgilfelt/android-sqlite-asset-helper

메모: 이 프로젝트는 더 이상 GitHub 링크에 명시된대로 유지되지 않습니다.

문서에 설명 된 바와 같이 :

  1. 모듈의 Gradle 빌드 파일에 종속성을 추가하십시오.

    dependencies {
        compile 'com.readystatesoftware.sqliteasset:sqliteassethelper:+'
    }
    
  2. 데이터베이스를 호출 된 하위 디렉토리에서 자산 디렉토리에 복사하십시오. assets/databases. 예를 들어:
    assets/databases/my_database.db

    (선택적으로, 데이터베이스를 zip 파일로 압축 할 수 있습니다. assets/databases/my_database.zip. APK가 이미 전체적으로 압축되어 있기 때문에 이것은 필요하지 않습니다.)

  3. 예를 들어 클래스를 만듭니다.

    public class MyDatabase extends SQLiteAssetHelper {
    
        private static final String DATABASE_NAME = "my_database.db";
        private static final int DATABASE_VERSION = 1;
    
        public MyDatabase(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }
    }
    

오늘까지 최고와 최신 방법은 SQLiteAssetHelper 수업.

이 튜토리얼 당신을 완벽하게 안내합니다 Android에서 외부 데이터베이스 가져 오기 및 사용

안드로이드 SQLiteAssetHelper 라이브러리를 사용하면 구축 할 수 있습니다 SQLite데스크탑 컴퓨터의 데이터베이스를 사용하고 Android 애플리케이션에서 가져 와서 사용합니다. 이 라이브러리의 응용 프로그램을 보여주는 간단한 응용 프로그램을 만들어 봅시다.

1 단계: 좋아하는 SQLITE 데이터베이스 응용 프로그램을 사용하여 데이터베이스 따옴표를 만듭니다. 단일 열 '인용'으로 '따옴표'테이블을 만듭니다. '따옴표'에 임의의 인용문을 삽입하십시오.

2 단계: 데이터베이스는 프로젝트로 직접 또는 압축 파일로 가져올 수 있습니다. 데이터베이스의 크기가 너무 크면 압축 파일을 권장합니다. 당신은 둘 중 하나를 만들 수 있습니다 ZIP압축 또는 a GZ 압축.

압축 된 DB 파일의 파일 이름은 quotes.db.zip, 지퍼 압축을 사용하는 경우 또는 quotes.db.gz, GZ 압축을 사용하는 경우.

3 단계: 새 응용 프로그램을 만듭니다 External Database Demo 패키지 이름으로 com.javahelps.com.javahelps.externaldatabasedemo.

4 단계: 열기 build.gradle (모듈 : App) 파일과 다음 종속성을 추가하십시오.

dependencies {
    compile 'com.readystatesoftware.sqliteasset:sqliteassethelper:+'
}

일단 당신이 저장 한 후 build.gradle 파일 프로젝트를 업데이트하려면 '동기화'링크를 클릭하십시오. 당신은 동기화 할 수 있습니다 build.gradle, 마우스 오른쪽 버튼을 클릭합니다 build.gradle 파일 및 선택 Synchronize build.gradle 옵션도 있습니다.

5 단계: 앱 폴더를 마우스 오른쪽 버튼으로 클릭하고 새 자산 폴더를 만듭니다.

6 단계: 자산 폴더 내부에서 새 폴더 '데이터베이스'를 만듭니다.

7 단계: 복사하여 붙여 넣습니다 quotes.db.zip 내부의 파일 assets/databases 폴더.

8 단계: 새 수업을 만듭니다 DatabaseOpenHelper

package com.javahelps.externaldatabasedemo;

import android.content.Context;

import com.readystatesoftware.sqliteasset.SQLiteAssetHelper;

public class DatabaseOpenHelper extends SQLiteAssetHelper {
    private static final String DATABASE_NAME = "quotes.db";
    private static final int DATABASE_VERSION = 1;

    public DatabaseOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }
}  Notice that rather than extending SQLiteOpenHelper, the DatabaseOpenHelper extends  SQLiteAssetHelper class.

9 단계: 새 수업을 만듭니다 DatabaseAccess 아래 그림과 같이 코드를 입력하십시오. 이 클래스에 대한 자세한 내용은 Advanced Android Database Tutorial에서 확인할 수 있습니다.

package com.javahelps.externaldatabasedemo;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import java.util.ArrayList;
import java.util.List;

public class DatabaseAccess {
    private SQLiteOpenHelper openHelper;
    private SQLiteDatabase database;
    private static DatabaseAccess instance;

    /**
     * Private constructor to aboid object creation from outside classes.
     *
     * @param context
     */
    private DatabaseAccess(Context context) {
        this.openHelper = new DatabaseOpenHelper(context);
    }

    /**
     * Return a singleton instance of DatabaseAccess.
     *
     * @param context the Context
     * @return the instance of DabaseAccess
     */
    public static DatabaseAccess getInstance(Context context) {
        if (instance == null) {
            instance = new DatabaseAccess(context);
        }
        return instance;
    }

    /**
     * Open the database connection.
     */
    public void open() {
        this.database = openHelper.getWritableDatabase();
    }

    /**
     * Close the database connection.
     */
    public void close() {
        if (database != null) {
            this.database.close();
        }
    }

    /**
     * Read all quotes from the database.
     *
     * @return a List of quotes
     */
    public List<String> getQuotes() {
        List<String> list = new ArrayList<>();
        Cursor cursor = database.rawQuery("SELECT * FROM quotes", null);
        cursor.moveToFirst();
        while (!cursor.isAfterLast()) {
            list.add(cursor.getString(0));
            cursor.moveToNext();
        }
        cursor.close();
        return list;
    }
}  In this class only the `getQuotes` method is implemented to read the data from the database. You have the full freedom to insert,

평소와 같이 데이터베이스의 행을 업데이트하고 삭제하십시오. 자세한 내용은이 링크 Advanced Android 데이터베이스를 참조하십시오.

모든 데이터베이스 관련 설정이 완료되었으며 이제 우리는 ListView 인용문을 표시합니다.

10 단계: 을 추가하다 ListView 당신의 activity_main.xml.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center" />
</FrameLayout>  

11 단계: 대상을 찾으십시오 ListView 에서 onCreate 의 방법 MainActivity 데이터베이스를 읽는 인용문을 피드하십시오.

package com.javahelps.externaldatabasedemo;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import java.util.List;


public class MainActivity extends ActionBarActivity {
    private ListView listView;

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

        this.listView = (ListView) findViewById(R.id.listView);
        DatabaseAccess databaseAccess = DatabaseAccess.getInstance(this);
        databaseAccess.open();
        List<String> quotes = databaseAccess.getQuotes();
        databaseAccess.close();

        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
quotes);
        this.listView.setAdapter(adapter);
    }
}

12 단계: 모든 변경 사항을 저장하고 응용 프로그램을 실행하십시오.

이 기사 외에도 다운로드 할 수 있습니다 SQLiteAssetHelper 여기

내 솔루션은 타사 라이브러리를 사용하지 않거나 사용자 정의 메소드를 호출하도록 강요하지 않습니다. SQLiteOpenHelper 생성시 데이터베이스를 초기화하기위한 서브 클래스. 또한 데이터베이스 업그레이드도 처리해야합니다. 해야 할 일은 서브 클래스입니다 SQLiteOpenHelper.

전제 조건 :

  1. 앱과 함께 배송하려는 데이터베이스. 포함해야합니다 1x1 테이블이 명명되었습니다 android_metadata 속성으로 locale 가치가 있습니다 en_US 앱에 고유 한 테이블 외에도.

서브 클래싱 SQLiteOpenHelper:

  1. 아강 SQLiteOpenHelper.
  2. a private 내에서의 방법 SQLiteOpenHelper 아강. 이 방법에는 '자산'폴더의 데이터베이스 파일에서 데이터베이스 내용을 응용 프로그램 패키지 컨텍스트에서 만든 데이터베이스로 복사하는 논리가 포함되어 있습니다.
  3. 우세하다 onCreate, onUpgrade 그리고 onOpen 방법 SQLiteOpenHelper.

충분했다. 여기에 간다 SQLiteOpenHelper 아강:

public class PlanDetailsSQLiteOpenHelper extends SQLiteOpenHelper {
    private static final String TAG = "SQLiteOpenHelper";

    private final Context context;
    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "my_custom_db";

    private boolean createDb = false, upgradeDb = false;

    public PlanDetailsSQLiteOpenHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        this.context = context;
    }

    /**
     * Copy packaged database from assets folder to the database created in the
     * application package context.
     * 
     * @param db
     *            The target database in the application package context.
     */
    private void copyDatabaseFromAssets(SQLiteDatabase db) {
        Log.i(TAG, "copyDatabase");
        InputStream myInput = null;
        OutputStream myOutput = null;
        try {
            // Open db packaged as asset as the input stream
            myInput = context.getAssets().open("path/to/shipped/db/file");

            // Open the db in the application package context:
            myOutput = new FileOutputStream(db.getPath());

            // Transfer db file contents:
            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInput.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }
            myOutput.flush();

            // Set the version of the copied database to the current
            // version:
            SQLiteDatabase copiedDb = context.openOrCreateDatabase(
                DATABASE_NAME, 0, null);
            copiedDb.execSQL("PRAGMA user_version = " + DATABASE_VERSION);
            copiedDb.close();

        } catch (IOException e) {
            e.printStackTrace();
            throw new Error(TAG + " Error copying database");
        } finally {
            // Close the streams
            try {
                if (myOutput != null) {
                    myOutput.close();
                }
                if (myInput != null) {
                    myInput.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
                throw new Error(TAG + " Error closing streams");
            }
        }
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        Log.i(TAG, "onCreate db");
        createDb = true;
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        Log.i(TAG, "onUpgrade db");
        upgradeDb = true;
    }

    @Override
    public void onOpen(SQLiteDatabase db) {
        Log.i(TAG, "onOpen db");
        if (createDb) {// The db in the application package
            // context is being created.
            // So copy the contents from the db
            // file packaged in the assets
            // folder:
            createDb = false;
            copyDatabaseFromAssets(db);

        }
        if (upgradeDb) {// The db in the application package
            // context is being upgraded from a lower to a higher version.
            upgradeDb = false;
            // Your db upgrade logic here:
        }
    }
}

마지막으로 데이터베이스 연결을 얻으려면 getReadableDatabase() 또는 getWritableDatabase()SQLiteOpenHelper 서브 클래스 및 데이터베이스가 존재하지 않는 경우 '자산'폴더의 지정된 파일에서 DB 내용을 복사하고 DB를 작성해야합니다.

요컨대, 당신은 그것을 사용할 수 있습니다 SQLiteOpenHelper 서브 클래스는 자산 폴더에 배송 된 DB에 액세스하기위한 서브 클래스에서 onCreate() 방법.

Android Studio 3.0에서 데이터베이스 파일로 앱 배송

데이터베이스 파일로 앱을 배송하는 것은 나에게 좋은 아이디어입니다. 장점은 복잡한 초기화를 수행 할 필요가 없다는 것입니다. 데이터 세트가 크면 때로는 많은 시간이 소요됩니다.

1 단계 : 데이터베이스 파일 준비

데이터베이스 파일을 준비하십시오. .db 파일 또는 .sqlite 파일 일 수 있습니다. .sqlite 파일을 사용하는 경우 파일 확장자 이름을 변경하기 만하면됩니다. 단계는 동일합니다.

이 예에서는 testdb.db라는 파일을 준비했습니다. 이와 같은 테이블 하나와 샘플 데이터가 있습니다.enter image description here

2 단계 : 파일을 프로젝트로 가져옵니다

자산 폴더가 없으면 자산 폴더를 만듭니다. 그런 다음 데이터베이스 파일을이 폴더에 복사하여 붙여 넣습니다.

enter image description here

3 단계 : 파일을 앱의 데이터 폴더에 복사합니다.

추가 상호 작용을 수행하려면 데이터베이스 파일을 앱의 데이터 폴더에 복사해야합니다. 데이터베이스 파일을 복사하는 한 번의 작업 (초기화)입니다. 이 코드를 여러 번 호출하면 데이터 폴더의 데이터베이스 파일이 자산 폴더의 데이터베이스 파일을 덮어 씁니다. 이 과도한 프로세스는 앱 업데이트 중에 향후 데이터베이스를 업데이트 할 때 유용합니다.

앱 업데이트 중에이 데이터베이스 파일은 앱의 데이터 폴더에서 변경되지 않습니다. 제거 만 제거하면 삭제됩니다.

데이터베이스 파일을 복사해야합니다 /databases 폴더. 장치 파일 탐색기 열기. 입력하다 data/data/<YourAppName>/ 위치. 위에서 언급 한 앱의 기본 데이터 폴더입니다. 기본적으로 데이터베이스 파일은이 디렉토리의 데이터베이스라는 다른 폴더에 배치됩니다.

enter image description here

이제 사본 파일 프로세스는 Java가하는 일과 거의 비슷합니다. 다음 코드를 사용하여 복사 페이스트를 수행하십시오. 이것은 시작 코드입니다. 향후 데이터베이스 파일을 업데이트하는 데 사용될 수도 있습니다.

//get context by calling "this" in activity or getActivity() in fragment
//call this if API level is lower than 17  String appDataPath = "/data/data/" + context.getPackageName() + "/databases/"
String appDataPath = context.getApplicationInfo().dataDir;

File dbFolder = new File(appDataPath + "/databases");//Make sure the /databases folder exists
dbFolder.mkdir();//This can be called multiple times.

File dbFilePath = new File(appDataPath + "/databases/testDB.db");

try {
    InputStream inputStream = context.getAssets().open("testDB.db");
    OutputStream outputStream = new FileOutputStream(dbFilePath);
    byte[] buffer = new byte[1024];
    int length;
    while ((length = inputStream.read(buffer))>0)
    {
        outputStream.write(buffer, 0, length);
    }
    outputStream.flush();
    outputStream.close();
    inputStream.close();
} catch (IOException e){
    //handle
}

그런 다음 폴더를 새로 고쳐서 복사 프로세스를 확인하십시오

enter image description here

4 단계 : 데이터베이스 열기 도우미를 만듭니다

서브 클래스를 만듭니다 SQLiteOpenHelper, Connect, Close, Path 등. DatabaseOpenHelper

import android.content.Context;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DatabaseOpenHelper extends SQLiteOpenHelper {
    public static final String DB_NAME = "testDB.db";
    public static final String DB_SUB_PATH = "/databases/" + DB_NAME;
    private static String APP_DATA_PATH = "";
    private SQLiteDatabase dataBase;
    private final Context context;

    public DatabaseOpenHelper(Context context){
        super(context, DB_NAME, null, 1);
        APP_DATA_PATH = context.getApplicationInfo().dataDir;
        this.context = context;
    }

    public boolean openDataBase() throws SQLException{
        String mPath = APP_DATA_PATH + DB_SUB_PATH;
        //Note that this method assumes that the db file is already copied in place
        dataBase = SQLiteDatabase.openDatabase(mPath, null, SQLiteDatabase.OPEN_READWRITE);
        return dataBase != null;
    }

    @Override
    public synchronized void close(){
        if(dataBase != null) {dataBase.close();}
        super.close();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
    }

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

5 단계 : 데이터베이스와 상호 작용할 최상위 클래스 생성

이것은 데이터베이스 파일을 읽고 쓰는 클래스입니다. 또한 데이터베이스의 값을 인쇄하는 샘플 쿼리가 있습니다.

import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class Database {
    private final Context context;
    private SQLiteDatabase database;
    private DatabaseOpenHelper dbHelper;

    public Database(Context context){
        this.context = context;
        dbHelper = new DatabaseOpenHelper(context);
    }

    public Database open() throws SQLException
    {
        dbHelper.openDataBase();
        dbHelper.close();
        database = dbHelper.getReadableDatabase();
        return this;
    }

    public void close()
    {
        dbHelper.close();
    }

    public void test(){
        try{
            String query ="SELECT value FROM test1";
            Cursor cursor = database.rawQuery(query, null);
            if (cursor.moveToFirst()){
                do{
                    String value = cursor.getString(0);
                    Log.d("db", value);
                }while (cursor.moveToNext());
            }
            cursor.close();
        } catch (SQLException e) {
            //handle
        }
    }
}

6 단계 : 테스트 실행

다음 줄의 코드를 실행하여 코드를 테스트하십시오.

Database db = new Database(context);
db.open();
db.test();
db.close();

런 버튼을 누르고 응원하십시오!

enter image description here

2017 년 11 월 Google은 The를 출시했습니다 방 지속성 라이브러리

문서에서 :

Room Persistence Library는 SQLITE의 전체 전력을 활용하면서 유창한 데이터베이스 액세스를 허용하기 위해 SQLITE에 대한 추상화 레이어를 제공합니다.

라이브러리를 사용하면 앱을 실행중인 장치에서 앱 데이터 캐시를 만들도록 도와줍니다. 앱의 단일 진실 소스 역할을하는이 캐시는 사용자가 인터넷에 연결되어 있는지 여부에 관계없이 앱 내에서 일관된 주요 정보 사본을 볼 수 있습니다.

룸 데이터베이스에는 데이터베이스가 처음 생성되거나 열리면 콜백이 있습니다. Create Callback을 사용하여 데이터베이스를 채울 수 있습니다.

Room.databaseBuilder(context.applicationContext,
        DataDatabase::class.java, "Sample.db")
        // prepopulate the database after onCreate was called
        .addCallback(object : Callback() {
            override fun onCreate(db: SupportSQLiteDatabase) {
                super.onCreate(db)
                // moving to a new thread
                ioThread {
                    getInstance(context).dataDao()
                                        .insert(PREPOPULATE_DATA)
                }
            }
        })
        .build()

이것에서 코드 블로그 게시물.

내가 본 것에서 당신은 이미 테이블 설정과 데이터가있는 데이터베이스를 배송해야합니다. 그러나 원하는 경우 (그리고 보유한 응용 프로그램 유형에 따라) "업그레이드 데이터베이스 옵션"을 허용 할 수 있습니다. 그런 다음 최신 SQLITE 버전을 다운로드하고 온라인으로 호스팅 된 TextFile의 최신 삽입/작성 문을 가져오고 문을 실행하며 이전 DB에서 새 DB에서 새로 전송하는 것입니다.

마침내 나는 그것을했다 !! 이 링크를 사용했습니다 Android 애플리케이션에서 자신의 SQLITE 데이터베이스를 사용하는 데 도움이됩니다, 그러나 조금 바꿔야했습니다.

  1. 패키지가 많으면 마스터 패키지 이름을 여기에 넣어야합니다.

    private static String DB_PATH = "data/data/masterPakageName/databases";

  2. 로컬 폴더에서 에뮬레이터 폴더로 데이터베이스를 복사하는 메소드를 변경했습니다! 해당 폴더가 존재하지 않을 때 약간의 문제가있었습니다. 우선, 경로를 점검해야하며 존재하지 않으면 폴더를 생성해야합니다.

  3. 이전 코드에서 copyDatabase 데이터베이스가 존재하지 않았을 때 메소드는 호출되지 않았고 checkDataBase 방법이 예외를 일으켰습니다. 그래서 코드를 조금 변경했습니다.

  4. 데이터베이스에 파일 확장자가없는 경우 파일 이름을 사용하지 마십시오.

그것은 나에게 좋다. 나는 너도 유용 할 수 있기를 바랍니다.

    package farhangsarasIntroduction;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;

import android.content.Context;
import android.database.Cursor;

import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;

import android.util.Log;


    public class DataBaseHelper extends SQLiteOpenHelper{

    //The Android's default system path of your application database.
    private static String DB_PATH = "data/data/com.example.sample/databases";

    private static String DB_NAME = "farhangsaraDb";

    private SQLiteDatabase myDataBase;

    private final Context myContext;

    /**
      * Constructor
      * Takes and keeps a reference of the passed context in order to access to the application assets and resources.
      * @param context
      */
    public DataBaseHelper(Context context) {

        super(context, DB_NAME, null, 1);
            this.myContext = context;

    }   

    /**
      * Creates a empty database on the system and rewrites it with your own database.
      * */
    public void createDataBase() {

        boolean dbExist;
        try {

             dbExist = checkDataBase();


        } catch (SQLiteException e) {

            e.printStackTrace();
            throw new Error("database dose not exist");

        }

        if(dbExist){
        //do nothing - database already exist
        }else{

            try {

                copyDataBase();


            } catch (IOException e) {

                e.printStackTrace();
                throw new Error("Error copying database");

            }
    //By calling this method and empty database will be created into the default system path
    //of your application so we are gonna be able to overwrite that database with our database.
        this.getReadableDatabase();


    }

    }

    /**
      * Check if the database already exist to avoid re-copying the file each time you open the application.
      * @return true if it exists, false if it doesn't
      */
    private boolean checkDataBase(){

    SQLiteDatabase checkDB = null;

    try{
        String myPath = DB_PATH +"/"+ DB_NAME;

        checkDB = SQLiteDatabase.openDatabase(myPath, null, SQLiteDatabase.OPEN_READONLY);
    }catch(SQLiteException e){

    //database does't exist yet.
        throw new Error("database does't exist yet.");

    }

    if(checkDB != null){

    checkDB.close();

    }

    return checkDB != null ? true : false;
    }

    /**
      * Copies your database from your local assets-folder to the just created empty database in the
      * system folder, from where it can be accessed and handled.
      * This is done by transfering bytestream.
      * */
    private void copyDataBase() throws IOException{



            //copyDataBase();
            //Open your local db as the input stream
            InputStream myInput = myContext.getAssets().open(DB_NAME);

            // Path to the just created empty db
            String outFileName = DB_PATH +"/"+ DB_NAME;
            File databaseFile = new File( DB_PATH);
             // check if databases folder exists, if not create one and its subfolders
            if (!databaseFile.exists()){
                databaseFile.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();



    }



    @Override
    public synchronized void close() {

        if(myDataBase != null)
        myDataBase.close();

        super.close();

    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }



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

    }

     you to create adapters for your views.

}

현재 APK와 함께 배송 할 SQLITE 데이터베이스를 사전 크리팅 할 방법이 없습니다. 당신이 할 수있는 최선은 적절한 SQL을 리소스로 저장하고 응용 프로그램에서 실행하는 것입니다. 그렇습니다. 이것은 데이터의 복제로 이어집니다 (동일한 정보는 Resrouce 및 데이터베이스와 동일한 정보가 존재합니다). 현재 다른 방법은 없습니다. 유일한 완화 계수는 APK 파일이 압축된다는 것입니다. 제 경험은 908KB 압축이 268KB 미만입니다.

아래 스레드에는 좋은 샘플 코드에서 찾은 최고의 토론/솔루션이 있습니다.

http://groups.google.com/group/android-developers/msg/9f455ae93a1cf152

context.getString ()로 읽을 문자열 자원으로 만들기 명령문을 저장하고 sqlitedatabse.execsql ()로 실행했습니다.

res/raw/inserts.sql에 삽입물에 대한 데이터를 저장했습니다 (7000 회 이상의 SQL 파일을 만들었습니다). 위의 링크의 기술을 사용하여 루프를 입력하고 파일을 라인별로 읽고 "TBL 값에 삽입"에 데이터를 조심하고 다른 sqlitedatabase.execsql ()를 수행했습니다. 7000 "TBL 값에 삽입"을 저장하는 것은 의미가 없습니다.

에뮬레이터에서 약 20 초가 걸리기 때문에 실제 전화를받는 시간은 얼마나 걸릴지 모르겠지만 사용자가 처음 응용 프로그램을 시작할 때만 한 번만 발생합니다.

APK 내부의 데이터베이스를 배송 한 다음 복사 /data/data/... 데이터베이스 크기의 두 배 data/data/...), APK 크기를 증가시킵니다 (물론). 따라서 데이터베이스가 너무 크지 않아야합니다.

Android는 이미 데이터베이스 관리에 대한 버전 인식 접근 방식을 제공합니다.이 접근 방식은 Android 애플리케이션용 BARACUS 프레임워크에서 활용되었습니다.

이를 통해 앱의 전체 버전 수명 주기에 따라 데이터베이스를 관리할 수 있으며, sqlite 데이터베이스를 이전 버전에서 현재 버전으로 업데이트할 수 있습니다.

또한 SQLite의 핫 백업 및 핫 복구를 실행할 수 있습니다.

100% 확신할 수는 없지만 핫 복구에 대한 내용은 다음과 같습니다. 특정한 장치를 사용하면 앱에 준비된 데이터베이스를 제공할 수 있습니다.그러나 특정 장치, 공급업체 또는 장치 세대에 특정한 데이터베이스 바이너리 형식에 대해서는 잘 모르겠습니다.

해당 내용은 Apache License 2이므로 코드의 일부를 자유롭게 재사용할 수 있습니다. github에서 찾을 수 있습니다

편집하다 :

데이터만 전송하려는 경우 애플리케이션이 처음 시작될 때 POJO를 인스턴스화하고 지속하는 것을 고려할 수 있습니다.BARACUS는 이에 대한 지원을 내장하고 있습니다(구성 정보를 위한 내장 키 값 저장소, 예:컨텍스트에서 실행 후 작업을 실행하기 위한 "APP_FIRST_RUN" 및 컨텍스트 후 부트스트랩 후크).이를 통해 앱과 함께 긴밀하게 결합된 데이터를 제공할 수 있습니다.대부분의 경우 이는 내 사용 사례에 적합했습니다.

필요한 데이터가 너무 크지 않은 경우 (내가 알지 못하는 한계는 많은 것들에 의존 할 것입니다) 웹 사이트/웹 앱에서 데이터 (XML, JSON 등)를 다운로드 할 수도 있습니다. 수신 후 수신 된 데이터를 사용하여 테이블을 작성하고 데이터를 삽입하여 SQL 문을 실행하십시오.

모바일 앱에 많은 데이터가 포함되어 있으면 나중에보다 정확한 데이터 나 변경으로 설치된 앱에서 데이터를 업데이트하기가 더 쉬울 수 있습니다.

나는 a 도서관 이 프로세스를 단순화합니다.

dataBase = new DataBase.Builder(context, "myDb").
//        setAssetsPath(). // default "databases"
//        setDatabaseErrorHandler().
//        setCursorFactory().
//        setUpgradeCallback()
//        setVersion(). // default 1
build();

데이터베이스를 생성합니다 assets/databases/myDb.db 파일. 또한 모든 기능을 얻을 수 있습니다.

  • 파일에서 데이터베이스를로드합니다
  • 데이터베이스에 대한 동기화 된 액세스
  • 사용 sqlite-android Requery에 의해, 최신 버전의 SQLite의 Android 특유의 분포.

그것을 복제하십시오 github.

나는 ormlite를 사용하고 있으며 아래 코드는 저를 위해 일했습니다

public class DatabaseProvider extends OrmLiteSqliteOpenHelper {
    private static final String DatabaseName = "DatabaseName";
    private static final int DatabaseVersion = 1;
    private final Context ProvidedContext;

    public DatabaseProvider(Context context) {
        super(context, DatabaseName, null, DatabaseVersion);
        this.ProvidedContext= context;
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
        boolean databaseCopied = preferences.getBoolean("DatabaseCopied", false);
        if (databaseCopied) {
            //Do Nothing
        } else {
            CopyDatabase();
            SharedPreferences.Editor editor = preferences.edit();
            editor.putBoolean("DatabaseCopied", true);
            editor.commit();
        }
    }

    private String DatabasePath() {
        return "/data/data/" + ProvidedContext.getPackageName() + "/databases/";
    }

    private void CopyDatabase() {
        try {
            CopyDatabaseInternal();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private File ExtractAssetsZip(String zipFileName) {
        InputStream inputStream;
        ZipInputStream zipInputStream;
        File tempFolder;
        do {
            tempFolder = null;
            tempFolder = new File(ProvidedContext.getCacheDir() + "/extracted-" + System.currentTimeMillis() + "/");
        } while (tempFolder.exists());

        tempFolder.mkdirs();

        try {
            String filename;
            inputStream = ProvidedContext.getAssets().open(zipFileName);
            zipInputStream = new ZipInputStream(new BufferedInputStream(inputStream));
            ZipEntry zipEntry;
            byte[] buffer = new byte[1024];
            int count;

            while ((zipEntry = zipInputStream.getNextEntry()) != null) {
                filename = zipEntry.getName();
                if (zipEntry.isDirectory()) {
                    File fmd = new File(tempFolder.getAbsolutePath() + "/" + filename);
                    fmd.mkdirs();
                    continue;
                }

                FileOutputStream fileOutputStream = new FileOutputStream(tempFolder.getAbsolutePath() + "/" + filename);
                while ((count = zipInputStream.read(buffer)) != -1) {
                    fileOutputStream.write(buffer, 0, count);
                }

                fileOutputStream.close();
                zipInputStream.closeEntry();
            }

            zipInputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }

        return tempFolder;
    }

    private void CopyDatabaseInternal() throws IOException {

        File extractedPath = ExtractAssetsZip(DatabaseName + ".zip");
        String databaseFile = "";
        for (File innerFile : extractedPath.listFiles()) {
            databaseFile = innerFile.getAbsolutePath();
            break;
        }
        if (databaseFile == null || databaseFile.length() ==0 )
            throw new RuntimeException("databaseFile is empty");

        InputStream inputStream = new FileInputStream(databaseFile);

        String outFileName = DatabasePath() + DatabaseName;

        File destinationPath = new File(DatabasePath());
        if (!destinationPath.exists())
            destinationPath.mkdirs();

        File destinationFile = new File(outFileName);
        if (!destinationFile.exists())
            destinationFile.createNewFile();

        OutputStream myOutput = new FileOutputStream(outFileName);

        byte[] buffer = new byte[1024];
        int length;
        while ((length = inputStream.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }

        myOutput.flush();
        myOutput.close();
        inputStream.close();
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource) {
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, ConnectionSource connectionSource, int fromVersion, int toVersion) {

    }
}

코드는 자산의 zip 파일에서 데이터베이스 파일을 추출합니다.

클래스와 질문에 대한 답변을 수정하고 DB_Version을 통해 데이터베이스를 업데이트 할 수있는 클래스를 작성했습니다.

public class DatabaseHelper extends SQLiteOpenHelper {
    private static String DB_NAME = "info.db";
    private static String DB_PATH = "";
    private static final int DB_VERSION = 1;

    private SQLiteDatabase mDataBase;
    private final Context mContext;
    private boolean mNeedUpdate = false;

    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
        if (android.os.Build.VERSION.SDK_INT >= 17)
            DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
        else
            DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
        this.mContext = context;

        copyDataBase();

        this.getReadableDatabase();
    }

    public void updateDataBase() throws IOException {
        if (mNeedUpdate) {
            File dbFile = new File(DB_PATH + DB_NAME);
            if (dbFile.exists())
                dbFile.delete();

            copyDataBase();

            mNeedUpdate = false;
        }
    }

    private boolean checkDataBase() {
        File dbFile = new File(DB_PATH + DB_NAME);
        return dbFile.exists();
    }

    private void copyDataBase() {
        if (!checkDataBase()) {
            this.getReadableDatabase();
            this.close();
            try {
                copyDBFile();
            } catch (IOException mIOException) {
                throw new Error("ErrorCopyingDataBase");
            }
        }
    }

    private void copyDBFile() throws IOException {
        InputStream mInput = mContext.getAssets().open(DB_NAME);
        //InputStream mInput = mContext.getResources().openRawResource(R.raw.info);
        OutputStream mOutput = new FileOutputStream(DB_PATH + DB_NAME);
        byte[] mBuffer = new byte[1024];
        int mLength;
        while ((mLength = mInput.read(mBuffer)) > 0)
            mOutput.write(mBuffer, 0, mLength);
        mOutput.flush();
        mOutput.close();
        mInput.close();
    }

    public boolean openDataBase() throws SQLException {
        mDataBase = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.CREATE_IF_NECESSARY);
        return mDataBase != null;
    }

    @Override
    public synchronized void close() {
        if (mDataBase != null)
            mDataBase.close();
        super.close();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if (newVersion > oldVersion)
            mNeedUpdate = true;
    }
}

수업 사용.

활동 클래스에서 변수를 선언하십시오.

private DatabaseHelper mDBHelper;
private SQLiteDatabase mDb;

OnCreate 메소드에서 다음 코드를 작성하십시오.

mDBHelper = new DatabaseHelper(this);

try {
    mDBHelper.updateDataBase();
} catch (IOException mIOException) {
    throw new Error("UnableToUpdateDatabase");
}

try {
    mDb = mDBHelper.getWritableDatabase();
} catch (SQLException mSQLException) {
    throw mSQLException;
}

폴더 res/raw에 데이터베이스 파일을 추가하면 클래스의 다음 수정을 사용하십시오.

public class DatabaseHelper extends SQLiteOpenHelper {
    private static String DB_NAME = "info.db";
    private static String DB_PATH = "";
    private static final int DB_VERSION = 1;

    private SQLiteDatabase mDataBase;
    private final Context mContext;
    private boolean mNeedUpdate = false;

    public DatabaseHelper(Context context) {
        super(context, DB_NAME, null, DB_VERSION);
        if (android.os.Build.VERSION.SDK_INT >= 17)
            DB_PATH = context.getApplicationInfo().dataDir + "/databases/";
        else
            DB_PATH = "/data/data/" + context.getPackageName() + "/databases/";
        this.mContext = context;

        copyDataBase();

        this.getReadableDatabase();
    }

    public void updateDataBase() throws IOException {
        if (mNeedUpdate) {
            File dbFile = new File(DB_PATH + DB_NAME);
            if (dbFile.exists())
                dbFile.delete();

            copyDataBase();

            mNeedUpdate = false;
        }
    }

    private boolean checkDataBase() {
        File dbFile = new File(DB_PATH + DB_NAME);
        return dbFile.exists();
    }

    private void copyDataBase() {
        if (!checkDataBase()) {
            this.getReadableDatabase();
            this.close();
            try {
                copyDBFile();
            } catch (IOException mIOException) {
                throw new Error("ErrorCopyingDataBase");
            }
        }
    }

    private void copyDBFile() throws IOException {
        //InputStream mInput = mContext.getAssets().open(DB_NAME);
        InputStream mInput = mContext.getResources().openRawResource(R.raw.info);
        OutputStream mOutput = new FileOutputStream(DB_PATH + DB_NAME);
        byte[] mBuffer = new byte[1024];
        int mLength;
        while ((mLength = mInput.read(mBuffer)) > 0)
            mOutput.write(mBuffer, 0, mLength);
        mOutput.flush();
        mOutput.close();
        mInput.close();
    }

    public boolean openDataBase() throws SQLException {
        mDataBase = SQLiteDatabase.openDatabase(DB_PATH + DB_NAME, null, SQLiteDatabase.CREATE_IF_NECESSARY);
        return mDataBase != null;
    }

    @Override
    public synchronized void close() {
        if (mDataBase != null)
            mDataBase.close();
        super.close();
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        if (newVersion > oldVersion)
            mNeedUpdate = true;
    }
}

http://blog.harrix.org/article/6784

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top