Слабый андроид Ссылка деятельности - PullRequest
0 голосов
/ 08 марта 2019

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

Поэтому я использовал 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();

1 Ответ

1 голос
/ 08 марта 2019

Вы должны иметь доступ к своему экземпляру списка так же, как вы обращаетесь к адаптеру:

activityReference.get().actorsList
...