2011-05-16 100 views
1

我有一个在 活动中调用的AsyncTask(在单独的文件中)。当我实例化AsyncTask时,我将该活动作为 参数发送。如何从 AsyncTask的onPostExecute方法访问活动的实例变量?从AsyncTask中的活动访问实例变量

谢谢!

回答

1

与程序员Bruce的答案类似,但不是通过AsyncTask本身将Activity作为参数传递,只需添加一个构造函数即可获取父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

我怎么能在这之后访问实例变量?我无法做到parentActivity.mLogin,我错过了一些东西... – user177468 2011-05-17 02:26:12

+0

@ user177468:在我的答案结尾处查看编辑。 – Squonk 2011-05-17 03:44:19

10

传递一个活动或ContextAsyncTask不是内部(非静态)类的活动的时,必须要小心 - 这是因为在这种情况下,Activity/Context的寿命和AsyncTask是不同的,如果你坚持一个Activity/Context更长的时间比你应该会导致内存泄漏。

您应该在活动中保留WeakReference,而不是坚持您的AsyncTask中的活动或活动上下文本身。这将确保与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如果可能的话,因为这是最长寿的上下文。

+0

'parentActivity.doSomething()'在后台线程上被调用。如果该方法修改了UI,你会得到'CalledFromWrongThreadException'。在'postExecute'回调中运行这样的方法。 – tomrozb 2013-03-11 22:45:35

0

您可以从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]; 
    .... 
}