Bonjour,

J'ai créé un classe qui hérite de SimpleAdapter qui permet d'afficher une liste (ListActivity) avec des images distantes (via HTTP).

Voici le code de ma classe :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
public class SimpleAdapterWithRemoteImage extends SimpleAdapter {
	Context context = null;
	Map<String, SoftReference<Bitmap>> bitmaps = new HashMap<String, SoftReference<Bitmap>>();
	Map<ImageView, URL> imageviews = new HashMap<ImageView, URL>();
 
 
	public SimpleAdapterWithRemoteImage(Context context, List<Map<String, String>> data, int resource, String[] from, int[] to) {
		super(context, data, resource, from, to);
		this.context = context;
	}
 
	private Bitmap fetchBitmap(String url) {
		SoftReference<Bitmap> bitmapReference =  bitmaps.get(url);
 
		if (bitmapReference!=null) {
			Bitmap bitmap = bitmapReference.get();
			if (bitmap!=null) {
				return bitmap;
			} else {
				bitmaps.remove(url);
			}
		}
 
		return null;
	}
 
	public View getView(int position, View convertView, ViewGroup parent) {
		View v = null;
 
 
		if ( super.getCount()>position) {
			v = super.getView(position, convertView, parent);
 
			if (v!=null) {
				ImageView imageView = (ImageView)v.findViewById(R.id.ad_detail_image);
				if ( imageView!=null) {
					URL url = null;
					String thumb = null;
					try {
						Map<String, String> params = (Map<String, String>)super.getItem(position);
						if ( params!=null) {
							thumb = params.get("image");
							if (thumb != null) {
								url = new URL(thumb);
							} else {
								imageView.setImageResource(R.drawable.blank);
							}
						} else {}
					} catch (MalformedURLException e) {}
 
					imageviews.put(imageView, url);
					if ( thumb!=null) {
						Bitmap bitmap = fetchBitmap(thumb);
						if ( bitmap!=null) {
							imageView.setImageBitmap(bitmap);
						} else {
							try {
								if (url!=null) {
									imageView.setImageResource(R.drawable.blank);
									ImageDownloadTask idt = new ImageDownloadTask();
									idt.execute(new RemoteImageView(imageView, url));
								} else {}
							} catch (RejectedExecutionException e) {}
						}
					} else {
						imageView.setImageDrawable(v.getResources().getDrawable(R.drawable.blank));
					}
				} else {}
			} else {}
		}
 
		return v;
	}
 
	private class RemoteImageView {
		ImageView iv;
		URL url;
 
 
		public RemoteImageView(ImageView iv, URL url) {
			this.iv = iv;
			this.url = url;
		}
	}
 
	private class ImageDownloadTask extends AsyncTask<RemoteImageView, Integer, Bitmap> {
		private RemoteImageView riv;
 
 
		protected Bitmap doInBackground(RemoteImageView... rivs) {
			Bitmap bm = null;
			riv = rivs[0];
 
 
			if ( riv!=null && riv.url!=null) {
				URL url = riv.url;
				InputStream is = null;
 
				try {
					is = url.openConnection().getInputStream();
				} catch (MalformedURLException e) {
				} catch (IOException e) {
				}
 
				if ( is!=null) {
					try {
						bm = BitmapFactory.decodeStream(is);
						bitmaps.put(url.toExternalForm(), new SoftReference<Bitmap>(bm));
					} catch ( OutOfMemoryError e) {}
 
					try {
						is.close();
					} catch (IOException e) {}
				} else {}
			}
 
			return bm;
		}
 
		protected void onPostExecute(Bitmap result) {
			if ( riv!=null && riv.iv!=null && riv.url!=null && riv.url.equals(imageviews.get(riv.iv))) {
				riv.iv.setImageBitmap(result);
			}
		}
	}
}
Dans la plupart des cas, l'application fonctionne très bien. Cependant, je reçois de temps en temps les deux rapports d'erreur suivant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
java.lang.NullPointerException
	at android.widget.ListView.setupChild(ListView.java:1735)
	at android.widget.ListView.makeAndAddView(ListView.java:1713)
	at android.widget.ListView.fillUp(ListView.java:670)
	at android.widget.ListView.fillGap(ListView.java:615)
	at android.widget.AbsListView.trackMotionScroll(AbsListView.java:2622)
	at android.widget.AbsListView.onTouchEvent(AbsListView.java:2048)
	at android.widget.ListView.onTouchEvent(ListView.java:3276)
	at android.view.View.dispatchTouchEvent(View.java:3796)
	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:856)
	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:888)
	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:888)
	at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1673)
	at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1114)
	at android.app.Activity.dispatchTouchEvent(Activity.java:2061)
	at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1657)
	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:888)
	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:888)
	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:888)
	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:888)
	at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:888)
	at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchTouchEvent(PhoneWindow.java:1673)
	at com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1114)
	at android.app.Activity.dispatchTouchEvent(Activity.java:2061)
	at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchTouchEvent(PhoneWindow.java:1657)
	at android.view.ViewRoot.handleMessage(ViewRoot.java:1758)
	at android.os.Handler.dispatchMessage(Handler.java:99)
	at android.os.Looper.loop(Looper.java:136)
	at android.app.ActivityThread.main(ActivityThread.java:4425)
	at java.lang.reflect.Method.invokeNative(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:521)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:850)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:608)
	at dalvik.system.NativeStart.main(Native Method)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(16908298, class android.widget.ListView) with Adapter(class com.company.project.SimpleAdapterWithRemoteImage)]
	at android.widget.ListView.layoutChildren(ListView.java:1508)
	at android.widget.AbsListView$CheckForTap.run(AbsListView.java:1930)
	at android.os.Handler.handleCallback(Handler.java:587)
	at android.os.Handler.dispatchMessage(Handler.java:92)
	at android.os.Looper.loop(Looper.java:123)
	at android.app.ActivityThread.main(ActivityThread.java:4627)
	at java.lang.reflect.Method.invokeNative(Native Method)
	at java.lang.reflect.Method.invoke(Method.java:521)
	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
	at dalvik.system.NativeStart.main(Native Method)
Quelqu'un sait-il d'où ça peut venir ? J'ai cherché un peu partout. Amélioré deux ou trois trucs. Mais quelques rares utilisateurs ont toujours ces erreurs.

Merci !