[英]update UI from AsyncTask
我創建了一個自定義TextView
來顯示和顯示圖像。 我必須下載圖像,然后在textview
上顯示它們。 所以我認為我可以使用AsyncTask
類來完成我的工作。 在doInBackground
我將圖像下載並保存到內部存儲中(用於脫機模式),在onPostExecute
上,我調用了一種在textview
上顯示圖像的方法。 但這是行不通的。 我的意思是不是顯示圖像而是顯示img
標簽。
我還嘗試從onPostExecute
方法的AsyncTask
類獲取狀態,該狀態為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.,@?^=%&:\\/~+#-]*[\\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);
}
}
*****編輯*****
我在其中調用add
方法的getTextWithImages
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);
}
您可以創建一個調用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);
希望這可以幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.