I have a launcher Activity
that load and resize big bitmap as it's background when it opens.
Whenever hit the back button, the Activity
is destroyed
. But I think the memory is not released yet.
When I open back the app, hit the back button and open it again (repeatedly), I will get a OutOfMemoryError
.
I am sorry for this newbie question but I am wondering how do I release the memory whenever an Activity
is destroyed
?
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_welcome);
//MARK - movingBackgroundImageView
movingBackgroundImageView = (ImageView) findViewById(R.id.movingBackgroundImageView);
movingBackgroundImageView.setColorFilter(Color.argb(255, 255, 255, 255));
movingBackgroundImageView.setScaleType(ImageView.ScaleType.MATRIX);
movingBackgroundImageView.setAlpha(0.28f);
prepareBackgroundAnimation();
}
private void prepareBackgroundAnimation() {
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
screenWidth = displaymetrics.widthPixels;
screenHeight = displaymetrics.heightPixels;
movingImageHeight = displaymetrics.heightPixels;
movingImageWidth = 1920.0 / 1080.0 * movingImageHeight;
bitmapImage = BitmapFactory.decodeResource(this.getResources(), R.drawable.moving_background_image);
scaledBitmap = bitmapImage.createScaledBitmap(bitmapImage, (int) movingImageWidth, (int) movingImageHeight, false);
movingBackgroundImageView.setImageBitmap(scaledBitmap);
backgroundImageInBeginning = true;
movingBackgroundImageView.post(new Runnable() {
@Override
public void run() {
movingBackgroundImageView.setImageMatrix(matrix);
moveBackground();
}
});
}
12-22 13:44:49.549 30885-30885/? E/AndroidRuntime: FATAL EXCEPTION: main Process: id.testingapp.android.TestingApp, PID: 30885 java.lang.OutOfMemoryError: Failed to allocate a 26211852 byte allocation with 14018312 free bytes and 13MB until OOM at dalvik.system.VMRuntime.newNonMovableArray(Native Method) at android.graphics.Bitmap.nativeCreate(Native Method) at android.graphics.Bitmap.createBitmap(Bitmap.java:939) at android.graphics.Bitmap.createBitmap(Bitmap.java:912) at android.graphics.Bitmap.createBitmap(Bitmap.java:843) at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:719) at id.testingapp.android.TestingApp.WelcomeActivity.prepareBackgroundAnimation(WelcomeActivity.java:140) at id.TestingApp.android.TestingApp.WelcomeActivity.onCreate(WelcomeActivity.java:72) at android.app.Activity.performCreate(Activity.java:6283) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2646) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2758) at android.app.ActivityThread.access$900(ActivityThread.java:177) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:145) at android.app.ActivityThread.main(ActivityThread.java:5942) 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:1400) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1195)
EDIT:
I have tried to put all these in onDestroyed()
but the problem persists
@Override
protected void onDestroy() {
finish();
bitmapImage = null;
scaledBitmap = null;
super.onDestroy();
Runtime.getRuntime().gc();
System.gc();
}
Add following code for it
@Override
protected void onDestroy() {
//android.os.Process.killProcess(android.os.Process.myPid());
super.onDestroy();
if(scaledBitmap!=null)
{
scaledBitmap.recycle();
scaledBitmap=null;
}
}
In activity if you're calling the finish()
method from is destroyed and all its resources are queued for garbage collection.
So, all memory that was used by this activity will be freed during next GC cycle.
OR
you can try this to clean memory,
@Override
public void onDestroy() {
super.onDestroy();
Runtime.getRuntime().gc();
}
check this details. hope that helps.
Try to set the bitmap to null while activity is destroyed and if desire run the garbage collector.
add this to your code
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK))
{
finish();
}
return super.onKeyDown(keyCode, event);
}
even after destroying the activity by calling finish(), it's resources are queued for garbage collection. activity will be freed during next GC cycle.
@Override
public void onDestroy() {
super.onDestroy();
Runtime.getRuntime().gc();
}
You can also use android:largeHeap="true"
to request a larger heap size, in your application tag in manifest.
try to finish the activity when pressing back button
@Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
Finishing an Activity doesn't clear its memory. It only removes the Activity from its stack, Android will clear its memory when it needs memory (garbage collection),if you face memory issue from drawable,
- Reducing the drawable size may solve your problem.
- Insufficient memory in Android devices also leads to memory issues.
来源:https://stackoverflow.com/questions/34409549/release-memory-of-particular-activity-when-it-is-destroyed