Доступ к переменным экземпляра из действия внутри AsyncTask - PullRequest
1 голос
/ 17 мая 2011

У меня есть AsyncTask (в отдельном файле), который вызывается на деятельность. Когда я создаю экземпляр AsyncTask, я отправляю действие как пары. Как я могу получить доступ к переменным экземпляра активности из onPostExecute метод AsyncTask?

Спасибо!

Ответы [ 3 ]

10 голосов
/ 17 мая 2011

Вы должны быть осторожны при передаче Activity или Context в AsyncTask, который не является внутренним (нестатическим) классом Activity - это потому, что в этом случае время жизни Activity / Context и AsyncTask различаются, и если вы удерживаете Activity / Context дольше, чем вы, это вызовет утечки памяти.

Вместо того, чтобы удерживать действие или контекст действияСам в своем AsyncTask вы должны оставить WeakReference в Деятельности.Это гарантирует, что память, связанная с Activity, может быть возвращена сборщиком мусора (GC) при необходимости.

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, где это возможно, так как этосамый долгоживущий контекст.

1 голос
/ 17 мая 2011

Аналогично ответу программиста Брюса, но вместо того, чтобы передавать Activity в качестве Param через сам AsyncTask, просто добавьте конструктор для получения родительского Activity.Пример из моего собственного кода ...

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

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

Когда вы создаете его в своей деятельности, просто сделайте это ...

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

РЕДАКТИРОВАТЬ: В ответ наВаш комментарий, убедитесь, что mLogin объявлен как public, затем используйте ...

parentActivity.mLogin

Если это не сработает, попробуйте ...

((MyActivity)parentActivity).mLogin
0 голосов
/ 17 мая 2011

Вы можете расширить от AsyncTask<Object, x x>, и затем вы можете передать любое количество произвольных параметров, которые вам нравятся, без необходимости передавать ссылку на всю активность.

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

На что вы можете ссылаться в doInBackground:

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