2016-01-27 95 views
0

我創建了一個自定義TextView來顯示它並顯示圖像。我必須下載圖像,然後在textview上顯示它們。所以我認爲我可以通過AsyncTask課來完成我的工作。在doInBackground我下載並保存在內部存儲器上(離線模式),並在onPostExecute我調用一個方法,顯示textview上的圖像。但它不起作用。我的意思不是顯示圖片,而是顯示img標籤。從AsyncTask更新UI

我也嘗試從AsyncTask類的onPostExecute方法和它的RUNNING獲得狀態。這不奇怪嗎?我認爲這將是FINISHED。我錯過了一些有關AsyncTask類的內容嗎?

下面是addImages方法,在這裏我找到的文本img標籤和數據存儲在一個List,並調用DownLoadImage類擴展AsyncTask

private boolean add(final Context context, final Spannable spannable) { 
    path = context.getFilesDir(); 

    Pattern refImgPattern = Pattern.compile("<img .+?\\/>"); 
    hasChanges = false; 

    refImgMatcher = refImgPattern.matcher(spannable); 
    while (refImgMatcher.find()) { 

    set = true; 
    for (ImageSpan span : spannable.getSpans(refImgMatcher.start(), refImgMatcher.end(), ImageSpan.class)) { 
      if (spannable.getSpanStart(span) >= refImgMatcher.start() 
         && spannable.getSpanEnd(span) <= refImgMatcher.end() 
         ) { 
       spannable.removeSpan(span); 
      } else { 
       set = false; 
       break; 
       } 
      } 

    String imageUrl = spannable.subSequence(refImgMatcher.start(0), refImgMatcher.end(0)).toString().trim(); 

    width = 0; 
    Pattern widthPattern = Pattern.compile("width=\"[0-9]+?\""); 
    Matcher widthMatcher = widthPattern.matcher(imageUrl); 

     if (widthMatcher.find()) { 
      String w = widthMatcher.group(0); 
      w = w.replaceAll("width=", ""); 
      w = w.replaceAll("\"", ""); 
      width = Integer.valueOf(w); 
     } 

      height = 0; 
      Pattern heightPattern = Pattern.compile("height=\"[0-9]+?\""); 
      Matcher heightMatcher = heightPattern.matcher(imageUrl); 

      if (heightMatcher.find()) { 
       String h = heightMatcher.group(0); 
       h = h.replaceAll("height=", ""); 
       h = h.replaceAll("\"", ""); 
       height = Integer.valueOf(h); 
      } 

    Pattern urlPattern = Pattern.compile("(http|ftp|https):\\/\\/([\\w_-]+(?:(?:\\.[\\w_ -]+)+))([\\w.,@?^=%&:\\/~+#-]*[\\[email protected]?^=%&\\/~+#-])?"); 
    Matcher urlMatcher = urlPattern.matcher(imageUrl); 

     if (urlMatcher.find()) 
      imageUrl = urlMatcher.group(0); 

      imageName = siteData.getId() + "_" + imageUrl.substring(imageUrl.lastIndexOf("/") + 1, imageUrl.length()); 

      images.add(new Image(imageUrl, imageName, width, height, refImgMatcher.start(0), refImgMatcher.end(0))); 


    } 

    if (images.size() > 0) { 

     for (final Image img : images) { 
      image = new File(path, img.name); 
      if (!image.exists()) { 
      new DownLoadImage(context, spannable, img).execute(); 
      } else 
       addImages(spannable, context, img); 
     } 
    } 

    return hasChanges; 
} 

這是addImages方法,其中,我替換圖像

private void addImages(Spannable spannable, Context context, Image im) { 
     image = new File(path, im.name); 
     BitmapFactory.Options bmOptions = new BitmapFactory.Options(); 
     bitmap = BitmapFactory.decodeFile(image.getAbsolutePath(), bmOptions); 
     if (im.width > 0 && im.height > 0) 
      bitmap = Bitmap.createScaledBitmap(bitmap, im.width * 3, im.height * 3, true); 

     if (set) { 
      hasChanges = true; 
      spannable.setSpan(new ImageSpan(context, bitmap), 
        im.startIndex, 
        im.endIndex, 
        Spannable.SPAN_EXCLUSIVE_EXCLUSIVE 
      ); 
     } 

    } 

DownLoadImage

private class DownLoadImage extends AsyncTask<Void, Void, Void> { 

     private Connection connection = Connection.getInstance(); 
     private Context context; 
     private Spannable spannable; 
     private Image image; 

