我使用AsyncTask來下載頁面html,然後從html中提取主題顏色和其他東西(也可以下載drawable)。它被作爲onPageStarted這樣執行:AsyncTask內存崩潰
if (interfaceUpdating && !url.contains("download.php")) {
new themeColorTask().execute(url);
}
這工作完全地很好,但問題是,當用戶下載文件,它工作正常幾秒鐘,但後來我得到這個在系統崩潰日誌:
12-30 20:08:18.645 3936-3975/cf.vojtechh.apkmirror E/art: Throwing OutOfMemoryError "Failed to allocate a 78465796 byte allocation with 16777168 free bytes and 73MB until OOM"
12-30 20:08:18.755 3936-3975/cf.vojtechh.apkmirror E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112 )
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.OutOfMemoryError: Failed to allocate a 78465796 byte allocation with 16777168 free bytes and 73MB until OOM
at java.lang.AbstractStringBuilder.enlargeBuffer(AbstractStringBuilder.java:95)
at java.lang.AbstractStringBuilder.append0(AbstractStringBuilder.java:146)
at java.lang.StringBuilder.append(StringBuilder.java:216)
at cf.vojtechh.apkmirror.MainActivity$themeColorTask.doInBackground(MainActivity.java:679)
at cf.vojtechh.apkmirror.MainActivity$themeColorTask.doInBackground(MainActivity.java:660)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
這是我的AsyncTask:
private class themeColorTask extends AsyncTask<String, Integer, Integer> {
@Override
protected Integer doInBackground(String... url) {
if (!url[0].contains("download.php")){
try {
// Downloading html source
URLConnection connection = (new URL(url[0])).openConnection();
connection.setConnectTimeout(5000);
connection.setReadTimeout(5000);
connection.connect();
// Read and store the result line by line then return the entire string.
InputStream in = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder html = new StringBuilder();
for (String line; (line = reader.readLine()) != null;) {
html.append(line);
}
in.close();
Source source = new Source(html.toString());
//theme color
String extractedThemeColor = ColorDarkTheme;
List<Element> elements = source.getAllElements("meta");
for (Element element : elements) {
final String id = element.getAttributeValue("name"); // Get Attribute 'id'
if (id != null && id.equals("theme-color")) {
extractedThemeColor = element.getAttributeValue("content");
}
}
//App title
appName = "APKMirror";
List<Element> h1elements = source.getAllElements("h1");
for (Element element : h1elements) {
final String id = element.getAttributeValue("class"); // Get Attribute 'id'
if (id != null && id.contains("app-title")) {
appName = element.getAttributeValue("title");
}
}
if (appName == null) {
appName = "APKMirror";
}
//Favicon
List<Element> IMGelements = source.getAllElements("img");
for (Element element : IMGelements) {
final String id = element.getAttributeValue("style"); // Get Attribute 'id'
if (id != null && id.matches("width:96px; height:96px;")) {
faviconURL = "http://www.apkmirror.com" + element.getAttributeValue("src");
}
}
// Favicon download
URLConnection favIconDownload = (new URL(faviconURL)).openConnection();
favIconDownload.setConnectTimeout(5000);
favIconDownload.setReadTimeout(5000);
favIconDownload.connect();
InputStream favIconDownloadStream = favIconDownload.getInputStream();
favico = BitmapFactory.decodeStream(favIconDownloadStream);
favIconDownloadStream.close();
if (extractedThemeColor != null && !extractedThemeColor.matches("#FF8B14")) {
//convert the color to darker color so its nice and material
float[] hsv = new float[3];
int color = Color.parseColor(extractedThemeColor);
Color.colorToHSV(color, hsv);
hsv[2] *= 0.8f; // value component
themeColor = Color.HSVToColor(hsv);
return themeColor;
} else {
//if color is not found we will return orange color
return Color.parseColor(ColorDarkTheme);
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
} else {
return Color.parseColor(ColorDarkTheme);
}
}
@Override
protected void onPostExecute(Integer result) {
// updating interface
if (isLollipop) {
setSystemBarColor(result);
}
fab.setBackgroundTintList(ColorStateList.valueOf(result));
drawable.setColorFilter(new LightingColorFilter(0xFF000000, result));
bottomBar.setBackgroundColor(result);
swipeRefreshLayout.setColorSchemeColors(result,result,result);
//updating recents
if (isLollipop) {
Bitmap bm = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher_circle);
if (currentUrl.matches(urlFrontPage)) {
ActivityManager.TaskDescription taskDesc = new ActivityManager.TaskDescription(getString(R.string.app_name), bm, ContextCompat.getColor(getApplicationContext(), R.color.colorPrimaryDark));
MainActivity.this.setTaskDescription(taskDesc);
} else {
ActivityManager.TaskDescription taskDesc = new ActivityManager.TaskDescription(appName, favico, result);
MainActivity.this.setTaskDescription(taskDesc);
}
}
}
}