【问题标题】:Issues calling AsyncTask from SQLiteAssetHelper从 SQLiteAssetHelper 调用 AsyncTask 的问题
【发布时间】:2015-09-01 05:25:34
【问题描述】:

我当前的 Android 项目使用 SQLite 数据库。根据有关该主题的可用文档,数据库操作可能会长时间运行,具体取决于数据库的大小,因此建议使用 AsyncTask,特别是对于大型数据集。因此,我在我的数据库类中将操作实现为 AsyncTasks:

package com.hadleyresearch.apptest;

import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.AsyncTask;
import android.support.v4.content.LocalBroadcastManager;

import com.readystatesoftware.sqliteasset.SQLiteAssetHelper;

public class TscDatabase extends SQLiteAssetHelper{

    private static final String DATABASE_NAME = "database.db";
    private static final int DATABASE_VERSION = 1;

    final private Context db_context;

    //Action Strings
    public static final String DEVICE_LIST_AVAILABLE =
            "com.hadleyresearch.apptest.DEVICE_LIST_AVAILABLE";
    public static final String FUNCTION_LIST_AVAILABLE =
            "com.hadleyresearch.apptest.FUNCTION_LIST_AVAILABLE";
    public static final String DEVICE_PROFILE_AVAILABLE =
            "com.hadleyresearch.apptest.DEVICE_PROFILE_AVAILABLE";

    public TscDatabase(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
        db_context = context;
        // An alternate constructor can be used here to specify a
        // different database location, such as an SD card. This folder
        // must be available and permissions must be included to write
        // to it.
        //super(context, DATABASE_NAME, context.getExternalFilesDir(null).getAbsolutePath(), null, DATABASE_VERSION);
    }

    private class ListDevices extends AsyncTask<Void, Void, Cursor> {
        SQLiteDatabase db;

        @Override
        protected Cursor doInBackground(Void... params) {
            db = getReadableDatabase();
            String sqlTable = "Devices";
            String[] sqlColumns = {"_id", "deviceAddr", "deviceName", "deviceType"};
            Cursor c = db.query(sqlTable, sqlColumns, null, null, null, null, null);
            c.moveToFirst();
            return c;
        }

        @Override
        protected void onPostExecute(Cursor result) {
            broadcastUpdate(DEVICE_LIST_AVAILABLE, result);
            db.close();
        }

    }

    public class GetDevice extends AsyncTask<String, Void, Cursor> {
        SQLiteDatabase db;

        protected Cursor doInBackground(String... device) {
            db = getReadableDatabase();
            String sqlTable = "Devices";
            //String[] sqlColumns = {"_id", "deviceAddr", "deviceName", "deviceType"};
            String[] sqlColumns = null;
            String sqlWhere = "deviceProfile = ?";
            String[] whereArgs = new String[] {device.toString()};
            Cursor c = db.query(sqlTable, sqlColumns, sqlWhere, whereArgs, null, null, null);
            c.moveToFirst();
            return c;
        }

        protected void onPostExecute(Cursor result) {
            broadcastUpdate(DEVICE_PROFILE_AVAILABLE, result);
            db.close();
        }
    }

    //TODO - Implement listFunctions() command
    // listFunctions() - list out mappable TactSense Functions
    private class ListFunctions extends AsyncTask<Void, Void, Cursor> {
        SQLiteDatabase db;

        @Override
        protected Cursor doInBackground(Void... params) {
            db = getReadableDatabase();
            String sqlTable = "Functions";
            String[] sqlColumns = {"_id", "FunctionID", "FunctionName"};
            Cursor c = db.query(sqlTable, sqlColumns, null, null, null, null, null);
            c.moveToFirst();
            return c;
        }

        @Override
        protected void onPostExecute(Cursor result) {
            broadcastUpdate(FUNCTION_LIST_AVAILABLE, result);
            db.close();
        }

    }

    private void broadcastUpdate(final String action) {
        final Intent intent = new Intent(action);
        LocalBroadcastManager.getInstance(db_context).sendBroadcast(intent);
    }

    private void broadcastUpdate(final String action,
                                 final Cursor cursor) {
        final Intent intent = new Intent(action);
        intent.putExtras(cursor.getExtras());
        LocalBroadcastManager.getInstance(db_context).sendBroadcast(intent);
    }
}

之后,我从服务中调用 AsyncTask:

    @Override
    public IBinder onBind(Intent intent) {
        initialize();
        db = new TscDatabase(this);
        new db.GetDevice().execute(device);
        return mBinder;
    }

Android Studio 似乎知道 GetDevice 作为 db 方法的存在,因为它作为自动完成示例提供给我。但是,一旦自动完成,它会以红色突出显示并给我错误“无法解析符号 GetDevice”。我尝试清理项目,但无济于事。

有人可以指出我正确的方向吗?谢谢!

【问题讨论】:

    标签: android android-studio autocomplete android-asynctask


    【解决方案1】:

    你的类结构并不完全清楚,但这应该可行:

    @Override
    public IBinder onBind(Intent intent) {
        initialize();
        db = new TscDatabase(this);
        TscDatabase.GetDevice asyncDev = new TscDatabase.GetDevice();
        asyncDev.execute(device);
        return mBinder;
    }
    

    【讨论】:

    • 修复了“无法解析符号”错误,但是实现上述代码会引发以下错误:“com.hadleyresearch.apptest.TscDatabase”不是封闭类
    • 那么请在问题中添加TscDatabase的代码。
    • @Gaurav:下班回家;将 TscDatabase 的完整代码添加到问题中。非常感谢您或其他人可以提供的任何帮助,谢谢。
    猜你喜欢
    • 2014-07-19
    • 2011-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多