0

I have an simplest app. in which there is no heavy programming going on. I Have 2 activities and I am going to and fro from one activity to another for Example I am going to Activity2 from Activity1 and then Back to Activity1 from Activity2.

By doing this multiple time I am getting OOM error and app crashes at that time I have no clue why it is happening only by just setting the background image and button in Activity1 and in Activity2 there is only background image, and a image view and a single button

On going back I am destroying Activity2 using onDestroy method also and using this method also in Activity1 but it stills not working to get some memory empty.

Here is the full stacktrace

E/AndroidRuntime: FATAL EXCEPTION: main Process: com.efu.myprojet, PID: 4241 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.efu.myprojet/com.efu.myprojet.MainActivity}: android.view.InflateException: Binary XML file line #1: Error inflating class at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2702) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2767) at android.app.ActivityThread.access$900(ActivityThread.java:177) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:145) at android.app.ActivityThread.main(ActivityThread.java:5951) 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) Caused by: android.view.InflateException: Binary XML file line #1: Error inflating class at android.view.LayoutInflater.createView(LayoutInflater.java:640) at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55) at android.view.LayoutInflater.onCreateView(LayoutInflater.java:689) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:748) at android.view.LayoutInflater.inflate(LayoutInflater.java:483) at android.view.LayoutInflater.inflate(LayoutInflater.java:415) at android.view.LayoutInflater.inflate(LayoutInflater.java:366) at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:267) at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:129) at com.efu.myprojet.MainActivity.onCreate(MainActivity.java:69) at android.app.Activity.performCreate(Activity.java:6289) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2655) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2767)  at android.app.ActivityThread.access$900(ActivityThread.java:177)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:145)  at android.app.ActivityThread.main(ActivityThread.java:5951)  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)  Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Constructor.newInstance(Native Method) at java.lang.reflect.Constructor.newInstance(Constructor.java:288) at android.view.LayoutInflater.createView(LayoutInflater.java:614) at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55)  at android.view.LayoutInflater.onCreateView(LayoutInflater.java:689)  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:748)  at android.view.LayoutInflater.inflate(LayoutInflater.java:483)  at android.view.LayoutInflater.inflate(LayoutInflater.java:415)  at android.view.LayoutInflater.inflate(LayoutInflater.java:366)  at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:267)  at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:129)  at com.efu.myprojet.MainActivity.onCreate(MainActivity.java:69)  at android.app.Activity.performCreate(Activity.java:6289)  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2655)  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2767)  at android.app.ActivityThread.access$900(ActivityThread.java:177)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:145)  at android.app.ActivityThread.main(ActivityThread.java:5951)  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)  Caused by: java.lang.OutOfMemoryError: Failed to allocate a 9216012 byte allocation with 2044572 free bytes and 1996KB until OOM at dalvik.system.VMRuntime.newNonMovableArray(Native Method) at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:747) at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:568) at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1014) at android.content.res.Resources.loadDrawableForCookie(Resources.java:3747) at android.content.res.Resources.loadDrawable(Resources.java:3620) at android.content.res.TypedArray.getDrawable(TypedArray.java:762) at android.view.View.(View.java:3957) at android.view.ViewGroup.(ViewGroup.java:507) at android.widget.RelativeLayout.(RelativeLayout.java:249) at android.widget.RelativeLayout.(RelativeLayout.java:245) at android.widget.RelativeLayout.(RelativeLayout.java:241) at java.lang.reflect.Constructor.newInstance(Native Method)  at java.lang.reflect.Constructor.newInstance(Constructor.java:288)  at android.view.LayoutInflater.createView(LayoutInflater.java:614)  at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:55)  at android.view.LayoutInflater.onCreateView(LayoutInflater.java:689)  at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:748)  at android.view.LayoutInflater.inflate(LayoutInflater.java:483)  at android.view.LayoutInflater.inflate(LayoutInflater.java:415)  at android.view.LayoutInflater.inflate(LayoutInflater.java:366)  at android.support.v7.app.AppCompatDelegateImplV7.setContentView(AppCompatDelegateImplV7.java:267)  at android.support.v7.app.AppCompatActivity.setContentView(AppCompatActivity.java:129)  at com.efu.myprojet.MainActivity.onCreate(MainActivity.java:69)  at android.app.Activity.performCreate(Activity.java:6289)  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2655)  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2767)  at android.app.ActivityThread.access$900(ActivityThread.java:177)  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1449)  at android.os.Handler.dispatchMessage(Handler.java:102)  at android.os.Looper.loop(Looper.java:145)  at android.app.ActivityThread.main(ActivityThread.java:5951)  at java.lang.reflect.Method.invoke(Native Method)  at java.lang.reflect.Method.invoke(Method.java:372) 

Update 1 :

