#java #android #android-fragments #android-asynctask #fragment-oncreateview
Вопрос:
У меня есть фрагмент Android, который запрашивает веб-страницу с помощью AsyncTask и извлекает заголовок страницы, который должен отображаться в текстовом представлении. Я вызываю AsyncTask в onCreateView().
Проблема в том, что существует заметная задержка до завершения AsyncTask и создания и отображения представления фрагмента. Похоже, он не работает асинхронно.
Код выглядит следующим образом:
GetWebsiteAsyncTask getWebsiteAsyncTask = new GetWebsiteAsyncTask(); String websiteTitle = getWebsiteAsyncTask.execute().get(); websiteViewModel.setTitle(websiteTitle);
С помощью AsyncTask, определенной как:
class GetWebsiteAsyncTask extends AsyncTasklt;Void, Void, Stringgt; { private static final String TAG = GetWebsiteAsyncTask.class.getName(); @Override protected String doInBackground(Void... voids) { try { Document doc = Jsoup.connect("https://www.google.com").get(); return doc.title(); } catch (Exception e) { Log.e(TAG, Log.getStackTraceString(e)); } return null; } }
Комментарии:
1. подсказка: onPostExecute проверьте документацию
2. Ладно, у меня все получилось. Я думаю, что на самом деле было очевидно, что мне понадобится обратный вызов для завершения асинхронного метода. Вызов get() должен быть похож на использование .Result в асинхронном методе C#.
Ответ №1:
Следуя совету Селвина в комментарии, я изменил код для использования делегата обратного вызова в AsyncTask следующим образом:
1.
public interface AsyncResponse { void processFinish(String output); }
class GetWebsiteAsyncTask extends AsyncTasklt;Void, Void, Stringgt; { public AsyncResponse delegate = null; @Override protected void onPostExecute(String result) { delegate.processFinish(result); } }
public class WebsiteFragment extends Fragment implements AsyncResponse
GetWebsiteAsyncTask getWebsiteAsyncTask = new GetWebsiteAsyncTask(); getWebsiteAsyncTask.delegate = this; getWebsiteAsyncTask.execute();
@Override public void processFinish(String output) { websiteViewModel.setTitle(output); }
Комментарии:
1. Пожалуйста, обратите внимание, что AsyncTask устарел и больше не должен использоваться.
2. Спасибо за подсказку. Я изменил код для использования: ExecutorService исполнитель = Исполнители.newSingleThreadExecutor();