【问题标题】:Is my LIST<E> AsyncTask understanding correct?我的 LIST<E> AsyncTask 理解正确吗?
【发布时间】:2013-02-07 08:48:18
【问题描述】:

我以前通过简单地添加 int 或字符串来使用标准形式的 List 数组,但现在我正在使用 List 方法查看集合。

我目前正在查看的代码实现了以下类:

public class GeoNamesAsyncTask extends AsyncTask<String, Void, List<GeoName>> {

private Context ctx = null;

public GeoNamesAsyncTask(Context ctx) {
    this.ctx = ctx;
}

@Override
protected List<GeoName> doInBackground(String... arg0) {
    return new GeoNamesService().searchPostalCode(arg0[0]);
}

@Override
protected void onPostExecute(List<GeoName> result) {
    this.populateActivity(result);
}

此方法所在的类扩展了 AsyncTask 超类,并具有一个标准构造函数,可从调用它的类设置上下文。至此,我明白了。

现在,当“doInBackGround”方法的 AsyncTask 类的重写方法时,我有点迷失了。

我了解该代码正在返回从 GeoNameService 类的“searchPostalCode”方法运行的地名列表(在此代码的情况下)。传递的字符串是用户输入的邮政编码。有人能告诉我为什么三个点是用字符串传递的吗?我会认为它只是'string arg0'而不是'string ... arg0'?

一旦 doInBackGround 方法返回,我是否认为 'onPostExecute' 方法总是在此之后直接调用?

我也读过用“doInBackGround”方法调用方法是不好的做法。

当我运行此代码并尝试输入字母和数字的组合(即“E4”)时,我在 doInBackGround 方法中遇到错误,但整数(例如“24501”)很好,如图所示。

02-21 20:05:18.461: E/AndroidRuntime(352): FATAL EXCEPTION: AsyncTask #1
02-21 20:05:18.461: E/AndroidRuntime(352): java.lang.RuntimeException: An error occured while executing doInBackground()
02-21 20:05:18.461: E/AndroidRuntime(352):  at android.os.AsyncTask$3.done(AsyncTask.java:200)
02-21 20:05:18.461: E/AndroidRuntime(352):  at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
02-21 20:05:18.461: E/AndroidRuntime(352):  at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
02-21 20:05:18.461: E/AndroidRuntime(352):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
02-21 20:05:18.461: E/AndroidRuntime(352):  at java.util.concurrent.FutureTask.run(FutureTask.java:137)
02-21 20:05:18.461: E/AndroidRuntime(352):  at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
02-21 20:05:18.461: E/AndroidRuntime(352):  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
02-21 20:05:18.461: E/AndroidRuntime(352):  at java.lang.Thread.run(Thread.java:1096)
02-21 20:05:18.461: E/AndroidRuntime(352): Caused by: com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: E4 6AA
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.google.gson.internal.bind.TypeAdapters$7.read(TypeAdapters.java:232)
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.google.gson.internal.bind.TypeAdapters$7.read(TypeAdapters.java:222)
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:81)
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60)
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.google.gson.Gson.fromJson(Gson.java:795)
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.google.gson.Gson.fromJson(Gson.java:761)
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.google.gson.Gson.fromJson(Gson.java:710)
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.google.gson.Gson.fromJson(Gson.java:682)
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.example.restfulweb.GeoNamesService$DataWrapper.fromJson(GeoNamesService.java:85)
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.example.restfulweb.GeoNamesService.searchPostalCode(GeoNamesService.java:41)
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.example.restfulweb.GeoNamesAsyncTask.doInBackground(GeoNamesAsyncTask.java:21)
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.example.restfulweb.GeoNamesAsyncTask.doInBackground(GeoNamesAsyncTask.java:1)
02-21 20:05:18.461: E/AndroidRuntime(352):  at android.os.AsyncTask$2.call(AsyncTask.java:185)
02-21 20:05:18.461: E/AndroidRuntime(352):  at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
02-21 20:05:18.461: E/AndroidRuntime(352):  ... 4 more
02-21 20:05:18.461: E/AndroidRuntime(352): Caused by: java.lang.NumberFormatException: E4 6AA
02-21 20:05:18.461: E/AndroidRuntime(352):  at org.apache.harmony.luni.util.FloatingPointParser.initialParse(FloatingPointParser.java:130)
02-21 20:05:18.461: E/AndroidRuntime(352):  at org.apache.harmony.luni.util.FloatingPointParser.parseDouble(FloatingPointParser.java:281)
02-21 20:05:18.461: E/AndroidRuntime(352):  at java.lang.Double.parseDouble(Double.java:287)
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.google.gson.stream.JsonReader.nextInt(JsonReader.java:599)
02-21 20:05:18.461: E/AndroidRuntime(352):  at com.google.gson.internal.bind.TypeAdapters$7.read(TypeAdapters.java:230)

