对扩展AsyncTask的自定义类有一些问题。我的应用是针对Android 4.0.3,以下代码适用于30多人测试它。但是,当我调用新的AsyncRequest时,有两个用户看到应用程序崩溃,如下所示。
我有一个工作记录器正在记录到用户存储上的文本文件,并且不记录AsyncRequest构造函数中的条目。所以我必须假设在调用构造函数之前发生了崩溃。
遇到此次崩溃的两个设备之一显然是运行Android 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);
}
}
编辑:根据以下评论。
这是我从自定义AsyncTask调用的完整方法。我创建AsyncTask的所有日志消息都显示在日志中。没有例外。
日志记录在创建AsyncRequest之前显示url值,并且URL根本没有格式错误。这就是我所期待的。
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;
}
}
答案 0 :(得分:0)
首先,请记住在Api 11之前executeOnExecutor()
不可用。您已经说过问题出在4.0.4设备上,但请记住这一点。
以下是解决问题所在的步骤。似乎您已经使用所有ReportInfo()
语句完成了其中一些操作。
首先,我假设您对GetServerInfoAsync
的电话在try...catch
范围内,对吗?我正在检查,因为您使用了Throw
。此外,您已添加日志记录以检查URL的错误。由于错误发生在您实际使用它之前,错误不能与url或任何Internet权限。
您可以使用对callback
和context
的引用来调用AsyncTask生成。您已经通过引用上下文的ReportInfo()
添加了日志记录,那些工作,是吗?因此,背景不是您的问题。但是,您永远不会检查callback
是什么。如果它为null,则抛出错误,但在调用AsyncRequest
之前,您从未对其执行任何操作。尝试ReportInfo(callback.toString())
查看它是什么。
如果所有其他方法都失败了,那么线程似乎是错误的。为什么不尝试使用AsyncTask而不是executeOnExecutor()
。你真的需要超过1个后台线程吗?
答案 1 :(得分:0)
很抱歉没有早点回复。这里有很多问题。
首先关闭...感谢Wolfram的建议我能够捕获异常并诊断问题是我的FileLogger(和另一个类)是静态引用,并且这两个平板电脑在运行时找不到引用。所以我最终从我的异步方法中删除了Logging。
其次,在进行上述更改后,还有另一个问题,即必须从主线程调用looper。事实证明,这两个平板电脑没有从主线程调用我的异步任务。因此,我必须使用MainLooper将异步调用封装在新的Handler中。