gpt4 book ai didi

java - Android 要求不要在主线程上查询,但异步查询正在延迟

转载 作者:行者123 更新时间:2023-12-01 16:58:17 26 4
gpt4 key购买 nike

正如标题所示,android 需要在主线程之外进行查询,因为它会抛出 java.lang.IllegalStateException: Cannot access database on the main thread because it might mightlock the UI for a long period of time 否则。因此,我设法按照许多教程的说明进行异步查询,但(到目前为止)它并没有我所能实现的那么有意义。

public class NewDetalleDiarioActivity extends AppCompatActivity {

@Override
protected void onStart() {
super.onStart();
db = Room.databaseBuilder(getApplicationContext(), AppDatabase.class, "database").build();
findPeriodo();
findDiario();
}

private void findPeriodo() {
periodo = Diarios.getPeriodo(db);
if (periodo == null) {
Intent intent = new Intent(NewDetalleDiarioActivity.this, NewPeriodoActivity.class);
startActivity(intent);
}
}

问题/错误:

如果periodo为空,则启动另一个 Activity ,否则该 Activity 将继续其线程。问题是,当我调试它时(当然,这会减慢进程)periodo 从数据库返回一个实例,但是当我在没有调试的情况下运行代码时,periodo 是空。

public class Diarios {
public static Periodo getPeriodo(AppDatabase db) {
return Factory.getIntPeriodo().getPeriodo(db);
}
}

.

public class Factory {
private static IntPeriodo intPeriodo;
public static IntPeriodo getIntPeriodo() {
return (intPeriodo == null) ? intPeriodo = new BusPeriodo() : intPeriodo;
}
}

.

public class BusPeriodo implements IntPeriodo {
// I don't think it's necessary to post the interface...
@Override
public Periodo getPeriodo(final AppDatabase db) {
final Periodo[] periodo = new Periodo[1];
AsyncTask.execute(new Runnable() {
@Override
public void run() { //the async query that is driving me mad.
periodo[0] = db.periodoDao().getPeriodo(new Date());
}
});
return periodo[0];
}
}

在不延迟查询的情况下进行select查询的正确方法是什么?选择查询确实有效,我认为没有必要发布它(因为当我调试时它返回一个唯一的结果),但是当我调试时它返回null无需调试即可运行代码!请帮忙。

最佳答案

解决方案:

正如 @user7041125 所建议的,但我创建了一个带有接口(interface)的新类来将方法调用回 Activity ,如下所示:

public class PeriodoBridge extends AsyncTask<Void, Void, Periodo> implements IntPeriodoBridge {

private WeakReference<Activity> weakActivity;
private IntPeriodoBridge caller; //implement this interface in the activity which needs to query
private AppDatabase db;
private Periodo periodo;

public PeriodoBridge(Activity activity, IntPeriodoBridge caller, AppDatabase db) {
weakActivity = new WeakReference<>(activity);
this.caller = caller; // assign activity instance to the local interface instance
this.db = db;
executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}

@Override
protected Periodo doInBackground(Void... voids) {
periodo = Diarios.getPeriodo(db);
return periodo;
}

@Override
protected void onPostExecute(Periodo periodo) {
Activity activity = weakActivity.get();
if (activity == null) {
return;
}
if (periodo == null) {
Intent intent = new Intent(activity, NewPeriodoActivity.class);
activity.startActivity(intent);
} else {
setPeriodo(periodo);
}
}

@Override //this is an interface method (IntPeriodoBridge)
public void setPeriodo(Periodo periodo) {
caller.setPeriodo(periodo); //I can set the query result back to the activity class with this
}

调用该类的init方法。该 Activity 实现了 IntPeriodoBridge,这样我就可以将查询结果对象设置为 Activity 类。

关于java - Android 要求不要在主线程上查询,但异步查询正在延迟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61554518/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com