Java AsyncTask的最佳实践:通用参数与多参数?
如果一个Java AsyncTask的最佳实践:通用参数与多参数?,java,android,generics,android-asynctask,Java,Android,Generics,Android Asynctask,如果一个AsyncTask需要返回一个结果,那么通常会为回调创建一个接口,并通过构造函数传递类(实现该接口) 另外,如果AsyncTask(或任何其他非活动类)需要访问ApplicationContext,则构造函数中的上下文参数可以解决此问题 但是,如果我同时需要它们,并且我的调用者一方面是一个活动(因此也是我的上下文),另一方面也是我的实现接口,该怎么办 AsyncTask的构造函数应该看起来像Constructor1还是Constructor2?这里的最佳实践是什么?为什么 (如果正确答案
AsyncTask
需要返回一个结果,那么通常会为回调创建一个接口,并通过构造函数传递类(实现该接口)
另外,如果AsyncTask
(或任何其他非活动类)需要访问ApplicationContext
,则构造函数中的上下文
参数可以解决此问题
但是,如果我同时需要它们,并且我的调用者一方面是一个活动
(因此也是我的上下文
),另一方面也是我的实现接口,该怎么办
AsyncTask
的构造函数应该看起来像Constructor1
还是Constructor2
?这里的最佳实践是什么?为什么
(如果正确答案是Constructor2
:我是否应该将变量合并到一个通用类型T
?)
公共类MyTask扩展了AsyncTask{
回调;
Context;//更新:此处应使用WeakReference以避免内存泄漏!
//构造器1
MyTask(回调、上下文){
this.callback=回调;
this.context=上下文;
}
//建造师2
MyTask(T contextAndCallback){
this.callback=contextAndCallback;
this.context=contextAndCallback;
}
@凌驾
受保护的Void doInBackground(Void…参数){
//做需要上下文的事情
返回null;
}
@凌驾
受保护的void onPostExecute(void避免){
super.onPostExecute(避免);
callback.callbackMethod();
}
接口回调{
void callbackMethod();
}
}
致以最良好的祝愿,
温克勒
更新28.04
将AsyncTask作为匿名类实现
在我的活动
中将异步任务
实现为一个匿名类将是一个可能的解决方案-是的
但是在我的例子中,我需要在不同的地方执行AsyncTask
,所以我不得不多次实现它,这对我来说不是一个好的解决方案
只有这些选项吗?
我不知道我的问题是否还有其他解决办法。我刚想到那两个。如果有更好的解决方案(“最佳实践”),请告诉我 这取决于您要归档的内容
- 使用双参数构造函数,您可以灵活地使用任何活动、服务或任何地方的上下文,并在另一个对象(例如扩展的TextView)内实现回调,还可以通过 例如,实现回调接口。这使您可以对代码执行更多有用的操作,并在任何需要的地方接收回调事件
- 使用合并参数的方式,您将失去这种灵活性,但您可以确保绑定到此AsyncTask的对象具有上下文并实现回调。换句话说,必须将上下文和回调放在一起。如果您需要强制自己和其他开发人员在这些条件下使用此异步任务,那么这将非常有用。当然,有一种“黑客”方式,例如实现一个伪对象并从另一个方面获取上下文,但这将导致代码中隐藏的依赖项,以及大量的实现,这将导致代码不清楚,并且“非优雅”解决方案
请记住,上下文可以是GC,AcsiCt任务可以继续运行。您确定这些选项是唯一的吗?您是否已经探索了Builder模式?考虑用队列替换回调吗?在中定义,您不必为了获得所需内容而干扰构造函数。在
doInBackground
中访问上下文是导致内存泄漏的一种方法。我会使用WeakReference来代替它。@OldCurmudgeon我更新了问题,因此将上下文
传递给异步任务
是一种不好的做法。还有什么替代方法吗?如表示使用包含未被GC“监视”的poiner的WeakReference。然后,当您要在AsyncTask中使用上下文时,请检查是否仍处于活动状态
public class MyTask<T extends Context & Callback> extends AsyncTask<Void, Void, Void> {
Callback callback;
Context context; // Update: WeakReference<Context> should be used here to avoid memory leaks!
// Constructor 1
MyTask(Callback callback, Context context) {
this.callback = callback;
this.context = context;
}
// Constructor 2
MyTask(T contextAndCallback) {
this.callback = contextAndCallback;
this.context = contextAndCallback;
}
@Override
protected Void doInBackground(Void... params) {
// do stuff for which the context is needed for
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
callback.callbackMethod();
}
interface Callback {
void callbackMethod();
}
}