Reputation: 321
I want to display some random images from my drawable folder when I press a button.
I named my photos "img_0"...to "img_51"
This is what I tried :
ImageView card1, card2, card3, card4, card5;
Button bPlay;
ArrayList<Integer> numbers = new ArrayList<Integer>();
Random randomGenerator = new Random();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
setContentView(R.layout.activity_play);
setReferences();
}
private void setReferences() {
card1 = (ImageView) findViewById(R.id.card1);
card2 = (ImageView) findViewById(R.id.card2);
card3 = (ImageView) findViewById(R.id.card3);
card4 = (ImageView) findViewById(R.id.card4);
card5 = (ImageView) findViewById(R.id.card5);
bPlay = (Button) findViewById(R.id.bPlay2);
bPlay.setOnClickListener(this);
}
private void getRandomNumbers() {
while(numbers.size() < 5) {
int random = randomGenerator .nextInt(51);
if (!numbers.contains(random)) {
numbers.add(random);
}
}
}
private void clearArrayList() {
for(int i = numbers.size()-1 ; i >= 0; i--){
numbers.remove(numbers.get(i));
}
}
private void setBitmap(ImageView iv, int n) {
String str = "img_" + numbers.get(n);
int resID = getResources().getIdentifier(str, "drawable", getPackageName());
iv.setImageResource(resID);
}
@Override
public void onClick(View v) {
getRandomNumbers();
setBitmap(card1, 0);
setBitmap(card2, 1);
setBitmap(card3, 2);
setBitmap(card4, 3);
setBitmap(card5, 4);
clearArrayList();
}
I was looking in the memory tab from the emulator, and I saw that the memory is very highly used...
How can I reduce the memory usage? only when I press one time the button it has 70 and something in the VM HEAP.
Any idea is very welcomed !
I tried also with Bitmap and recycle but it gives me error.. Application has stopped working...
Here is what i tried :
private void setBitmap(ImageView iv, int n) {
String str = "img_" + numbers.get(n);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), getResourceID(str, "drawable",
this));
iv.setImageBitmap(bitmap);
bitmap.recycle();
}
Here is the logcat :
07-10 16:57:10.402 1906-1906/? I/art﹕ Not late-enabling -Xcheck:jni (already on)
07-10 16:57:14.321 1906-1937/com.symplyfyweb.gherghina.oldschoolwesternpoker D/OpenGLRenderer﹕ Use EGL_SWAP_BEHAVIOR_PRESERVED: true
07-10 16:57:14.335 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker D/﹕ HostConnection::get() New Host Connection established 0xb4a93f40, tid 1906
07-10 16:57:14.349 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker D/Atlas﹕ Validating map...
07-10 16:57:14.813 1906-1937/com.symplyfyweb.gherghina.oldschoolwesternpoker D/﹕ HostConnection::get() New Host Connection established 0xb4b270b0, tid 1937
07-10 16:57:14.957 1906-1937/com.symplyfyweb.gherghina.oldschoolwesternpoker I/OpenGLRenderer﹕ Initialized EGL, version 1.4
07-10 16:57:15.032 1906-1937/com.symplyfyweb.gherghina.oldschoolwesternpoker D/OpenGLRenderer﹕ Enabling debug mode 0
07-10 16:57:15.054 1906-1937/com.symplyfyweb.gherghina.oldschoolwesternpoker W/EGL_emulation﹕ eglSurfaceAttrib not implemented
07-10 16:57:15.063 1906-1937/com.symplyfyweb.gherghina.oldschoolwesternpoker W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xb4b23b00, error=EGL_SUCCESS
07-10 16:57:15.169 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/Choreographer﹕ Skipped 38 frames! The application may be doing too much work on its main thread.
07-10 16:57:16.748 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/Choreographer﹕ Skipped 93 frames! The application may be doing too much work on its main thread.
07-10 16:57:22.533 1906-1937/com.symplyfyweb.gherghina.oldschoolwesternpoker W/EGL_emulation﹕ eglSurfaceAttrib not implemented
07-10 16:57:22.533 1906-1937/com.symplyfyweb.gherghina.oldschoolwesternpoker W/OpenGLRenderer﹕ Failed to set EGL_SWAP_BEHAVIOR on surface 0xb4b23cc0, error=EGL_SUCCESS
07-10 16:57:23.378 1906-1913/com.symplyfyweb.gherghina.oldschoolwesternpoker W/art﹕ Suspending all threads took: 19.779ms
07-10 16:57:28.898 1906-1913/com.symplyfyweb.gherghina.oldschoolwesternpoker W/art﹕ Suspending all threads took: 12.510ms
07-10 16:57:31.940 1906-1918/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Clamp target GC heap from 66MB to 64MB
07-10 16:57:32.352 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Alloc sticky concurrent mark sweep GC freed 8(432B) AllocSpace objects, 0(0B) LOS objects, 1% free, 62MB/64MB, paused 1.468ms total 17.160ms
07-10 16:57:32.378 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Clamp target GC heap from 66MB to 64MB
07-10 16:57:32.378 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Alloc partial concurrent mark sweep GC freed 14(576B) AllocSpace objects, 0(0B) LOS objects, 1% free, 62MB/64MB, paused 889us total 19.090ms
07-10 16:57:32.444 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Clamp target GC heap from 66MB to 64MB
07-10 16:57:32.444 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Alloc concurrent mark sweep GC freed 8(12KB) AllocSpace objects, 0(0B) LOS objects, 1% free, 62MB/64MB, paused 789us total 57.650ms
07-10 16:57:32.451 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Forcing collection of SoftReferences for 12MB allocation
07-10 16:57:32.501 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Clamp target GC heap from 66MB to 64MB
07-10 16:57:32.502 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Alloc concurrent mark sweep GC freed 11(288B) AllocSpace objects, 0(0B) LOS objects, 1% free, 62MB/64MB, paused 799us total 49.442ms
07-10 16:57:32.507 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker E/art﹕ Throwing OutOfMemoryError "Failed to allocate a 13068012 byte allocation with 1263808 free bytes and 1234KB until OOM"
07-10 16:57:32.524 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Alloc sticky concurrent mark sweep GC freed 5(448B) AllocSpace objects, 0(0B) LOS objects, 1% free, 62MB/64MB, paused 731us total 14.526ms
07-10 16:57:32.550 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Clamp target GC heap from 66MB to 64MB
07-10 16:57:32.551 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Alloc partial concurrent mark sweep GC freed 10(376B) AllocSpace objects, 0(0B) LOS objects, 1% free, 62MB/64MB, paused 954us total 19.113ms
07-10 16:57:32.664 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Clamp target GC heap from 66MB to 64MB
07-10 16:57:32.665 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Alloc concurrent mark sweep GC freed 3(96B) AllocSpace objects, 0(0B) LOS objects, 1% free, 62MB/64MB, paused 1.193ms total 108.749ms
07-10 16:57:32.675 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker W/art﹕ Suspending all threads took: 9.507ms
07-10 16:57:32.675 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Forcing collection of SoftReferences for 12MB allocation
07-10 16:57:32.770 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Clamp target GC heap from 66MB to 64MB
07-10 16:57:32.770 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker I/art﹕ Alloc concurrent mark sweep GC freed 3(96B) AllocSpace objects, 0(0B) LOS objects, 1% free, 62MB/64MB, paused 11.517ms total 93.336ms
07-10 16:57:32.775 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker E/art﹕ Throwing OutOfMemoryError "Failed to allocate a 13068012 byte allocation with 1263992 free bytes and 1234KB until OOM"
07-10 16:57:32.777 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker D/skia﹕ --- allocation failed for scaled bitmap
07-10 16:57:32.779 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker D/AndroidRuntime﹕ Shutting down VM
--------- beginning of crash
07-10 16:57:32.802 1906-1906/com.symplyfyweb.gherghina.oldschoolwesternpoker E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.symplyfyweb.gherghina.oldschoolwesternpoker, PID: 1906
java.lang.OutOfMemoryError: Failed to allocate a 13068012 byte allocation with 1263992 free bytes and 1234KB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method)
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609)
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444)
at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:467)
at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:497)
at com.symplyfyweb.gherghina.oldschoolwesternpoker.PlayActivity.setBitmap(PlayActivity.java:97)
at com.symplyfyweb.gherghina.oldschoolwesternpoker.PlayActivity.onClick(PlayActivity.java:112)
at android.view.View.performClick(View.java:4780)
at android.view.View$PerformClick.run(View.java:19866)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
Upvotes: 0
Views: 1424
Reputation: 2358
Besides recycling bitmaps, one thing that can really help is to not load a full size bitmap if you don't need it. For instance, if you are trying to load images that were taken using the device camera, they probably have a much higher resolution than you are able to show on your display anyway (for example, the full size image may be 2000 x 20000 pixels and you may be trying to display it in an ImageView that is 500 x 500 pixels). The full size bitmap will take up a lot more room in memory and in reality you will be discarding a lot of the pixels when showing on a reduced size imageview.
Try this SO post to learn how to reduce the memory footprint of a bitmap if the ImageView it will be displayed in isn't as big as the full-size image:
How to scale bitmap to screen size?
Upvotes: 0
Reputation: 1937
// create second array list:
ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>();
private void clearArrayList() {
numbers.clear();
for(Bitmap bitmap : bitmaps)
{
bitmap.recycle();
}
bitmaps.clear();
}
@Override
public void onClick(View v) {
clearArrayList();
getRandomNumbers();
setBitmap(card1, 0);
setBitmap(card2, 1);
setBitmap(card3, 2);
setBitmap(card4, 3);
setBitmap(card5, 4);
}
Edit:
private void setBitmap(ImageView iv, int n) {
String str = "img_" + numbers.get(n);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), getResourceID(str, "drawable",
this));
iv.setImageBitmap(bitmap);
bitmaps.add(bitmap);
}
Upvotes: 0
Reputation: 520
You should really cache your images so that they only need to be loaded one time.
It would be very simple, all you would have to do is when you go to load a bitmap, check to see if it's already in the cache and if it is then use that. If it isn't then load the image. This will prevent you from loading resources multiple times.
HashMap<String, Integer> resCache = new HashMap<String, Integer>();
...
...
private void setBitmap(ImageView iv, int n) {
String str = "img_" + numbers.get(n);
int resID = -1;
if (resCache.containsKey(str)) {
resID = resCache.get (str);
} else {
resID = getResources().getIdentifier(str, "drawable", getPackageName());
resCache.put (str, resID);
}
iv.setImageResource(resID);
}
Upvotes: 1