繁体   English   中英

如何在不锁定 UI 的情况下从 MySQLite 进行 SELECT?

[英]How to make a SELECT from MySQLite without locking the UI?

我的 Activity 有问题,这是一个旧的 Android 项目,我正在尝试对其进行重构以提高应用程序的性能。

在 onCreate 中,我正在从不同的表中选择数据,如下所示:

@Override
protected void onCreate(Bundle savedInstanceState) {
    LoadDataDB();
}

LoadDataDB看起来像这样:

public void LoadDataDB() {
    myDB = DataBaseHandler.getInstance(this);

    menuConstructors = myDB.getMenu();
    items = myDB.getTasti();
    variantiConstructors = myDB.getVarianti();
    printers = myDB.getPrinters();

    if (myDB.getFamiglie().size() != 0) {
        myDB.deleteFam();
    }
    for (VariantiConstructor variantiConstructor : variantiConstructors) {
        if (!variantiConstructor.getFamiglie().equals("") && !variantiConstructor.getFamiglie().equals("0")) {
            myDB.insertFamiglie(variantiConstructor.getFamiglie());
        }
    }

    modelFamiglie = myDB.getFamiglie();

}

然后像getMenu这样的每个函数都构建如下:

public ArrayList<MenuConstructor> getMenu() {
    database = this.getReadableDatabase();
    Cursor cursor = database.query(TABLE_MENU, null, null, null, null, null, null);
    ArrayList<MenuConstructor> contacts = new ArrayList<>();
    MenuConstructor contactModel;
    if (cursor.getCount() > 0) {
        for (int i = 0; i < cursor.getCount(); i++) {
            cursor.moveToNext();
            contactModel = new MenuConstructor(Integer.parseInt(cursor.getString(0)),
                    cursor.getString(1),cursor.getString(2),
                    cursor.getString(3));
            contacts.add(contactModel);
        }
    }
    cursor.close();
    database.close();
    return contacts;
}

当我打开 Activity 时,它会锁定在 SplashScreen 上,直到获取数据为止,那么我如何重构该函数以使其类似于异步,而不会锁定 UI?

为了防止锁定 UI,您需要在另一个线程上执行 SELECT 查询。 如果你会使用 Kotlin,我会推荐协程。

我开始使用ThreadPoolExecutor来完成这个任务。

您可以像这样在DatabaseHandler创建ThreadPoolExecutor的静态实例:

public static final ExecutorService databaseWriteExecutor =  Executors.newFixedThreadPool(NUMBER_OF_THREADS);

并使用此实例来执行您的查询。

要在另一个线程上执行指令,您可以使用:

DatabaseHandler.databaseWriteExecutor.execute(new Runnable() {
        @Override
        public void run() {
            LoadDataDB();
        }
    });

在此之后,您只需要解决一个小问题。 您需要在 UI 线程上执行 UI 更改。 这个问题有不止一种解决方案。

一种解决方案是创建 UI 线程 Looper 的处理程序并像这样发布您的 UI 更改。

另一种解决方案是创建LiveData实例并观察数据变化(观察者回调总是在 UI 线程上)

暂无
暂无

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

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