活动的Android WeakReference

时间:2019-03-08 09:49:46

标签: android android-asynctask weak-references

我有一个异步任务,在其中我警告它应该是静态的,否则可能发生泄漏。

所以我使用了这样的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循环中说不能从静态上下文中引用非静态字段'actorsList'

2 / 在放置runOnUiThread的catch和else语句中,我遇到Novinky.this.runOnUiThread的问题-无法从静态上下文中引用

如果我只用WeakReference(activityReference)替换Novinky.this,那么它说应该是类名,所以不确定在这些线程中如何正确替换Novinky.this。

我也尝试过使用Novinky activity = activityReference.get();,然后使用activity.runOnUiThread-这样可以消除错误,但是Novinky activity = activityReference.get();的定义随后警告此字段泄漏了上下文对象

3 / 最后一个问题在我的onPostExecute-adapter.notifyDataSetChanged();中。错误显示:不能从静态上下文中引用非静态字段'adapter'

更新:我以某种方式解决了该问题,现在我没有任何错误,并且该应用正在运行,但是仍然不确定是否能够正确解决该问题:

对于1 /,我在主类中定义了static ArrayList<Actors> actorsList;

2 /在捕获中,否则我定义了  final Novinky activity = activityReference.get();

然后:

activity.runOnUiThread

3 /在onPostExecute中,我使用了activity.adapter.notifyDataSetChanged();

1 个答案:

答案 0 :(得分:1)

您应该能够以与访问适配器相同的方式访问列表的实例:

activityReference.get().actorsList