Я понимаю, что, возможно, делаю это немного задом наперед, но пока не нашел подходящего решения, и это самое близкое, что я нашел. Сначала я представляю представление «Вход в систему» пользователю и отправляю введенные учетные данные в веб-службу, которая проверяет учетные данные и возвращает HTTP 200, если вход выполнен успешно. После успеха я делаю HTTP-запрос JSON к тому же веб-сервису для загрузки списка объектов JSON. Затем эти объекты анализируются и помещаются в базу данных SQLite. Есть около 100 или более объектов, поэтому асинхронная задача привлекательна, поэтому я не блокирую интерфейс. Смысл этого состоит в том, чтобы отобразить ProgressBar (неопределенный) пользователю, говорящему, что в фоновом режиме выполняется работа, а затем вернуть его в отдельное намерение после заполнения БД. Вот фрагменты кода:
Подтверждение логина и вызов действия входа:
switch(statusCode) {
case 200:
PrepareLogin doLogin = new PrepareLogin();
doLogin.execute();
if (doLogin.getStatus().equals(AsyncTask.Status.FINISHED)) {
// Redirect to intent?
}
break;
case 401:
Toast.makeText(Login.this, "Invalid Username/Password", Toast.LENGTH_LONG).show();
}
Асинхронная задача с вспомогательными функциями в фоновом режиме:
private class PrepareLogin extends AsyncTask<Void,Void,Void> {
ProgressDialog dialog;
@Override
protected void onPreExecute() {
dialog = new ProgressDialog(Login.this);
dialog.setTitle(getString(R.string.get_login_dialog_title));
dialog.setMessage(getString(R.string.get_login_dialog_message));
dialog.setIndeterminate(true);
dialog.setCancelable(false);
dialog.show();
}
@Override
protected Void doInBackground(Void... params) {
Looper.myLooper().prepare();
Looper.myLooper().loop();
DBHelper dbHelp = new DBHelper(Login.this);
WSHelper wsHelp = new WSHelper();
long timeNow = System.currentTimeMillis();
dbHelp.resetDB(Login.this); // For dev environment only...remove in prod
dbHelp.create();
dbHelp.createUser(username, password, timeNow, "false");
dbHelp.close();
wsHelp.getEmployees(Login.this, username, password);
Looper.myLooper().quit();
return null;
}
protected void onPostExecute() {
Intent myIntent = new Intent(login.getContext(), Main.class);
startActivityForResult(myIntent, 0);
dialog.dismiss();
}
}
Единственный способ заставить это функционировать без выдачи ошибки «Обработчик должен подготовить петлитель» - это функция Looper.myLooper.prepare()
.
Я вижу в журналах, что соединение установлено и БД заполнена, но диалоговое окно продолжает вращаться и никогда не достигает функции onPostExecute()
задачи Async. Хотя он достигает линии Looper.myLooper().quit();
.
Есть предложения?