花一点时间来理解一个架构的架构对AsyncTask
你来说比让别人简单地为你做一个架构会更有帮助。
AsyncTask 实际上是一个相当简单的扩展和使用类。以最简单的形式,AsyncTask 可以是在后台运行的代码(脱离 UI 线程——这是导致锁定的原因),但设置为允许一些代码在后台运行,一些代码在之前执行/after,以及一些在必要时作为进度更新执行的代码。
您将需要创建自己的扩展 AsyncTask 的类,如下所示。您的任务将采用三个参数。第一个将传递给doInBackground
在后台运行的函数,第二个是可以传递给进度更新函数的参数类型,第三个是传递给onPostExecute
在 UI 线程上运行的 fn的类型后台功能完成后。在下面的简单示例中,我不会包含要传递给后执行函数或进度更新函数的类型,因此它们将是 Void 类型。
private class YourTask extends AsyncTask<byte[], Void, Void> {
protected Long doInBackground(byte[]... data) {
//get the array
byte[] array = data[0];
//do something with it.
HERE IS WHERE YOU RUN YOUR CODE IN THE BACKGROUND THAT IS TAKING TOO LONG ON THE UI THREAD
//return null because this type needs to match the last type for returning to the postexec fn
return null;
}
}
当您想运行您的任务时,您可以调用以下命令:
new YourTask().execute(someByteArray);
因此,您通常可以将花费很长时间的代码粘贴到该doInBackground
函数中,但您必须小心,因为它不在 UI 线程上,并且某些代码确实必须在 UI 线程上运行。
我建议做一些分析,看看具体是什么代码阻塞了你的 UI 线程,然后使用 AsyncTask 在后台运行它。您可以通过在 Eclipse 中使用 DDMS 并使用方法分析来做到这一点。另一种方法是使用Debug
类并Debug.startMethodTracing("tracefilename");
在您想要开始时调用Debug.stopMethodTracing();
. 您可以在此处阅读更多相关信息。但是,您的代码确实加载了一个 url ( mWebView.loadUrl
),所以我认为这可能是一个很大的瓶颈!
就像附录一样,如果您想要更深入的 AsyncTask 示例,这里是这个有用文档中的一个 I C&Pd :
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
上面的示例中的代码既可以举例说明后台任务期间 UI 上的更新进度,也可以传递一个参数,该参数随后由 UI 线程运行后执行 fn 使用。