【问题标题】:android WeakReference of activity活动的android弱引用
【发布时间】:2019-03-08 09:49:45
【问题描述】:

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

所以我使用了这样的 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 的问题 - 无法从静态上下文中引用

如果我只是将 Novinky.this 替换为 WeakReference (activityReference),那么它会说类名是预期的,所以不确定如何在这些线程中正确替换 Novinky.this。

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

3/ 最后一期在我的 onPostExecute - adapter.notifyDataSetChanged();。错误说:不能从静态上下文中引用非静态字段“适配器”

更新:我以某种方式解决了它,现在我没有错误并且应用程序正在运行,但仍然不确定我是否正确解决了它:

对于 1/ 我在主类中定义了 static ArrayList&lt;Actors&gt; actorsList;

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

然后:

activity.runOnUiThread

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

【问题讨论】:

  • 应该已经接受了 AsyncTask 类的构造函数中的数组列表。

标签: android android-asynctask weak-references


【解决方案1】:

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

activityReference.get().actorsList

【讨论】:

  • 我删除了静态定义并使用了activityReference.get().actorsList。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多