AsyncTask的最佳实践:泛型参数与多个参数?

时间:2017-04-28 07:18:58

标签: java android generics android-asynctask

如果AsyncTask需要返回结果,则通常会为回调创建一个接口,并通过构造函数传递类(实现接口)。

此外,如果AsyncTask(或任何其他非活动类)需要访问ApplicationContext,构造函数中的Context参数可以解决此问题。

但是如果我需要两者并且我的来电者一方面是Activity(因此我的Context),另一方面也是我的实施界面?

AsyncTask的构造函数应该是Constructor1还是Constructor2?这里最好的做法是什么?为什么?

(如果正确的答案是Constructor2:我应该将我的变量合并到一般类型T的单个变量吗?)

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();
    }
}

祝你好运, winklerrr

更新28.04

将AsyncTask实现为匿名类

在我的AsyncTask中实现Activity作为匿名类将是一种可能的解决方案 - 是的。

但在我的情况下,我需要在不同的地方AsyncTask - 所以我会多次实施它,这对我来说不是一个好的解决方案。

这些是唯一的选择吗?

我不知道我的问题是否有其他解决方案。我想出了那两个。如果有更好的解决方案(“最佳实践”),请告诉我!

1 个答案:

答案 0 :(得分:0)

这取决于您要归档的内容。

  • 使用两个参数构造函数,您可以灵活地使用任何活动,服务或任何地方的上下文,并在另一个对象中实现回调,例如扩展的TextView,并使用绑定到此的上下文查看,通过https://developer.android.com/reference/android/view/View.html#getContext() 例如,实现你的回调接口。这使您可以使用代码执行更多有用的操作,并随时随地接收回调事件。

  • 使用合并参数方式会失去这种灵活性,但您确定绑定到此AsyncTask的对象具有上下文并实现回调。换句话说,上下文和回调是必须的。如果你强迫自己和其他开发人员在这些条件下使用这个AsyncTask会有用,当然有一种“hackish”方式,比如实现一个假对象并从另一边获取上下文,但这会引导你隐藏您的代码和许多工具中的依赖项将导致您使用不清楚的代码和“非优雅”解决方案。

从架构视图中,“最佳方式”,或者他们在大学时向我们展示的地方,永远不会合并参数和返回,以使您的代码从另一方更可重用,并避免隐藏的依赖关系。您也可以尝试其他方法,例如使用服务或队列。

请记住,上下文可以是GC,AsyncTask可以继续运行。