У меня есть асинхронная задача, где у меня было предупреждение о том, что она должна быть статической, иначе могут возникнуть утечки.
Поэтому я использовал WeakReference, например:
private static class GetContacts extends AsyncTask<String, Void, Boolean> {
ProgressDialog dialog;
private WeakReference<Novinky> activityReference;
GetContacts(Novinky context) {
activityReference = new WeakReference<>(context);
}
@Override
protected void onPreExecute() {
// get a reference to the activity if it is still there
Novinky activity = activityReference.get();
if (activity == null || activity.isFinishing()) return;
super.onPreExecute();
dialog = new ProgressDialog(activity);
dialog.setMessage("Načítavam");
dialog.setTitle("Pripájam sa k serveru");
dialog.show();
dialog.setCancelable(false);
}
@Override
protected Boolean doInBackground(String... args) {
HttpHandler sh = new HttpHandler();
String url = "https://www...";
String jsonStr = sh.makeServiceCall(url);
if (jsonStr != null) {
try {JSONObject jsonObj = new JSONObject(jsonStr);
JSONArray actors = jsonObj.getJSONArray("result");
for (int i = 0; i < actors.length(); i++) {
JSONObject c = actors.getJSONObject(i);
Actors actor = new Actors();
actor.setLetter(c.getString("letter"));
actor.setNazov(c.getString("name"));
actor.setPerex(c.getString("perex"));
actorsList.add(actor);
}
} catch (final JSONException e) {
Novinky.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(Novinky.this.getApplicationContext(),
"Chyba dát: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}); }
return true;
} else {
Novinky.this.runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(Novinky.this.getApplicationContext(),
"Chyba internetového pripojenia.",
Toast.LENGTH_LONG).show();
}
});
return false;
}
}
protected void onPostExecute(Boolean result) {
// get a reference to the activity if it is still there
Novinky activity = activityReference.get();
if (activity == null || activity.isFinishing()) return;
super.onPostExecute(result);
dialog.dismiss();
adapter.notifyDataSetChanged();
}
}
Теперь это предупреждениеушел, но я все еще борюсь с некоторыми другими ошибками, которые возникли из-за моих изменений.
1 / actorsList.add(actor);
- в моем цикле for теперь отображается Нестатическое полеСсылка'ctorsList 'не может быть указана из статического контекста
2 / в операторе catch и else, где размещается runOnUiThread. У меня есть проблемы с Novinky.this.runOnUiThread
- нельзя ссылатьсяиз статического контекста
Если я просто заменю Novinky.this на WeakReference (activityReference), то там будет указано имя класса, поэтому не уверен, как правильно заменить Novinky.this в этих потоках.
Я также пытался использовать Novinky activity = activityReference.get();
и затем использовать activity.runOnUiThread
- это устраняет ошибку, но определение Novinky activity = activityReference.get();
имеет затем предупреждение В этом поле просачивается объект контекста
3 / Последний выпускмой onPostExecute - adapter.notifyDataSetChanged();
.Ошибка говорит: Нестатическое поле 'адаптер' нельзя ссылаться из статического контекста
ОБНОВЛЕНИЕ: Я решил это как-то, и теперь у меня нет ошибок, и приложение работает, однако все еще не уверен, правильно ли я решил:
Для 1 / я определил static ArrayList<Actors> actorsList;
в основном классе.
2 / в улове, а еще я определил final Novinky activity = activityReference.get();
, а затем:
activity.runOnUiThread
3 / в onPostExecute Я использовал activity.adapter.notifyDataSetChanged();