Reputation: 17429
I created a ListView
using an ArrayAdapter
that implements the getView()
method in this way:
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
if(rowView ==null){
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
rowView = inflater.inflate(R.layout.rowlayout_member, parent, false);
}
TextView textView = (TextView) rowView.findViewById(R.id.label);
TextView textView1 = (TextView) rowView.findViewById(R.id.label1);
ImageView imageView = (ImageView) rowView.findViewById(R.id.icon);
textView.setText(values[position]);
textView1.setText(surname[position]);
String s = values[position];
if(foto[position] != null){
Drawable c = Drawable.createFromPath(basePath+foto[position]); // line 56
if(c!=null)
imageView.setImageDrawable(c);
else
imageView.setImageResource(R.drawable.default);
}else{
imageView.setImageResource(R.drawable.default);
}
return rowView;
}
All seems to work fine, but when I come in and go out to the List for many times(changing Activity) sometimes I obtain the following error:
08-06 15:06:14.110: E/dalvikvm-heap(3527): Out of memory on a 2380816-byte allocation.
08-06 15:06:14.110: W/dalvikvm(3527): threadid=1: thread exiting with uncaught exception (group=0x40a3d1f8)
08-06 15:06:14.120: E/AndroidRuntime(3527): FATAL EXCEPTION: main
08-06 15:06:14.120: E/AndroidRuntime(3527): java.lang.OutOfMemoryError
08-06 15:06:14.120: E/AndroidRuntime(3527): at android.graphics.BitmapFactory.nativeDecodeStream(Native Method)
08-06 15:06:14.120: E/AndroidRuntime(3527): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:493)
08-06 15:06:14.120: E/AndroidRuntime(3527): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:299)
08-06 15:06:14.120: E/AndroidRuntime(3527): at android.graphics.BitmapFactory.decodeFile(BitmapFactory.java:324)
08-06 15:06:14.120: E/AndroidRuntime(3527): at android.graphics.drawable.Drawable.createFromPath(Drawable.java:880)
08-06 15:06:14.120: E/AndroidRuntime(3527): at host.framework.component.MySimpleArrayAdapter.getView(MySimpleArrayAdapter.java:56)
08-06 15:06:14.120: E/AndroidRuntime(3527): at android.widget.AbsListView.obtainView(AbsListView.java:2012)
08-06 15:06:14.120: E/AndroidRuntime(3527): at android.widget.ListView.makeAndAddView(ListView.java:1772)
08-06 15:06:14.120: E/AndroidRuntime(3527): at android.widget.ListView.fillUp(ListView.java:705)
08-06 15:06:14.120: E/AndroidRuntime(3527): at android.widget.ListView.fillGap(ListView.java:645)
08-06 15:06:14.120: E/AndroidRuntime(3527): at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4546)
08-06 15:06:14.120: E/AndroidRuntime(3527): at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:3813)
08-06 15:06:14.120: E/AndroidRuntime(3527): at android.os.Handler.handleCallback(Handler.java:605)
08-06 15:06:14.120: E/AndroidRuntime(3527): at android.os.Handler.dispatchMessage(Handler.java:92)
08-06 15:06:14.120: E/AndroidRuntime(3527): at android.os.Looper.loop(Looper.java:137)
08-06 15:06:14.120: E/AndroidRuntime(3527): at android.app.ActivityThread.main(ActivityThread.java:4424)
08-06 15:06:14.120: E/AndroidRuntime(3527): at java.lang.reflect.Method.invokeNative(Native Method)
08-06 15:06:14.120: E/AndroidRuntime(3527): at java.lang.reflect.Method.invoke(Method.java:511)
08-06 15:06:14.120: E/AndroidRuntime(3527): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
08-06 15:06:14.120: E/AndroidRuntime(3527): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
08-06 15:06:14.120: E/AndroidRuntime(3527): at dalvik.system.NativeStart.main(Native Method)
08-06 15:06:14.120: W/ActivityManager(149): Force finishing activity host.activity/.ACT_CircoliDiSupporto
08-06 15:06:14.640: W/ActivityManager(149): Activity pause timeout for ActivityRecord{413de508 host.activity/.ACT_CircoliDiSupporto}
08-06 15:06:24.140: W/ActivityManager(149): Launch timeout has expired, giving up wake lock!
08-06 15:06:24.650: W/ActivityManager(149): Activity idle timeout for ActivityRecord{41389d58 host.activity/.HostActivity}
The line 56 (highlighted in the code) seems to generate the error
Drawable c = Drawable.createFromPath(basePath+foto[position]);
Upvotes: 3
Views: 1475
Reputation: 15476
There are a number of problems with the current implementation:
Drawable c = Drawable.createFromPath(basePath+foto[position]); // line 56
), this would make your list scrolling quite choppyI would suggest you to use Universal Image Loader library (https://github.com/nostra13/Android-Universal-Image-Loader) which would solve all of the above issues. Though I am not sure if it provides native local image loading capability or if you have to extend some class to have such a capability.
[Edit]
I wouldn't recommend rolling your own solution as it'll take more time than you'd first imagined (trust me...). But if you really want to do it you can check out this tutorial: http://codehenge.net/blog/2011/06/android-development-tutorial-asynchronous-lazy-loading-and-caching-of-listview-images/
The above tutorial solves #1 & #2, for #3 check this: Strange out of memory issue while loading an image to a Bitmap object
Upvotes: 3
Reputation: 2878
First of all you need a data structure like LruCache to hold the drawables that are being created.
How can I be sure that my objects are correctly released?
On activity destroy with usage the data structure, make sure the object of the class is being made null or clearing internal objects of it. (This will tell the gc that this object is ready to be cleared (in most cases)).
Also running a file operation on main thread is not the best approach as it will introduce jerkiness in listview scrolling. Try to do this in secondary thread.
Upvotes: 1