Я использую ArrayAdapter для отображения списка элементов, и у меня есть поток AsyncTask, который загружает эти элементы через HttpURLConnection. Я хочу, чтобы этот список элементов был первым, что пользователь видит при запуске приложения. Я знаю, что это неудачная практика, чтобы приложение ожидало запуск для завершения этой загрузки, поэтому я сделал загрузку AsyncTask. У меня есть локальные данные, хранящиеся в SharedPreferences, которые отображаются пока.Загрузка данных в фоновом режиме, обновление адаптера?
К сожалению, я не могу изменить адаптер непосредственно из AsyncTask.
java.lang.IllegalStateException: Make sure the content of your adapter is not modified from a background thread, but only from the UI thread.
Я предполагаю, что я просто нужен сигнал, чтобы уведомить поток пользовательского интерфейса, что фоновая задача выполнена; Я могу изменить свой код для загрузки данных в другую структуру данных, которая не является адаптером, а затем поток пользовательского интерфейса может добавить его в адаптер, как только он узнает, что задача завершена. Я не знаю, как это сделать, но не дожидаясь завершения AsyncTask, что равносильно тому, что я ожидал загрузки данных в основном потоке пользовательского интерфейса.
Как мне это сделать?
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
...
LoadAnnouncementDataFromAPI announcementAPIQuery = new LoadAnnouncementDataFromAPI();
announcementAPIQuery.execute();
...
}
...
private class LoadAnnouncementDataFromAPI extends AsyncTask<String, String, String> {
private String announcementAPI = "http://10.0.2.2:3000/announcements";
@Override
protected String doInBackground(String... params) {
try {
URL url = new URL(announcementAPI);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
StringBuilder stringBuilder = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
stringBuilder.append(line).append("\n");
}
bufferedReader.close();
return stringBuilder.toString();
} catch (IOException e) {
return "";
}
}
@Override
protected void onPostExecute(String queryResponse) {
if (queryResponse != null && !queryResponse.equals("")) {
try {
JSONArray apiResponse = new JSONArray(queryResponse);
for (int i = 0; i < apiResponse.length(); i++) {
JSONObject announcementJSON = apiResponse.getJSONObject(i);
if (!announcementJSON.getString("id").equals("")) {
mAnnouncementAdapter.items.add(new AnnouncementBlock(announcementJSON));
}
}
mAnnouncementAdapter.notifyDataSetChanged();
} catch (JSONException e) {
return;
}
}
}
}
}
Использование publishProgress – Submersed
Я не понимаю, почему это интересно, что вы должны ждать, пока не будет получать данные, прежде чем показывать его? – Divers