如何在不锁定 UI 的情况下从 MySQLite 创建 SELECT?
How to make a SELECT from MySQLite without locking the UI?
我的 Activity 有问题,这是一个旧的 Android 项目,我正在尝试对其进行一些重构以提高应用程序的性能。
在 onCreate 中,我正在对来自不同表的数据执行 SELECT,如下所示:
@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 线程循环程序的 Handler 并且 post 您的 UI 更改如下。
另一个解决方案是创建 LiveData 个实例并观察数据变化(观察者回调总是在 UI 线程上)
我的 Activity 有问题,这是一个旧的 Android 项目,我正在尝试对其进行一些重构以提高应用程序的性能。
在 onCreate 中,我正在对来自不同表的数据执行 SELECT,如下所示:
@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 线程循环程序的 Handler 并且 post 您的 UI 更改如下。
另一个解决方案是创建 LiveData 个实例并观察数据变化(观察者回调总是在 UI 线程上)