AsyncTask内存崩溃

时间:2016-12-30 19:17:52

标签: android webview android-asynctask crash

我使用AsyncTask下载页面html,然后从html中提取主题颜色和其他东西(也可下载drawable)。这将在onPageStarted中执行,如下所示:

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);

            }
        }


    }


}

2 个答案:

答案 0 :(得分:2)

78Mb它并不太多。您可以在清单文件中添加android:largeHeap="true"。 此外,请勿忘记在使用后回收位图。

答案 1 :(得分:0)

它不是异步任务我认为它是你的位图对象。在post执行中使用位图对象bm后,尝试使用bitmap.recycle()和set bitmap = null。