从 AsyncTask 内的活动访问实例变量

发布于 2024-11-07 19:19:14 字数 128 浏览 3 评论 0原文

我有一个 AsyncTask (在一个单独的文件中),它是在 活动。当我实例化 AsyncTask 时,我将活动作为 参数。我如何从以下位置访问活动的实例变量 AsyncTask 的 onPostExecute 方法?

谢谢!

I have an AsyncTask (in a separate file) which is invoked on an
activity. When I instantiate the AsyncTask, I send the activity as a
param. How can I access the acitivity's instance variables from the
onPostExecute method of the AsyncTask?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

云裳 2024-11-14 19:19:14

将 Activity 或 Context 传递给不是 Activity 内部(非静态)类的 AsyncTask 时必须小心 - 这是因为在这种情况下,生命周期Activity/ContextAsyncTask 是不同的,并且如果您持有 Activity/上下文时间比你应该的时间长,你会导致记忆泄漏。

您不应在 AsyncTask 中保留 Activity 或活动上下文本身,而应保留对 Activity 的 WeakReference。这将确保垃圾收集器 (GC) 在需要时可以回收与 Activity 关联的内存。

public class MyTask extends AsyncTask<..., ..., ...> {
    private WeakReference<MyActivity> mParentActivity = null;

    public MyTask(MyActivity parentActivity) {
        mParentActivity = new WeakReference<MyActivity>(parentActivity);
    }

    @Override
    public ... doInBackground(... params) {
        // do some stuff

        // now we do something that requires the context
        if (mParentActivity.get() != null) {
            // the WeakReference is still valid and hasn't been reclaimed
            // by the GC
            final MyActivity parentActivity = mParentActivity.get();
            parentActivity.doSomething();
        }

        // return result
    }
}

传递 Context 时,请尽可能尝试使用 ApplicationContext,因为这是寿命最长的上下文。

You must be careful when passing an Activity or Context to an AsyncTask that is not an inner (non-static) class of an Activity - this is because in this case the lifetime of the Activity/Context and the AsyncTask are different, and if you hold on to an Activity/Context for longer than you should you will cause memory leaks.

Rather than holding onto the Activity or activity context itself in your AsyncTask you should keep a WeakReference to the Activity. This will ensure that the memory associated with the Activity can be reclaimed by the garbage collector (GC) when needed.

public class MyTask extends AsyncTask<..., ..., ...> {
    private WeakReference<MyActivity> mParentActivity = null;

    public MyTask(MyActivity parentActivity) {
        mParentActivity = new WeakReference<MyActivity>(parentActivity);
    }

    @Override
    public ... doInBackground(... params) {
        // do some stuff

        // now we do something that requires the context
        if (mParentActivity.get() != null) {
            // the WeakReference is still valid and hasn't been reclaimed
            // by the GC
            final MyActivity parentActivity = mParentActivity.get();
            parentActivity.doSomething();
        }

        // return result
    }
}

When passing a Context always try to use the ApplicationContext where possible as this is the longest-lived context.

痴梦一场 2024-11-14 19:19:14

与程序员 Bruce 的答案类似,但不是通过 AsyncTask 本身将 Activity 作为参数传递,只需添加一个构造函数来获取父 Activity。我自己的代码示例...

public class FileDownloader extends AsyncTask<..., ..., ...> {
    private MyActivity parentActivity = null;

    public FileDownloader(MyActivity parentActivity) {
        this.parentActivity = parentActivity;
    }
}

当您在 Activity 中创建它时,只需执行以下操作...

FileDownloader fdl = new FileDownloader(this);
fdl.execute(...);

编辑:在回复您的评论时,请确保将 mLogin 声明为 public然后使用...

parentActivity.mLogin

如果这不起作用,请尝试...

((MyActivity)parentActivity).mLogin

Similar to Programmer Bruce's answer but instead of passing the Activity as a Param through the AsyncTask itself, simply add a constructor to take the parent Activity. Example from my own code...

public class FileDownloader extends AsyncTask<..., ..., ...> {
    private MyActivity parentActivity = null;

    public FileDownloader(MyActivity parentActivity) {
        this.parentActivity = parentActivity;
    }
}

When you create it in your Activity just do this...

FileDownloader fdl = new FileDownloader(this);
fdl.execute(...);

EDIT: In reply to your comment, make sure mLogin is declared as public then use...

parentActivity.mLogin

If that doesn't work, try...

((MyActivity)parentActivity).mLogin
感情废物 2024-11-14 19:19:14

您可以从 AsyncTask 进行扩展,然后您可以传入任意数量的任意参数,无需传递对整个 Activity 的引用。

 new CustomTask().execute(param1, param2, param3);

您可以在 doInBackground 中引用:

 public Void doInBackground(Object... params) {
    Integer id = (Integer) params[0];
    String name = (String) params[1];
    ....
 } 

You can extend from AsyncTask<Object, x x>, and you can then pass in any number of arbitrary parameters you like, no need to pass around reference to the whole Activity.

 new CustomTask().execute(param1, param2, param3);

Which you can reference in your doInBackground:

 public Void doInBackground(Object... params) {
    Integer id = (Integer) params[0];
    String name = (String) params[1];
    ....
 } 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文