I created a custom TextView
to show and images on it. I have to download the images and then show them on the textview
. So I thought that I can do my job with a AsyncTask
class. On the doInBackground
I download and save the image on the Internal storage (for offline mode), and on the onPostExecute
I call a method which shows the images on the textview
. But it doesn't work. I mean instead of showing the images it shows the img
tags.
I also tried to get the status from the AsyncTask
class on the onPostExecute
method and it's RUNNING
. Isn't that weird? I thought that it will be FINISHED
. Am I missing something about AsyncTask class?
Below is addImages
method, where I find the img
tags from the text and store the data on a List
, and call the DownLoadImage
class which extends the 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;
}
This is the addImages
method where I replace the tags with images
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
);
}
}
and the DownLoadImage
class
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 *****
the getTextWithImages
where I call the add
method
private Spannable getTextWithImages(Context context, CharSequence text) {
images = new ArrayList<>();
Spannable spannable = spannableFactory.newSpannable(text);
add(context, spannable);
return spannable;
}
and the setText
method where I call the getTextWithImages
@Override
public void setText(CharSequence text, BufferType type) {
Spannable s = getTextWithImages(getContext(), text);
super.setText(s, BufferType.SPANNABLE);
}
You could create an interface that invokes a callback to the UI thread, instead of using the context. For example, in your 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;
}
}
Then when you create your task try:
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);
Hope this helps.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.