Android просит не запрашивать в основном потоке, но asy c запросы задерживаются - PullRequest
0 голосов
/ 02 мая 2020

Как видно из заголовка, android нужны запросы вне основного потока, так как в противном случае будет java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time. Так что мне удалось сделать асин c запросы, как объясняют многие учебные пособия, но это не имеет особого смысла (пока), которого я мог достичь.

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 равно нулю, запускается другое действие, в противном случае оно продолжает свой поток. Проблема в том, что когда я отлаживаю его (что, конечно, замедляет) 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 запросы, не задерживая их? select query действительно работает, я не думаю, что нужно публиковать его (потому что он возвращает уникальный результат, когда я debug ), но он возвращает ноль, когда я запускаю код без отладки !! Пожалуйста, помогите.

1 Ответ

0 голосов
/ 02 мая 2020

РЕШЕНИЕ:

Как предложил @ user7041125, но вместо этого я создал новый класс с интерфейсом для вызова методов обратно в действие, например:

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 этого класса. Действие реализует IntPeriodoBridge, и таким образом я могу установить для объекта результата запроса класс действия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...