【问题讨论】:

  • 你能发布你的 GeoName 对象的代码吗?此行指向 GSON 错误,可能与您的注释或您尝试映射数据的方式有关:02-21 20:05:18.461: E/AndroidRuntime(352): Caused by: com.google.gson.JsonSyntaxException : java.lang.NumberFormatException: E4 6AA
  • 另外,是的,您不直接调用“doInBackground()”。您想调用“execute()”方法来处理 AsyncTask 的所有其他必要调用。

标签: java android list android-asynctask


【解决方案1】:

是的,您对 AsyncTask 所做的事情看起来是正确的。

只有 UI 线程应该修改 UI,并且 doInBackground 方法不在 UI 线程中运行。 onPostExecute 是。

好吧,堆栈跟踪是不言自明的,JSON 试图将您的“E4”解析为一个数字,但未能这样做。看起来你应该只提供可解析的数字:)

【讨论】:

    【解决方案2】:

    传递的字符串是用户输入的邮政编码。谁能告诉我 为什么三个点与字符串一起传递?我会想到的 会不会是 'string arg0' 而不是 'string... arg0'?

    它们被称为variable arity arguments 并被提供以便 AsyncTask 在参数方面可以更加灵活。只要有 1 个或多个参数,通过 arg0[0] 访问是访问提供的参数的正确方法。

    但如果你有不止一个,你可以遍历它们:

    例如:

    for (String s: arg0)
    {
      System.out.println (s);
    }
    

    一旦 doInBackGround 方法返回,我的想法是否正确 'onPostExecute' 方法总是在这之后直接调用?

    是的,见documentation

    onPostExecute(Result),后台后在UI线程上调用 计算结束。背景计算的结果是 作为参数传递到这一步。


    我也读过用 a 调用方法是不好的做法 'doInBackGround' 方法。

    如果那个方法修改了UI Thread是的,那就不好了。

    在我运行此代码的那一刻,并尝试输入以下组合 字母和数字,即“E4”,我在 doInBackGround 方法,但整数如 '24501' 很好,如 显示。

    02-21 20:05:18.461: E/AndroidRuntime(352): Caused by: java.lang.NumberFormatException: E4 6AA
    

    基于堆栈跟踪,JsonReader.nextInt() 使用底层方法 Double.parseDouble(),它不适用于字母。

    【讨论】:

    • 非常感谢您解决了这个问题。我可以看到 [0] 看起来是某种类型的第一个数组对象,并且我只传递了一个非常有意义的变量。解析异常原来是一个简单的例子,当它应该是一个字符串时将一个字段设置为一个 int。
    【解决方案3】:
    1. 3 个点 (...) 用于变量参数,也称为 varargs。更多这里Java, 3 dots in parameters

    2. onPostExecute()doInBackground() 完成执行后被调用。

    3. 你可以调用doInBackground()中的任何方法,只是注意不要触摸GUI。

    4. searchPostalCode() 的某个地方,您试图将 E4 解析为一个数字,这就是您遇到异常的原因。

    【讨论】:

      猜你喜欢
      • 2019-05-03
      • 1970-01-01
      • 2012-01-27
      • 2021-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多