Skip to main content
 首页 » 编程设计

android之AsyncTask内存崩溃

2024年02月20日8me-sa

我使用 AsyncTask 下载页面 html,然后从 html 中提取主题颜色和其他内容(还下载可绘制的)。这在 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) 

这是我的异步任务:

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

请您参考如下方法:

78Mb 这并不算太多。您可以在 list 文件中添加 android:largeHeap="true" 。 另外,不要忘记在使用后回收位图。