Adding my xmls Xml of first Activity

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.efu.myproject.FirstActivity"
    android:background="@drawable/bg_enter_the_book">


    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true"
        android:id="@+id/lLayout"
        android:padding="10dp">
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:layout_alignParentBottom="true"
            android:background="@drawable/btn_next"
            android:onClick="EnterTheJungleBookButton"
            android:text="           "
            android:visibility="invisible"
            android:layout_marginBottom="20dp"/>
    </LinearLayout>
</RelativeLayout>

Activity2 Named MainActivity

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/background"
    tools:context="com.efu.myproject.MainActivity">

       <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:src="@drawable/bg_anim_name"
            android:id="@+id/iv_anim_name"/>

        <TextView
            android:id="@+id/tv_anim_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:layout_centerHorizontal="true"
            android:keepScreenOn="true"
            android:text="@string/dummy_content"
            android:textColor="#ffffff"
            android:textSize="@dimen/tv_anim_name"
            android:textStyle="bold"
            android:layout_above="@+id/tv_empty"/>
        <TextView
            android:id="@+id/tv_empty"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:layout_centerHorizontal="true"
            android:keepScreenOn="true"
            android:text="sdasdasd"
            android:visibility="invisible"
            android:textColor="#33b5e5"
            android:textSize="@dimen/tv_empty"
            android:layout_alignBaseline="@+id/iv_anim_name"
            android:layout_alignBottom="@+id/iv_anim_name"
            android:textStyle="bold"
            />
    </RelativeLayout>

    <ImageView
        android:id="@+id/iv_anim_pic"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:maxHeight="@dimen/iv_anim_pic_height"
        android:src="@drawable/ic_launcher" />

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_gravity="bottom|center_horizontal"
        android:fitsSystemWindows="true">

        <RelativeLayout
            android:id="@+id/fullscreen_content_controls"
            style="?metaButtonBarStyle"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|center_horizontal"

            android:orientation="horizontal"
            tools:ignore="UselessParent">

            <Button
                android:id="@+id/btn_next"
                style="?metaButtonBarButtonStyle"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:background="@drawable/btn_next"
                android:layout_alignParentTop="true"
                android:layout_centerHorizontal="true" />

        </RelativeLayout>
    </FrameLayout>

</RelativeLayout>

Also I have a static class which contains the resources of my app and I am retrieving those resources from that static class for example

ivAnimPicture.setImageResource(NextResource.getPicture(anyRandomNum));

here is my that Class which contains resources

    public class NextResource {

    static int[] animPics  =  {R.drawable.anteater,R.drawable.antelope,R.drawable.bear,
            R.drawable.bird,R.drawable.cat,R.drawable.chicken,R.drawable.cow,R.drawable.dog,
            R.drawable.duck,R.drawable.elephant,R.drawable.fox,
            R.drawable.frog,R.drawable.impala,R.drawable.lion,R.drawable.monkey,R.drawable.ostrich,
            R.drawable.panda,R.drawable.penguin,R.drawable.rabbit,
            R.drawable.sheep,R.drawable.tiger,R.drawable.vulture,R.drawable.zebra};

    static  String[] animName  = {"Anteater","Antelope","Bear","Parrot","Cat","Chicken","Cow","Dog",
            "Duck","Elephant","Fox","Frog","Impala","Lion","Monkey","Ostrich",
            "Panda","Penguin","Rabbit","Sheep","Tiger","Vulture","Zebra"};
//    public static int [] animSound = {R.raw.ballon,R.raw.billi,R.raw.carrot,
//            R.raw.fountain,R.raw.horse,R.raw.huka,R.raw.sparrow,R.raw.tea};

    public static int [] animSound = {R.raw.anteater,R.raw.antelope,R.raw.bear,
            R.raw.parrot,R.raw.cat,R.raw.chicken,R.raw.cow,R.raw.dog,
            R.raw.duck,R.raw.elephant,R.raw.fox,
            R.raw.frog,R.raw.impala,R.raw.lion,R.raw.monkey,R.raw.ostrich,
            R.raw.panda,R.raw.penguin,R.raw.fox,
            R.raw.sheep,R.raw.tiger,R.raw.vulture,R.raw.zebra};

    public static int getPicture(int i){

        return animPics[i];
    }
    public static int getSound(int i){

        return animSound[i];
    }

    public static String getName(int i){

        return animName[i];
    }
}

So what shoud I do? Where are my mistakes?

As I am using NextResource Static class to fetch my resources, is it the real reason to gain the memory again and again and not freeing the memory allocation?

Edit2

