2016-12-30 170 views
0

我使用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); 

      } 
     } 


    } 


} 

回答

2

78Mb它不是太多。您可以在清單文件中添加android:largeHeap="true"。 另外,不要忘記使用後回收位圖。

0

它不是異步任務,我認爲這是你的位圖對象。嘗試使用bitmap.recycle()和設置位圖= null在您的後執行中使用位圖對象bm後。