简体   繁体   English

如何在 Android 中使用 AsyncTask 复制数据库

[英]How to use AsyncTask for copy Database in Android

I want use AsyncTask for copy database in my application.我想在我的应用程序中使用AsyncTask复制数据库 The application has 4 fragments, and any fragment shows one table from the database (database has 4 tables).应用程序有4个片段,任何片段都显示数据库中的一张表(数据库有4张表)。 But when I run the application, it show me this error:但是当我运行应用程序时,它显示了这个错误:

03-07 12:49:18.775 11190-11190/com.tellfa.dastanak E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.tellfa.dastanak, PID: 11190
android.database.sqlite.SQLiteException: no such table: tbl_Book (code 1): , while compiling: SELECT * FROM tbl_Book WHERE Cat_ID = ?
at android.database.sqlite.SQLiteConnection.nativePrepareStatement(Native Method)
at android.database.sqlite.SQLiteConnection.acquirePreparedStatement(SQLiteConnection.java:897)
at android.database.sqlite.SQLiteConnection.prepare(SQLiteConnection.java:508)
at android.database.sqlite.SQLiteSession.prepare(SQLiteSession.java:726)
at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:58)
at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:37)
at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:44)
at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1426)
at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1365)
at com.tellfa.dastanak.Database.DataBase.getCat1_Datas(DataBase.java:157)
at com.tellfa.dastanak.Fragments.Home_Frag.onCreateView(Home_Frag.java:49)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1962)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1067)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1248)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:738)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1613)
at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:570)
at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1106)
at android.support.v4.view.ViewPager.populate(ViewPager.java:952)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1474)
at android.view.View.measure(View.java:17496)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
at android.support.design.widget.CoordinatorLayout.onMeasureChild(CoordinatorLayout.java:610)
at android.support.design.widget.CoordinatorLayout.onMeasure(CoordinatorLayout.java:677)
at android.view.View.measure(View.java:17496)
at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:940)
at android.view.View.measure(View.java:17496)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:135)
at android.view.View.measure(View.java:17496)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1438)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:724)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:615)
at android.view.View.measure(View.java:17496)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at android.view.View.measure(View.java:17496)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1438)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:724)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:615)
at android.view.View.measure(View.java:17496)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5466)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:430)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2636)
at android.view.View.measure(View.java:17496)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2031)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1193)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1400)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1078)
at android.view.Vi

AsyncTask code :异步任务代码:

public class LoadDB_AsyncTask extends AsyncTask<Void, Void, Boolean> {

    Context mContext;
    boolean loadedDB = false;
    private DataBase dataBase;
    private ProgressDialog progressDialog;
    private static final String LOG_TAG = "log : ";

    public LoadDB_AsyncTask(Context context) {
        this.mContext = context;
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        Log.i(LOG_TAG, "onPreExecute in loadDB");
        progressDialog = new ProgressDialog(mContext);
        progressDialog.setMessage("Data loading ...");
        progressDialog.setCancelable(false);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        super.onProgressUpdate(values);
        Log.i(LOG_TAG, "onProgressUpdate in loadDB");
        progressDialog.show();
    }

    @Override
    protected Boolean doInBackground(Void... params) {
        Log.i(LOG_TAG, "doInBackground in loadDB");

        dataBase = new DataBase(mContext);
        boolean dbExist = dataBase.checkDataBase();

        if (dbExist) {
            loadedDB = true;
        } else {
            publishProgress(null);
        }

        try {
            dataBase.createDataBase();
        } catch (IOException e) {
            throw new Error("Error on create DataBase");
        }

        dataBase.close();

        return null;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        super.onPostExecute(result);
        Log.i(LOG_TAG, "onPostExecute in loadDB");

        if (!loadedDB) {
            progressDialog.dismiss();
            Log.i(LOG_TAG, "Loaded DataBase");
            Toast.makeText(mContext, "Data Loaded", Toast.LENGTH_SHORT).show();
        } else {
            Log.i(LOG_TAG, "The database was already loaded");
        }
        try {
            finalize();
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
    }
}

DataBase code:数据库代码:

public class DataBase extends SQLiteOpenHelper {

    private static String DB_PATH = "";
    private static String DB_NAME = "Dastansara";
    private static int DB_VERSION = 1;
    private SQLiteDatabase sqLiteDatabase;
    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 DataBase(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.myContext = context;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

    }

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

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

        boolean dbExist = checkDataBase();
        if (dbExist) {
            // do nothing - database alerdy exist
        } else {

            this.getReadableDatabase();

            try {
                copyDataBase();
            } catch (IOException e) {
                throw new Error("Error copying database");
            }
        }
    }

    /**
     * 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
     */
    public 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
        }

        if (checkDB != null) {
            checkDB.close();
        }
        return checkDB != null ? true : false;
    }

    /**
     * Open DataBase
     *
     * @throws SQLException
     */
    public void openDataBase() throws SQLException {

        String myPATH = DB_PATH + DB_NAME;
        sqLiteDatabase = SQLiteDatabase.openDatabase(myPATH, null, SQLiteDatabase.OPEN_READONLY);
    }

    /**
     * Close DataBase
     */
    public void closeDataBase() {

        sqLiteDatabase.close();
    }

    /**
     * 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.
     */
    public void copyDataBase() throws IOException {

        //Open your local db as the input stream
        InputStream myInput = myContext.getAssets().open(DB_NAME);
        // Path to the just created empty db
        String myPath = DB_PATH + DB_NAME;
        //Open the empty db as the output stream
        OutputStream myOutput = new FileOutputStream(myPath);

        byte[] buffer = new byte[1024];
        int length;
        //transfer bytes from the inputfile to the outputfile
        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 (sqLiteDatabase != null) {
            sqLiteDatabase.close();
        }
        super.close();
    }

    public Cursor getCat1_Datas(SQLiteDatabase sqLiteDatabase) {

        try {
            String query = "SELECT * FROM tbl_Book WHERE Cat_ID = ?";

            Cursor cursor = sqLiteDatabase.rawQuery(query, new String[] {"1"});

            if (cursor != null) {
                cursor.moveToNext();
            }
            return cursor;
        } catch (SQLException e) {
            Log.e("Data Adapter", "getTestData >>" + e.toString());
            throw e;
        }
    }
}

