Android 异步任务创建导致崩溃

Android 异步任务创建导致崩溃,android,android-asynctask,Android,Android Asynctask,扩展AsyncTask的自定义类存在一些问题。我的应用程序是针对安卓4.0.3的,下面的代码可以很好地为30多人测试。然而,当我调用新的AsyncRequest时,有两个用户看到应用程序崩溃,如下所示 我有一个正在工作的记录器,它正在记录到用户存储上的文本文件中,而不记录AsyncRequest构造函数中的条目。所以我必须假设崩溃发生在调用构造函数之前 正在经历这次崩溃的两台设备中,有一台运行的是安卓4.0.4。不确定其他设备正在运行什么。不幸的是,我无法访问这两个设备,因此无法看到logcat

扩展AsyncTask的自定义类存在一些问题。我的应用程序是针对安卓4.0.3的,下面的代码可以很好地为30多人测试。然而,当我调用新的AsyncRequest时,有两个用户看到应用程序崩溃,如下所示

我有一个正在工作的记录器,它正在记录到用户存储上的文本文件中,而不记录AsyncRequest构造函数中的条目。所以我必须假设崩溃发生在调用构造函数之前

正在经历这次崩溃的两台设备中,有一台运行的是安卓4.0.4。不确定其他设备正在运行什么。不幸的是,我无法访问这两个设备,因此无法看到logcat输出

任何关于对象创建导致崩溃的原因的输入都将非常感谢

String url = "www.google.com";

new AsyncRequest(callback, context).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url);
下面是完整的AsyncRequest类

public class AsyncRequest extends AsyncTask<String, String, String>{

HttpURLConnection connection;
InputStream inStream;
IApiCallback callback;
Context context_;

public AsyncRequest(IApiCallback callback, Context context) {
    // Log entry added for testing. Never gets called.
    FileLogger.getFileLogger(context).ReportInfo("Enter AsyncRequest Constructor");
    this.callback = callback;
    context_ = context;
}

@Override
protected String doInBackground(String... uri) {

    try {
        URL url = new URL(uri[0] + "?format=json");
        FileLogger.getFileLogger(context_).ReportInfo("Async Request: Sending HTTP GET to " + url);

        connection = (HttpURLConnection) url.openConnection();
        connection.setConnectTimeout(5000);
        connection.setReadTimeout(5000);
        connection.addRequestProperty("Accept-Encoding", "gzip");
        connection.addRequestProperty("Cache-Control", "no-cache");

        connection.connect();

        String encoding = connection.getContentEncoding();

        // Determine if the stream is compressed and uncompress it if needed.
        if (encoding != null && encoding.equalsIgnoreCase("gzip")) {
            inStream = new GZIPInputStream(connection.getInputStream());

        }  else {
            inStream = connection.getInputStream();
        }

        if (inStream != null) {
            // process response
            BufferedReader br = new BufferedReader(new InputStreamReader(inStream));
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }

            return sb.toString();  

        }

    } catch (SocketTimeoutException e) {
        FileLogger.getFileLogger(context_).ReportException("Async Request: SocketTimeoutException", e);
        Log.i("AsyncRequest", "Socket Timeout occured");
    } catch (MalformedURLException e) {
        FileLogger.getFileLogger(context_).ReportException("Async Request: MalformedUrlException", e);
    } catch (IOException e) {
        FileLogger.getFileLogger(context_).ReportException("Async Request: IOException", e);
        Log.i("doInBackground:","IOException");

        if (e != null && e.getMessage() != null) {
            Log.i("doInBackground:",e.getMessage());
        }
    } catch (Exception e) {
        FileLogger.getFileLogger(context_).ReportException("Async Request: Exception", e);

    } finally {
        if (connection != null)
            connection.disconnect();
    }

    return null;
}

@Override
protected void onPostExecute(String result) {

    if (result != null) 
        FileLogger.getFileLogger(context_).ReportInfo("Async Request: Response is valid");
    else
        FileLogger.getFileLogger(context_).ReportInfo("Async Request: Invalid response");

    callback.Execute(result);
}
}

