首页 > 解决方案 > Android - 如何在运行时动态选择具有不同泛型类型的 AsyncTask?

问题描述

首先让我说我是一位经验丰富的 Python 开发人员,在 Android/Java 生态系统中感到非常迷茫。我无法理解我所期望的应该是一个非常简单的多态性使用。我要解决的确切问题是我有一个活动需要在运行时根据传入的数据选择一个实现。

对于我的第一个功能,处理文件,我发现我需要实现一个 AsyncTask 来卸载读取文件和处理内容的实际工作。没问题,我实现了AsyncTask如下:

class UploadUriTask extends AsyncTask<Uri, Integer, String>

我在我的活动类中添加了一个类型的成员变量,UploadUriTask一切都很好:

private UploadUriTask task;

但是,我要添加的第二个功能是处理 URL 而不是文件。虽然我的第一个 AsyncTask 实现将其Params作为Uri[],但这个新任务需要将它们作为String[]

class UploadUrlTask extends AsyncTask<String, Integer, String>

在这一点上,我认为这两个类都扩展了AsyncTask,所以我可以将我的成员变量更改为AsyncTask

private AsyncTask task;

在创建活动时,我检查传入的数据类型并实例化适当的任务:

if (dataType.equals("image/*")) {
  task = new UploadUriTask(this);
}
else {
  task = new UploadUrlTask(this);
}

但是,现在当我的任何一个任务被调用时,Params类型将被转换为,Object[]而不是由我在调用时得到的错误所Uri[]证明:String[]task.execute(url)

java.lang.ClassCastException: java.lang.Object[] cannot be cast to java.lang.String[]

我觉得我只是在这里遗漏了一些非常明显的东西,但我似乎无法找出正确的搜索词。任何帮助将不胜感激。

标签: androidgenericspolymorphism

解决方案


问题在于private AsyncTask task;您的变量存储为原始类型,因此任何类型参数都将被删除。AsyncTask类型参数是无界的,因此Object当类型参数像这样被删除时,它们默认为 (java class root)。这就是为什么executethen 期望参数类型Object[]

如此处更详细地解释

如果您在声明变量时未指定类型,编译器将无法猜测类型。

根据例外,Object[]不能强制转换String[]String[]不是的子类Object[]


推荐阅读