     public DownLoadImage(Context context, Spannable spannable, Image image) { 
      this.spannable = spannable; 
      this.context = context; 
      this.image = image; 
     } 

     @Override 
     protected Void doInBackground(Void... params) { 

      try { 
       connection.openConnection(image.path, ConnectionType.GET, false, false, null); 

       Integer status = connection.getResponseCode(); 
       if (status >= 200 && status < 300) { 
        InputStream inputStream = new BufferedInputStream(connection.getInputStream()); 
        Bitmap bitmap = BitmapFactory.decodeStream(inputStream); 
        Actions.saveImage(context, bitmap, image.name); 
       } 

      } catch (IOException e) { 
       e.printStackTrace(); 
      } finally { 
       connection.closeConnection(); 
      } 


      return null; 
     } 

     @Override 
     protected void onPostExecute(Void aVoid) { 
      super.onPostExecute(aVoid); 
      Log.i("status", this.getStatus().toString()); 
      addImages(spannable, context, image); 
     } 
    } 

***** EDIT標籤*****

getTextWithImages其中我稱之爲add方法

private Spannable getTextWithImages(Context context, CharSequence text) { 
    images = new ArrayList<>(); 

    Spannable spannable = spannableFactory.newSpannable(text); 
    add(context, spannable); 
    return spannable; 
} 

setText方法,我稱之爲getTextWithImages

@Override 
public void setText(CharSequence text, BufferType type) { 
    Spannable s = getTextWithImages(getContext(), text); 
    super.setText(s, BufferType.SPANNABLE); 
} 
+0

1.檢查你的正則表達式是否正確。 2.只分析圖像URL,讓[Picasso](http://square.github.io/picasso/)或[Glide](https://github.com/bumptech/glide)完成剩下的工作。 – Emmanuel

+0

正則表達式是正確的,因爲它適用於離線模式。我嘗試過畢加索,但輸出結果是一樣的 –

+0

正則表達式是否會爲您提供有效的URL?如果您在瀏覽器上訪問該網址,是否顯示該圖片? – Emmanuel

回答

0

您可以創建可調用回調到UI線程的界面,而不是使用上下文。例如,在您的AsyncTask:

private class DownLoadImage extends AsyncTask<Void, Void, Void> { 
    private Connection connection = Connection.getInstance(); 
    private Context context; 
    private Spannable spannable; 
    private Image image; 
    private OnImageDownloadedListener mOnImageDownloadedListener; 
    ... 

    @Override 
    protected Void doInBackground(Void... params) { 
     ... 
     ... 
    } 
    // Interface the task will use to communicate with your activity method. 
    public interface OnImageDownloadedListener { 
     void onImageDownloaded(Spannable spannable, Image image); // No need for context. 
    } 

    @Override 
    protected void onPostExecute(Void aVoid) { 
     if (mOnImageDownloadedListener != null) { 
      // If we set a listener, invoke it. 
      mOnImageDownloadedListener.onImageDownloaded(spannable, image); 
     } 
    } 

    // Setter. 
    public setOnImageDownloadedListener(OnImageDownloadedListener listener) { 
     mOnImageDownloadedListener = listener; 
    } 
} 

然後,當你創建你的任務嘗試:

if (!image.exists()) { 
    // Create the task. 
    DownloadImage downloadTask = new DownLoadImage(context, spannable, img); 

    // Set your listener. 
    downloadTask.setOnImageDownloadedListener(new OnImageLoadedListener() { 
     @Override 
     public void onImageDownloaded(Spannable spannable, Image image) { 
      // Add the images. 
      addImages(spannable, **YourContextHere(Activity/etc)**.this, image) 
     } 
    }); 

    // Execute. 
    downloadTask.execute(); 
} else 
    addImages(spannable, context, img); 

希望這有助於。

+0

不,它具有相同的輸出。 :\ 看,我調試應用程序,發現當我下載圖像並向他們顯示hasChanges值(返回add方法的值)爲false時,但是當我嘗試從內部存儲器顯示它們時是true ... –

+0

hasChanges將始終從下載任務中爲假,因爲AsyncTask是異步的。當您調用execute()後臺線程時,會創建與UI線程分開的後臺線程,並在該後臺線程中執行'doInBackground()'。 'execute()'是非阻塞的,意味着它將運行,然後立即繼續下一行代碼,無論'doInBackground()'中的代碼是否完成。 –

+0

嗯,所以我怎麼能使add方法返回true? :\ –