首先,请记住,
executeOnExecutor()
在Api 11之前不可用。您已经说过问题出在4.0.4设备上,但请记住这一点

以下是我将采取的步骤,以排除问题所在。似乎您已经用所有这些
ReportInfo()
语句完成了其中一些

首先,我假设您对
GetServerInfoAsync
的调用在
try…catch
中,对吗?我检查是因为您使用了
Throw
。另外,您已经添加了日志记录来检查url的错误。由于错误发生在您实际使用它之前,因此该错误不能与url或任何internet权限关联。 通过引用
回调
上下文
调用异步任务生成。您已经通过引用上下文的
ReportInfo()
添加了日志记录,这些都可以工作,是吗?因此,上下文不是你的问题。但是,您从不检查什么是
callback
。如果错误为null,则抛出错误,但在调用
AsyncRequest
之前,您从未对其执行任何操作。尝试使用
ReportInfo(callback.toString())
查看它是什么


如果所有这些都失败了,那似乎是线程错误。为什么不尝试使用AsyncTask而不是
executeOnExecutor()
。你真的需要一个以上的后台线程吗?

很抱歉没有早点回到这里。这里有许多问题

首先。。。感谢Wolfram的建议,我能够捕捉到异常并诊断出问题在于我的FileLogger(和另一个类)是一个静态引用,而这两个平板电脑在运行时找不到引用。因此,我最终从异步方法中删除了日志记录


其次,在进行上述更改之后,还有一个问题,那就是必须从主线程调用活套。原来这两个平板电脑并没有从主线程调用我的异步任务。因此,我必须使用MainLooper将异步调用封装在一个新的处理程序中。

如果您已经发现错误在该请求之前,请在调用它之前显示代码。Gustek。在我调用它之前,错误似乎不存在。我已将调用方法附加到我的原始帖子中。可能是offtopic,但您可能希望将String更改为String。。。在onPostExecute签名中,您似乎能够获取错误日志(否则,您如何知道构造函数中的条目未被记录)。那么,为什么不添加更多设备信息(设备类型、SDK版本、可用内存)并使用
线程.UncaughtExceptionHandler
?@Wolfram。我不好意思说我不知道Thread.UncaughtExceptionHandler。明天我将把它烘焙成一个构建,看看它能提供什么额外的信息。我已经记录了有限的设备信息。这两个设备都有几百兆的可用空间,并且每个应用程序都有48MB的内存级别。一台设备的屏幕分辨率为1280x752(Acer Iconia A200)。另一个是谢谢你的回复。我的min/target sdk版本是15/17,我在没有执行ExecuteExecutor的情况下进行了测试,但同样失败。调用方法确实被try/catch包围。正如您所建议的,在创建(或尝试创建)AsyncTask实例之前,日志记录确实在GetServerInfoAsync方法中工作。下班后,我会尝试Wolframs的建议,希望能为大家提供更多的具体信息。
public void GetServerInfoAsync(IApiCallback callback, Context context) throws IllegalArgumentException, Exception {

    if (callback == null)
        throw new IllegalArgumentException("callback");

    if (context == null)
        throw new IllegalArgumentException("context");

    try {
        FileLogger.getFileLogger(context).ReportInfo("Build URL");
        String url = GetApiUrl("System/Info");
        FileLogger.getFileLogger(context).ReportInfo("Finished building URL");

        if (url != null) {
            FileLogger.getFileLogger(context).ReportInfo("GetServerInfoAsync: url is " + url);
            new AsyncRequest(callback, context).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, url);
        } else {
            FileLogger.getFileLogger(context).ReportError("GetServerInfoAsync: url is null");
        }

    } catch (IllegalArgumentException iae) {
        FileLogger.getFileLogger(context).ReportException("GetServerInfoAsync: IllegalArgumentException", iae);
        throw iae;
    } catch (Exception e) {
        FileLogger.getFileLogger(context).ReportException("GetServerInfoAsync: Exception", e);
        throw e;
    }
}