title: update UI from AsyncTask
body: <p>I created a custom <code>TextView</code> to show and images on it. I have to download the images and then show them on the <code>textview</code>. So I thought that I can do my job with a <code>AsyncTask</code> class. On the <code>doInBackground</code> I download and save the image on the Internal storage (for offline mode), and on the <code>onPostExecute</code> I call a method which shows the images on the <code>textview</code>. But it doesn't work. I mean instead of showing the images it shows the <code>img</code> tags.</p>
  
  <p>I also tried to get the status from the <code>AsyncTask</code> class on the <code>onPostExecute</code> method and it's <code>RUNNING</code>. Isn't that weird? I thought that it will be <code>FINISHED</code>. Am I missing something about AsyncTask class?</p>
  
  <p>Below is <code>addImages</code> method, where I find the <code>img</code> tags from the text and store the data on a <code>List</code>, and call the <code>DownLoadImage</code> class which extends the <code>AsyncTask</code>.</p>
  
  <pre><code> private boolean add(final Context context, final Spannable spannable) {
      path = context.getFilesDir();
  
      Pattern refImgPattern = Pattern.compile("&lt;img .+?\\/&gt;");
      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) &gt;= refImgMatcher.start()
                          &amp;&amp; spannable.getSpanEnd(span) &lt;= 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.,@?^=%&amp;:\\/~+#-]*[\\w@?^=%&amp;\\/~+#-])?");
       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() &gt; 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;
   }
  </code></pre>
  
  <p>This is the <code>addImages</code> method where I replace the tags with images</p>
  
  <pre><code> 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 &gt; 0 &amp;&amp; im.height &gt; 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
              );
          }
  
      }
  </code></pre>
  
  <p>and the <code>DownLoadImage</code> class</p>
  
  <pre><code>private class DownLoadImage extends AsyncTask&lt;Void, Void, Void&gt; {
  
          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 &gt;= 200 &amp;&amp; status &lt; 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);
          }
      }
  </code></pre>
  
  <p>***** EDIT *****</p>
  
  <p>the <code>getTextWithImages</code> where I call the <code>add</code> method</p>
  
  <pre><code>private Spannable getTextWithImages(Context context, CharSequence text) {
      images = new ArrayList&lt;&gt;();
  
      Spannable spannable = spannableFactory.newSpannable(text);
      add(context, spannable);
      return spannable;
  }
  </code></pre>
  
  <p>and the <code>setText</code> method where I call the <code>getTextWithImages</code></p>
  
  <pre><code>@Override
  public void setText(CharSequence text, BufferType type) {
      Spannable s = getTextWithImages(getContext(), text);
      super.setText(s, BufferType.SPANNABLE);
  }
  </code></pre>