D'accord, je perds la raison devant celui-ci. J'ai une méthode dans mon programme qui analyse le HTML. Je veux inclure les images en ligne, et j'ai l'impression que l'utilisation de Html.fromHtml (chaîne, Html.ImageGetter, Html.TagHandler) permettra que cela se produise.
Comme Html.ImageGetter n'a pas d'implémentation, c'est à moi d'en écrire une. Cependant, comme l'analyse des URL dans Drawables nécessite un accès réseau, je ne peux pas le faire sur le thread principal. Il doit donc s'agir d'une AsyncTask. Je pense.
Toutefois, lorsque vous passez le paramètre ImageGetter en tant que paramètre à Html.fromHtml, il utilise la méthode getDrawable qui doit être remplacée. Il n'y a donc aucun moyen d'appeler l'ensemble de la transaction ImageGetter.execute qui déclenche la méthode doInBackground. Il est donc impossible de rendre cette opération asynchrone.
Est-ce que j'y vais complètement, ou pire, est-ce impossible? Merci
J'ai fait quelque chose de très similaire (je pense) à ce que vous voulez faire. Ce que j’avais besoin de faire à l’époque est d’analyser le code HTML et de le configurer à nouveau dans TextView. J’avais besoin d’utiliser également Html.ImageGetter
et d’avoir le même problème lors de la récupération d’image sur le fil principal.
Les étapes que j'ai faites essentiellement:
URLDrawable
in getDrawable
de Html.ImageGetter
onPostExecute
est appelé, je redessine le conteneur du résultat Spanned
Maintenant, le code pour URLDrawable est comme suit
public class URLDrawable extends BitmapDrawable {
// the drawable that you need to set, you could set the initial drawing
// with the loading image if you need to
protected Drawable drawable;
@Override
public void draw(Canvas canvas) {
// override the draw to facilitate refresh function later
if(drawable != null) {
drawable.draw(canvas);
}
}
}
Assez simplement, je remplace juste draw
pour choisir le Drawable que je place là-bas après la fin de AsyncTask.
La classe suivante est l'implémentation de Html.ImageGetter
et celle qui extrait l'image de AsyncTask
et met à jour l'image.
public class URLImageParser implements ImageGetter {
Context c;
View container;
/***
* Construct the URLImageParser which will execute AsyncTask and refresh the container
* @param t
* @param c
*/
public URLImageParser(View t, Context c) {
this.c = c;
this.container = t;
}
public Drawable getDrawable(String source) {
URLDrawable urlDrawable = new URLDrawable();
// get the actual source
ImageGetterAsyncTask asyncTask =
new ImageGetterAsyncTask( urlDrawable);
asyncTask.execute(source);
// return reference to URLDrawable where I will change with actual image from
// the src tag
return urlDrawable;
}
public class ImageGetterAsyncTask extends AsyncTask<String, Void, Drawable> {
URLDrawable urlDrawable;
public ImageGetterAsyncTask(URLDrawable d) {
this.urlDrawable = d;
}
@Override
protected Drawable doInBackground(String... params) {
String source = params[0];
return fetchDrawable(source);
}
@Override
protected void onPostExecute(Drawable result) {
// set the correct bound according to the result from HTTP call
urlDrawable.setBounds(0, 0, 0 + result.getIntrinsicWidth(), 0
+ result.getIntrinsicHeight());
// change the reference of the current drawable to the result
// from the HTTP call
urlDrawable.drawable = result;
// redraw the image by invalidating the container
URLImageParser.this.container.invalidate();
}
/***
* Get the Drawable from URL
* @param urlString
* @return
*/
public Drawable fetchDrawable(String urlString) {
try {
InputStream is = fetch(urlString);
Drawable drawable = Drawable.createFromStream(is, "src");
drawable.setBounds(0, 0, 0 + drawable.getIntrinsicWidth(), 0
+ drawable.getIntrinsicHeight());
return drawable;
} catch (Exception e) {
return null;
}
}
private InputStream fetch(String urlString) throws MalformedURLException, IOException {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet request = new HttpGet(urlString);
HttpResponse response = httpClient.execute(request);
return response.getEntity().getContent();
}
}
}
Enfin, vous trouverez ci-dessous un exemple de programme montrant comment les choses fonctionnent:
String html = "Hello " +
"<img src='http://www.gravatar.com/avatar/" +
"f9dd8b16d54f483f22c0b7a7e3d840f9?s=32&d=identicon&r=PG'/>" +
" This is a test " +
"<img src='http://www.gravatar.com/avatar/a9317e7f0a78bb10a980cadd9dd035c9?s=32&d=identicon&r=PG'/>";
this.textView = (TextView)this.findViewById(R.id.textview);
URLImageParser p = new URLImageParser(textView, this);
Spanned htmlSpan = Html.fromHtml(html, p, null);
textView.setText(htmlSpan);
Pas mal. Cependant, le type DefaultHttpClient est obsolète. Essayez ceci sur la méthode de récupération:
private InputStream fetch(String urlString) throws MalformedURLException, IOException {
URL url = new URL(urlString);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
InputStream stream = urlConnection.getInputStream();
return stream;
}
Je suis un peu confus: le code HTML que vous souhaitez rendre est-il statique et uniquement destiné à la mise en forme, ou est-il dynamique et provient du Web? Si vous vouliez utiliser ce dernier, c'est-à-dire restituer le code HTML et récupérer les images, eh bien ça va être un peu pénible (suggestion - il suffit d'utiliser une WebView?).
Quoi qu'il en soit, vous devez d’abord exécuter AsyncTask pour récupérer le code HTML initial. Vous transmettriez ensuite ces résultats à la fonction Html.fromHtml()
avec l'implémentation personnalisée de la classe Html.ImageGetter
. Ensuite, dans cette implémentation, vous devrez lancer une AsyncTask individuelle pour récupérer chacune des images (vous souhaiterez probablement implémenter une mise en cache).
Cependant, à la lecture de la documentation (et je pense en avoir vu quelques exemples), il me semblerait que ce n’est pas ce qu’ils désignaient par le Html.ImageGetter
. Je pense que cela concerne le code HTML codé en dur avec des références à internal drawables, mais ce n’est que mon point de vue.
si vous utilisez Picasso, remplacez une partie du code @momo par
/***
* Get the Drawable from URL
* @param urlString
* @return
*/
public Drawable fetchDrawable(String urlString) {
try {
Drawable drawable = fetch(urlString);
drawable.setBounds(0, 0, 0 + drawable.getIntrinsicWidth(), 0
+ drawable.getIntrinsicHeight());
return drawable;
} catch (Exception e) {
return null;
}
}
private Drawable fetch(String urlString) throws MalformedURLException, IOException {
return new BitmapDrawable(c.getResources(), Picasso.with(c).load(urlString).get());
}
AsyncTask task = new AsyncTask () {
@Override
protected String doInBackground(Integer... params) {
span = Html.fromHtml(noticeList.get(0)
.getContent(), imgGetter, null);
return null;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
text.setMovementMethod(ScrollingMovementMethod
.getInstance());
if(span != null){
text.setText(span);
}
}
};
task.execute();