4

The application has one main activity and two fragments. The main activity hosts MainFragment and MainFragment contain a button to commit BreedingFragment (run). The application works fine only when the orientation is not changed but crashes when the BreedingFragment is open and orientation changes.

After investigating on stackoverflow for few hours, I found the following articles and followed the answers but It did not debug the problem.

  1. Android Application Crashes With Orientation Changes
  2. Orientation change Crash Application
  3. Rotation of screen crashes android app
  4. My Android application crashes when I change screen orientation

The answers mainly suggest to use the following code in AndroidManifest.xml:

android:configChanges="orientation|keyboardHidden|screenSize"

The last thread suggests the following to consider:

The activity actually stops and restarts every time the device orientation changes. You need to write your thread with that in mind, i.e. stopping the thread and restarting it when the device changes orientation, perhaps saving the state in between.

MainActivity:

public class MainActivity extends FragmentActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

MainFragment:

public class MainFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View v = inflater.inflate(R.layout.fragment_main, container, false);

        Button breedButton = (Button) v.findViewById(R.id.pokemon_breeding_button);

        breedButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
                final FragmentTransaction transaction = fragmentManager.beginTransaction();
                transaction.replace(R.id.fragment, new BreedingFragment());
                transaction.addToBackStack(null);
                transaction.commit();
            }
        });
        return v;
    }
}

BreedingFragment:

public class BreedingFragment extends Fragment {

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        return inflater.inflate(R.layout.fragment_breeding, container, false);
    }
}

Log Cat:

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.revittechnology.zapdos, PID: 12795
                  java.lang.RuntimeException: Unable to start activity ComponentInfo{com.revittechnology.zapdos/com.revittechnology.zapdos.MainActivity}: android.view.InflateException: Binary XML file line #24: Error inflating class fragment
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2429)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2493)
                      at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4014)
                      at android.app.ActivityThread.access$900(ActivityThread.java:166)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1289)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:136)
                      at android.app.ActivityThread.main(ActivityThread.java:5590)
                      at java.lang.reflect.Method.invokeNative(Native Method)
                      at java.lang.reflect.Method.invoke(Method.java:515)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1280)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1096)
                      at dalvik.system.NativeStart.main(Native Method)
                   Caused by: android.view.InflateException: Binary XML file line #24: Error inflating class fragment
                      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:720)
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:762)
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:771)
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:771)
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:499)
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:354)
                      at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:331)
                      at android.app.Activity.setContentView(Activity.java:2018)
                      at com.revittechnology.zapdos.MainActivity.onCreate(MainActivity.java:13)
                      at android.app.Activity.performCreate(Activity.java:5447)
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094)
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2393)
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2493) 
                      at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4014) 
                      at android.app.ActivityThread.access$900(ActivityThread.java:166) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1289) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:136) 
                      at android.app.ActivityThread.main(ActivityThread.java:5590) 
                      at java.lang.reflect.Method.invokeNative(Native Method) 
                      at java.lang.reflect.Method.invoke(Method.java:515) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1280) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1096) 
                      at dalvik.system.NativeStart.main(Native Method) 
                   Caused by: java.lang.IllegalStateException: Fragment com.revittechnology.zapdos.MainFragment did not create a view.
                      at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2319)
                      at android.support.v4.app.FragmentController.onCreateView(FragmentController.java:120)
                      at android.support.v4.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:356)
                      at android.support.v4.app.BaseFragmentActivityHoneycomb.onCreateView(BaseFragmentActivityHoneycomb.java:31)
                      at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:79)
                      at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:696)
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:762) 
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:771) 
                      at android.view.LayoutInflater.rInflate(LayoutInflater.java:771) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:499) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:398) 
                      at android.view.LayoutInflater.inflate(LayoutInflater.java:354) 
                      at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:331) 
                      at android.app.Activity.setContentView(Activity.java:2018) 
                      at com.revittechnology.zapdos.MainActivity.onCreate(MainActivity.java:13) 
                      at android.app.Activity.performCreate(Activity.java:5447) 
                      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1094) 
                      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2393) 
                      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2493) 
                      at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:4014) 
                      at android.app.ActivityThread.access$900(ActivityThread.java:166) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1289) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:136) 
                      at android.app.ActivityThread.main(ActivityThread.java:5590) 
                      at java.lang.reflect.Method.invokeNative(Native Method) 
                      at java.lang.reflect.Method.invoke(Method.java:515) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1280) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1096) 
                      at dalvik.system.NativeStart.main(Native Method) 