@Override
protected void onDestroy() {

    if (tts != null) {
        tts.stop();//tts is Text To Speech whcih I am using 
        tts.shutdown();
    }
    ivAnimPicture = null; //this is the Imageview to show random pics
    secureRandom = null; 
    mAccelerometer = null;
    mSensorManager = null;
    mShakeDetector = null;
    tvAnimName = null;
    btnNext = null;
    random = null;
    mediaPlayer = null;
    map = null;

    super.onDestroy();

}
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Coas Mckey
  • 701
  • 1
  • 13
  • 39
  • can you add both your layout xmls(Activity 1 and activity 2)? – Droidekas May 11 '16 at 10:16
  • yes updating my question – Coas Mckey May 11 '16 at 10:17
  • what do u mean by "I am destroying Activity2 using onDestroy method"??? Post your `onDestroy` method code. – Budius May 11 '16 at 10:24
  • I mean I am using OnDestroy method in Activity2 so that it can free the resources – Coas Mckey May 11 '16 at 10:27
  • and my surprise is that unless you're doing some pretty advanced stuff on Activity2, there's no need to do anything during onDestroy, and I'm afraid you might even not be calling `super.onDestroy()`. Reason why I asked to see the code. PS.: check my answer as I'm confident is your way forward. – Budius May 11 '16 at 10:29
  • let me add that on destroy too – Coas Mckey May 11 '16 at 10:30
  • I have added the OnDestroy – Coas Mckey May 11 '16 at 10:32
  • and I have added some more on my original answer. There's no definitive answer and you'll have to dig deeper yourself. But take it as a great learning moment that will teach you lots about the perils of the garbage collector. – Budius May 11 '16 at 10:39

3 Answers3

0

As per the log posted above, this error is occurring because of error inflating in your layout. please check your layout once or post your code to be more clear. Or is there any background task going on in your activity, where you had to load any image?

0

What you describe is the classic scenario of a memory leak.

So start from the beginning, if you don't know what a memory leak is I Googled for it and link here is for the prettiest illustration I could find on the first result page: http://www.programcreek.com/2013/10/the-introduction-of-memory-leak-what-why-and-how/

Unfortunately memory leaks can happen anywhere and even if you share your complete project to us, most wouldn't bother reading it because finding memory leaks is just so damn boring.

Said that there're methods and tools to help you out:

  • memory monitor. First things things. You should use the memory monitor on Android Studio to check that it is actually a memory leak. You'll see it happening when memory grows going to a new activity and it doesn't reduces when coming back from it.

  • LeakCanary to the rescue. The guys at square did this awesome library to automagically detect memory leaks https://github.com/square/leakcanary it doesn't do ALL the work by itself, but as you point out Activity, it should be pretty straight forward. Just follow whats on their readme.

That should get your started. Happy coding.

edit:

from your onDestroy code I can see you're using accelerometer, sensor manager, shake detector and media player. Those are all stuff that could have reference to the activity and be leaking it. Just calling null doesn't mean, the other side isn't holding your activity.

So all that just re-inforces my original answer: Learn about memory leaks, check memory monitor and use leak canary.

Budius
  • 39,391
  • 16
  • 102
  • 144
  • so How can I unrefernce them ? I mean if I am setting them to null then why do memory is not cleaning up ? Or what Else I should do – Coas Mckey May 11 '16 at 10:53
  • look on those classes for methods like: `removeListener` or `setListener(null)` or some type of `stop` or `clean up`. They can very easily be hooked in a framework level and still hold referece to your activity when you created them and setLister to be your activity. But all of this are expeculation, you really should use LeakCanary to get detailed data. – Budius May 11 '16 at 10:57
  • I am not getting it how to use it, can you please guide me How can I use the LeakCanary – Coas Mckey May 11 '16 at 11:00
  • if you mean actually use it after it's running on your application, well.. open the app, do the stuff that you know would get to memory leak (on your case enter activity 2 and then back from it). Then you wait a few seconds as LeakCanary operates on a timeout – Budius May 11 '16 at 11:03
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/111630/discussion-between-coas-mckey-and-budius). – Coas Mckey May 11 '16 at 11:09
  • i have tried that LeakCananry it has generated the dump in the following directory I/art: hprof: heap dump "/storage/emulated/0/Download/leakcanary-com.efu.myproject/suspected_leak_heapdump.hprof" starting... 05-11 16:26:32.466 25469-26098/com.efu.myproject I/art: hprof: heap dump completed (77MB) in 4.701s – Coas Mckey May 11 '16 at 11:30
  • Now there should be a Leak Canary app on your device app launcher. It shows you the leak trace in a nice UI – Budius May 11 '16 at 11:41
  • what do yow mean I didnt get that in a Launcher ? – Coas Mckey May 11 '16 at 11:58
-1

Scale down your background image size. May be you are using too large image. Please refer this and this.

Bhavin Shah
  • 361
  • 4
  • 11