Fragment code:片段代码:

public class Home_Frag extends Fragment {

    DataProvider dataProvider;
    DataBase dataBase;
    SQLiteDatabase sqLiteDatabase;
    Cursor cursor;
    ListView listView;
    Cat1_frag_adapter cat1FragAdapter;
    private LoadDB_AsyncTask task;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.frag_home,
                container, false);

        task = new LoadDB_AsyncTask(getContext());
        task.execute();

        dataBase = new DataBase(getActivity());
        sqLiteDatabase = dataBase.getReadableDatabase();
        cursor = dataBase.getCat1_Datas(sqLiteDatabase);

        listView = (ListView) rootView.findViewById(R.id.list);
        cat1FragAdapter = new Cat1_frag_adapter(getActivity(), R.layout.list_card_layout);
        listView.setAdapter(cat1FragAdapter);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            listView.setNestedScrollingEnabled(true);
        }

        if (cursor.moveToFirst()) {
            do {
                String id;
                String title;
                //id = cursor.getString(0);
                title = cursor.getString(2);

                dataProvider = new DataProvider(title);
                cat1FragAdapter.add(dataProvider);

            } while (cursor.moveToNext());
        }

        return rootView;
    }

How to fix this error and use Asynctask in my application?如何修复此错误并在我的应用程序中使用Asynctask tnx <3 tnx <3

Create your database tables in the onCreate of your DBHandler class.(Replace table name and columns)在 DBHandler 类的 onCreate 中创建数据库表。(替换表名和列)

Helper class帮手类

DBHandler Class: DBHandler 类:

public class DBHandler {
     private static String TAG = "DBHandler";
    static File dir = new File(Environment.getExternalStorageDirectory() + "");
    private static String MYDATABASE_NAME = dir + "/test/tablename.db";// dir+"/


    public static final String MYDATABASE_TABLE = "tablename";
    public static final int MYDATABASE_VERSION = 1;
    public static final String KEY_TDATE  = "TDATE" ;
    public static final String KEY_TARIFFFCBASIS = "TARIFFFCBASIS" ;



    private static final String SCRIPT_CREATE_DATABASE = "create table "
            + MYDATABASE_TABLE + " (" + KEY_ID
            + " integer primary key autoincrement, "
            +KEY_TDATE  + " text , "
                        +KEY_TARIFFFCBASIS  + "  text  );"


    private SQLiteHelper sqLiteHelper;
    private SQLiteDatabase sqLiteDatabase;

    private Context context;

    public DBHandler(Context c) {
        context = c;
         if(logger == null){
                logger = MasterLibraryFunction.getlogger(context, TAG);
                logger.info("In Side DBHandler(Context c)");
         }
    }

    public DBHandler openToRead() throws android.database.SQLException {
        sqLiteHelper = new SQLiteHelper(context, MYDATABASE_NAME, null,
                MYDATABASE_VERSION);
        sqLiteDatabase = sqLiteHelper.getReadableDatabase();
        return this;
    }

    public DBHandler openToWrite() throws android.database.SQLException {
        sqLiteHelper = new SQLiteHelper(context, MYDATABASE_NAME, null,
                MYDATABASE_VERSION);
        sqLiteDatabase = sqLiteHelper.getWritableDatabase();
        return this;
    }

    public void close() {
        sqLiteHelper.close();
    }
    /**
     * Check if the database exist
     * 
     * @return true if it exists, false if it doesn't
     */
    public boolean checkDataBase() {
        SQLiteDatabase checkDB = null;
        try {
            checkDB = SQLiteDatabase.openDatabase(MYDATABASE_NAME, null,
                    SQLiteDatabase.OPEN_READONLY);
            checkDB.close();
        } catch (SQLiteException e) {
            // database doesn't exist yet.
        }
        return checkDB != null ? true : false;
    }

    public int deleteAll() {
        return sqLiteDatabase.delete(MYDATABASE_TABLE, null, null);
    }

    public class SQLiteHelper extends SQLiteOpenHelper {

        public SQLiteHelper(Context context, String name,
                CursorFactory factory, int version) {

            super(context, name, factory, version);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {
            // TODO Auto-generated method stub
            db.execSQL(SCRIPT_CREATE_DATABASE); 
        }
    }
    }

AsyncTask code :异步任务代码:

     private class AsyncTaskRunner extends AsyncTask<String, String, String> {

      private String resp;

      @Override
      protected String doInBackground(String... params) {

      // Open DB file to write/read 
      db_helper = new DBHandler(getApplicationContext());
                db_helper.openToWrite();
// Complete your operation and close db_helper 
       return resp;
      }


      @Override
      protected void onPostExecute(String result) {
      // execution of result of Long time consuming operation
      }


          @Override
          protected void onPreExecute() {
           // Things to be done before execution of long running operation. For
       // example showing ProgessDialog
          }



     }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM