5

I'm sorry if this is broad, inappropriate or a dupe, feel free to flag.

However I couldn't find a solution. I'm getting StackOverflowError, and Android Studio shows -

08-03 16:22:49.293    5163-5163/com.package E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.StackOverflowError
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5384)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(ViewGroup.java:5388)
            at android.view.ViewGroup.jumpDrawablesToCurrentState(V

I spent hours right now trying to understand what's wrong: I'm not aware of any recursive call in my code. I'm asking:

  • Do you have any suggestion about what could be causing this particular issue?
  • Do you have any suggestion about how to technically face similar issues? Any way to get to the "root" cause in the stack? There should be some recursive stuff going on, but it surely has (a) a starting point, and a call to that point; (b) an end, when the StackOverflowError is thrown. We can see the end part, but not the start, because the logcat stops.
natario
  • 24,954
  • 17
  • 88
  • 158
  • Show some code. This is StackOverflowError which means you are recursively calling same method without break. – kosa Aug 03 '15 at 14:37
  • 2
    It is clearly on line `ViewGroup.java:5388` – dotvav Aug 03 '15 at 14:37
  • You could have searched for others with the same problem : http://stackoverflow.com/q/12858264/2001247. Possible solution : LayoutInflater.inflate([subViewOfViewPager],[ParentOfViewPager]) change to LayoutInflater.inflate([subViewOfViewPager],null) (this is most probably wrong, but you are not giving much) – ElDuderino Aug 03 '15 at 14:39
  • where is your the code? – dsharew Aug 03 '15 at 14:42
  • @ElDuderino that is a good clue! I spent a lot searching, but focused on StackOverflows and debug approaches. I guess my first question is solved, we can leave it open for the second "best approach" question, or close it as a dupe. Thank you. – natario Aug 03 '15 at 14:45
  • @dotvav you might know that ViewGroup.jumpDrawablesToCurrentState() is a framework method, called mostly (and often) by the framework itself. Hard to tell something from that, for me. – natario Aug 03 '15 at 14:55
  • @mvai Clearly, you are having circular references in your `View` parent's hierarchy. Get a look at the `ViewGroup` source, the method `jumpDrawablesToCurrentState` is quite simple. – dotvav Aug 03 '15 at 15:02

1 Answers1

11

I had this issue today working with fragments. This code was sufficient to cause the error:

public static class ProductionFragment extends Fragment {   
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.something, container);
        return view;
    }
}

The solution was one of the following:

//The preferred way
View view = inflater.inflate(R.layout.something, container, false);

//Not optimal but still working way
View view = inflater.inflate(R.layout.something, null);

When I call inflater.inflate() method with two params, the inflater implicitly tries to attach the inflated view to the container. This causes the newly created view to be already attached to the fragment even if we still didn't return our view.

If we pass a null as the second param, Android Studio reminds us that

When inflating a layout, avoid passing in null as the parent view, since otherwise any layout parameters on the root of the inflated layout will be ignored.

technically driving us to fill the second param.

The best way to manage it is to keep track of the container parameters by passing it to the function and NOT adding our view to the root. This is done by calling inflate with three parameters:

inflater.inflate(R.layout.something, container, false);

where the last false tells the inflate method to not add the view to the container view we've supplied.

So, to prevent this mistake in the future, how to programmatically decide what overload of inflate method use?

  • Are you implementing a method that asks you to return a view and the view appending is not not meant to be done by you? (Fragments, ListAdapter of ListView/Spinners...)

    Use inflater.inflate(R.layout.something, container, false);

  • Are you building your interface from code and what you're loading is going to be the container?

    Use inflater.inflate(R.layout.something, null);

  • Are you inflating something that you're planning to manually add to an another container?

    Use inflater.inflate(R.layout.something, container); and do not add the item to the container (it already does it).

Bob
  • 2,430
  • 22
  • 27
  • I don't remember it exactly but my error was definitely related. I'd say this is a good answer to a poorly-worded question (an appropriate title would have been: how to debug stackoverflows when they happen on android SDK methods that are called internally by the framework itself, and you can't see anything yours in the stack trace?). Unlike comments above, you got the point. – natario Oct 28 '15 at 14:17