2014-09-04 65 views
0

我需要在每個頁面上使用webview查看傳呼機。應用程序將下載從服務器到設備緩存的遠程(大型)圖像,當下載完成時,它應顯示在當前的webview中。這是我的看法尋呼機項目佈局:查看傳呼機與網絡瀏覽器快速滾動

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:background="#000000" 
    android:gravity="center" 
    android:padding="10dp" > 

    <WebView 
     android:id="@+id/image" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:background="#00000000" 
     android:padding="1dp" /> 

</RelativeLayout> 

,這是考慮到尋呼機適配器我instantiateItem方法:

public Object instantiateItem(ViewGroup container, int position) { 

     inflater = (LayoutInflater) context 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     View itemView = inflater.inflate(R.layout.viewpager_item, container, 
       false); 

     imgflag = (WebView) itemView.findViewById(R.id.image); 

     imgflag.setBackgroundColor(0x000000); 
     imgflag.getSettings().setBuiltInZoomControls(true); 
     imgflag.getSettings().setUseWideViewPort(true); 
     imgflag.getSettings().setLoadWithOverviewMode(true); 
     DownloadImageTask task = new DownloadImageTask(urls[position]); 
     task.execute(); 


     ((ViewPager) container).addView(itemView); 

     return itemView; 
    } 

這是DownloadImageTask類:

private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { 

    String imageUrl; 
    String filename; 
    public DownloadImageTask(String url) 
    { 
     super(); 
     this.imageUrl=url;   
    } 

    protected Bitmap doInBackground(String... urls) { 
     Bitmap image = null; 
     Log.d("Start", "Start downloading"); 
     filename=imageUrl.replace('/', '-'); 
     filename=filename.replace('.', '-'); 
     filename=filename.replace(':', '-'); 
     File file=new File(context.getCacheDir(), filename);    
     if(file.exists()) 
     { 
      BitmapFactory.Options options = new BitmapFactory.Options(); 
      options.inPreferredConfig = Bitmap.Config.ARGB_8888; 
      Bitmap bitmap = BitmapFactory.decodeFile(context.getCacheDir() + "/" + filename); 
      return bitmap; 
     }       
     URL url; 
     try { 
      url = new URL(imageUrl); 
      HttpURLConnection ucon = (HttpURLConnection) url.openConnection(); 
      image = BitmapFactory.decodeStream(ucon.getInputStream()); 
      File cacheDir = context.getCacheDir(); 

      File imageFile = new File(cacheDir, filename); 

      FileOutputStream fos; 
      fos = new FileOutputStream(imageFile); 
      image.compress(Bitmap.CompressFormat.JPEG, 100, fos); 
      fos.close(); 
      fos.flush(); 

     } catch (MalformedURLException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     return image; 
    } 

    protected void onPostExecute(Bitmap result) { 
     if(result!=null) 
     { 

      String style="width='100%'"; 
      if(result.getWidth()>result.getHeight()) 
       style="height='100%'"; 
      String base = context.getCacheDir().getAbsolutePath().toString(); 
      String imagePath = "file://"+ base + "/" + filename; 
      String html = "<html><head></head><body><img " + style + " src=\""+ imagePath + "\"></body></html>"; 
      imgflag.loadDataWithBaseURL("", html, "text/html","utf-8", ""); 
     } 
    } 
} 

而且一切都運行完美當我慢慢滾動,一頁頁......但如果我快速滾動約10-20頁(無需等待每一個加載),它沒有工作的權利。它不會崩潰或類似的東西,但視圖只是黑色。當我離開開始加載的頁面時,開始下載不會停止,它仍然會在後臺加載圖像,所以也許會導致問題?當它不加載圖像時,控制檯說:nativeOnDraw失敗;清除背景顏色。

有沒有簡單的解決這個問題?我不應該使用任何外部代碼,庫或類似的東西 - 我應該自己編寫一切代碼。

回答

0

問題的根本原因在於您正在快速連續啓動大量的AsyncTasks。這些在他們自己的線程中操作。如果滾動瀏覽20頁,則同時嘗試從遠程源下載最多20個圖像。可以通過調用AsyncTask.cancel(true)方法來取消AsyncTask,但這不是很有用,因爲您還需要在doInBackground()方法中檢查AsyncTask.isCancelled()。由於您只是在執行一項長時間運行的任務,所以這不是很有幫助。此外,您的ViewPager負責維護您的WebView,因此確定何時調用它很困難。

我建議儘快下載ViewPager adapater實例化的所有圖像。如果圖像尚未下載,您還需要一個佔位符圖像來顯示。

所以你的AsyncTask會是這個樣子:

private class DownloadImages extends AsyncTask<String, Void, Void> { 

    private List<String> mUrls 

    public DownloadImagesTask(List<String> urls){ 
     mUrls = urls; 
    }  

    protected Void doInBackground(){ 

     for(String url : mUrls){ 

      if(isCancelled()) 
       break; 

      //Your code to download and save the files locally 
    } 

而且你ViewPager適配器這樣的事情

public Object instantiateItem(ViewGroup container, int position) { 

    inflater = (LayoutInflater) context 
      .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View itemView = inflater.inflate(R.layout.viewpager_item, container, 
      false); 

    imgflag = (WebView) itemView.findViewById(R.id.image); 

    imgflag.setBackgroundColor(0x000000); 
    imgflag.getSettings().setBuiltInZoomControls(true); 
    imgflag.getSettings().setUseWideViewPort(true); 
    imgflag.getSettings().setLoadWithOverviewMode(true); 

    String imageUrl = urls[position] 

    //Your code to turn url into filepath 
    //If file exists - display set WebView image = file 
    //Otherwise set WebView image to placeholder file 
}