从AsyncTask更新UI

时间:2016-01-27 20:47:27

标签: android android-asynctask

我创建了一个自定义TextView来显示和显示图片。我必须下载图像,然后在textview上显示它们。所以我认为我可以用AsyncTask课来完成我的工作。在doInBackground我下载并将图像保存在内部存储上(用于离线模式),在onPostExecute上我调用了一个显示textview图像的方法。但它不起作用。我的意思是代替显示图像,而不显示img标记。

我还试图通过AsyncTask方法及onPostExecute方法获取RUNNING课程的状态。这不奇怪吗?我以为它会FINISHED。我错过了有关AsyncTask类的内容吗?

以下是addImages方法,我在其中找到文本中的img标记并将数据存储在List上,并调用扩展DownLoadImage的{​​{1}}类{1}}。

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.,@?^=%&:\\/~+#-]*[\\w@?^=%&\\/~+#-])?"); 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); } } 方法的getTextWithImages

add

以及我调用private Spannable getTextWithImages(Context context, CharSequence text) { images = new ArrayList<>(); Spannable spannable = spannableFactory.newSpannable(text); add(context, spannable); return spannable; }

setText方法
getTextWithImages

1 个答案:

答案 0 :(得分: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);

希望这有帮助。