I/Process: Sending signal. PID: 12795 SIG: 9
Application terminated.
Community
  • 1
  • 1
Maihan Nijat
  • 9,054
  • 11
  • 62
  • 110
  • Stack Overflow is for programming questions. What is your question? If your question is "why am I crashing?", use LogCat to examine the Java stack trace associated with your crash: https://stackoverflow.com/questions/23353173/unfortunately-myapp-has-stopped-how-can-i-solve-this – CommonsWare Sep 25 '16 at 22:16
  • Yes, if your question is about the cause of the crash that you're observing, then please post the crash stacktrace here. – Tobias Sep 25 '16 at 22:17
  • 1
    You shouldn't have your Fragments replace themselves – OneCricketeer Sep 25 '16 at 22:18
  • @cricket_007 What do you suggest instead? Thanks – Maihan Nijat Sep 25 '16 at 22:19
  • 1
    If you follow this guide, it shows how to "callback" to the activity to replace a Fragment on a click event. https://developer.android.com/training/basics/fragments/communicating.html – OneCricketeer Sep 25 '16 at 22:21
  • You have to place the ConfigChanges line into the scope of your activity in Manifest file. – crakxx Sep 25 '16 at 22:40

1 Answers1

0

Main Activity and Main Fragment. The above photo elaborates the case. MainActivity.java which hosts MainFragment.java and the Main Fragment has one button which launches another fragment.

What are my requirements?

  1. The Main Activity just hosts the Main Fragment and doesn't have anything else.
  2. Main Fragment has button to launch second Fragment.
  3. Close (end/ finish) the second Fragment when back button is pressed (return to Main Activity).
  4. Works with device (screen) rotation.

The first step is to create Main Activity. There are few things to consider in Main Activity:

  1. Extends MainActivity to FragmentActivity

public class MainActivity extends FragmentActivity as follows:

  1. Check savedInstanceState and if it is null then run the MainFragment. The reason we are doing this to avoid running again and again the MainFragment with device rotation.

Here is the code for MainActivity.java:

public class MainActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            FragmentManager fManager = getSupportFragmentManager();
            FragmentTransaction fTransaction = fManager.beginTransaction();
            fTransaction.add(R.id.fragment, new MainFragment());
            fTransaction.commit();
        }

    }
}

Make sure to have following lines of code in activity_main.xml:

<FrameLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:name="com.revittechnology.zapdos.MainFragment"
    android:id="@+id/fragment" /> 

Now create MainFragment.java:

public class MainFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_main, container, false);
        // Inflate the layout for this fragment
        Button breedButton = (Button) v.findViewById(R.id.pokemon_breeding_button);

        breedButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
                final FragmentTransaction transaction = fragmentManager.beginTransaction();
                transaction.replace(R.id.fragment, new BreedingFragment());
                transaction.addToBackStack("tag");
                transaction.commit();
            }
        });
        return v;
    }
}

Include all the code before returning the view (return v) because it is not possible to find button and other elements of layout if the view is not exist. The transaction.addToBackStack("tag"); helps to add the fragment into back-stack and enables to return to close the fragment with back-press.

Now create the second fragment BreedingFragment.java`:

public class BreedingFragment extends Fragment {
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_breeding, container, false);
    }
}

Note: Import the required libraries for above classes before declaring the class.

Conclusion: The app was crashing with device orientation because the second fragment was launched with button click and MainFragment was hosts by MainActivity. With the device orientation the Fragments were closed and there was no code in MainActivity.java to initiate the fragments again, therefore, it was giving empty exceptional error. After adding the fragment related code into MainActivity.java to initiate the fragment programatically solved the problem.

Maihan Nijat
  • 9,054
  • 11
  • 62
  • 110