title: Main Activity with Fragments, Viewpager and Tablayout - onLoadFinished not being called after orientation changes
body: <p>I have an activity which implements LoaderManager.LoaderCallbacks.</p>
  
  <p>This activity gets from a webservice an object which is used by 3 fragments.</p>
  
  <p>The first fragment shows the basic information of the object obtained from the loader. </p>
  
  <p>The second fragment shows a list contained in the object if it exists. </p>
  
  <p>The third fragment shows another list contained in the object if it exists.</p>
  
  <p>All the fragments use the same object obtained by the activity</p>
  
  <p>The structure of my app is the following :</p>
  
  <p>1- I have a main Activity in order to get an object that will be used by three Fragment classes</p>
  
  <p>2- in the activity's layout I have a android.support.design.widget.TabLayout and a android.support.v4.view.ViewPager</p>
  
  <p>3- I have a class called PagerFragmentAdapter which extends android.support.v4.app.FragmentStatePagerAdapter</p>
  
  <p>4- In the Activity's onCreate method I initialize the PagerFragmentAdapter class as follows :
             pagerFragmentAdapter = new PagerFragmentAdapter(getSupportFragmentManager());</p>
  
  <p>5- In the Activity's onCreate method I create an instance of the loaderManager as follows :
             loaderManager = getSupportLoaderManager();</p>
  
  <p>6- In the Activity's onCreate method I call -> loaderManager.initLoader(PROPOSITURA_DETAILS_LOADER_ID, null, ProposituraDetailsActivity.this);</p>
  
  <p>7- For the first time, the initiloader call the loader and the callback method onCreateLoader is called and then onLoadfinished is called</p>
  
  <p>8- After getting the object from onLoafinished I update the User Interface in a method called updateUi() </p>
  
  <p>9- in the updateUi method I get the viewpager and the tablayout as follows :</p>
  
  <pre><code>    viewPager = (ViewPager) findViewById(R.id.pager);
      tabLayout = (TabLayout) findViewById(R.id.tab_layout);
  </code></pre>
  
  <p>10- using PagerFragmentAdapter I add fragments depending on the resulted object as follows :<br>
          - if the obtained object has it's basic information I instantiate a fragment class which will show the basic information and then I add that fragment to the list of fragments in the FragmentPagerAdapter.<br>
          - if the obtained object has the "first list of objects" I instantiate the fragment class which will show the "first list of objects" and then I add that fragment to the list of fragments in the FragmentPagerAdapter.<br>
          - if the obtained object has the "second list of objects" I instantiate the fragment class which will show the "second list of objects" and then I add that fragment to the list of fragments in the FragmentPagerAdapter.  </p>
  
  <p>11- after creating the fragments according to the content of the obtained object, I set the PagerFragmentAdapter in the viewpager as follows :</p>
  
  <pre><code>     viewPager.setAdapter(pagerFragmentAdapter);
       viewPager.setCurrentItem(currentTABPosition); this line aims at keeping the current viewed page after coming back from another activity
  </code></pre>
  
  <p>12- after setting the adapter in the viewPager I set the viewPager in the TabLayout as follows :</p>
  
  <pre><code>     tabLayout.setupWithViewPager(viewPager);
  </code></pre>
  
  <p>13- then I set </p>
  
  <p>viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));</p>
  
  <p>14- then I set         </p>
  
  <pre><code>        tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
          @Override
          public void onTabSelected(TabLayout.Tab tab) {
              viewPager.setCurrentItem(tab.getPosition());
          }
  
          @Override
          public void onTabUnselected(TabLayout.Tab tab) {
  
          }
  
          @Override
          public void onTabReselected(TabLayout.Tab tab) {
  
          }
      });
  </code></pre>
  
  <p>15- after the above steps, everything works perfectly. The activity gets the needed object which is used by the fragments and the fragments are created and added to the PagerFragmentAdapter.</p>
  
  <p>16- THEN THE PROBLEM HAPPENS HERE - ON ORIENTATION CHANGE - when orientation changes, obviously the activity onCreate method is called, but when this line is called :</p>
  
  <p>loaderManager.initLoader(PROPOSITURA_DETAILS_LOADER_ID,null,ProposituraDetailsActivity.this);</p>
  
  <p>, the onLoadFinished is NEVER called and it jumps immediately to the method onCreateView of the first fragment (TabFragmentPropositura). Since the object is null because it was not obtained again from the onLoadFinished() in the main activity, the app crashes.   </p>
  
  <p>THIS INFORMATION IS VERY IMPORTANT: After doing some debug, I realized that after orientation changes, obviously, the Activity onCreate() method is called an then, exactly on the line "super.onCreate(savedInstanceState);" THE CODE FLOW IS DIVERTED and there is a sequence of calls to methods of the Fragment TabFragmentPropositura, the first call is to onDestroyView(), then onDetach(), then it comes back to the line "super.onCreate(savedInstanceState);" of the main activity and then THE CODE FLOW IS DIVERTED TO the method onAttach() of the Fragment TabFragmentPropositura, then to method onCreate() of the same TabFragmentPropositura, then it comes back to executing the rest of the lines in  the method onCreate() of the main activity passing on the lines "loaderManager = getSupportLoaderManager();" and "loaderManager.initLoader(PROPOSITURA_DETAILS_LOADER_ID, null, ProposituraDetailsActivity.this); (when passing through this line after orientation changes, it does not call onLoadFinished which is the responsible for getting the object propositura)", then THE CODE FLOW goes to the method onCreateView() of TabFragmentPropositura and finally it tries to update the user interface for the TabFragmentPropositura with no success because the object propositura is null since it was not obtained from the onLoadFinished. Sorry for this very long description, but I am telling you exactly the whole code flow. </p>
  
  <p>Bellow are the cited parts of my code :<br>
       p.s. -> I have taken off many parts of the code so, only the important parts are listed below.<br>
               I really appreciate your help. Before posting this question I have searched a lot through stackoverflow, but I have not found anything similar to my problem USING LOADER ONLY IN THE MAIN ACTIVITY</p>
  
  <p>This is the main activity which gets the object from the webserver :</p>
  
  <pre><code>package br.gov.sp.camarasorocaba.legislacao;
  
  import android.app.Activity;
  import android.support.v4.app.LoaderManager;
  import android.app.ProgressDialog;
  import android.content.Intent;
  import android.support.v4.content.Loader;
  import android.os.Bundle;
  import android.support.design.widget.TabLayout;
  import android.support.v4.app.FragmentActivity;
  import android.support.v4.view.ViewPager;   
  
  public class ProposituraDetailsActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks&lt;Propositura&gt; {
  
  
  public static final int PROPOSITURA_DETAILS_LOADER_ID = 3;
  
  LoaderManager loaderManager;
  
  ProgressDialog asyncDialog;
  
  Intent intentWithCriterios;
  
  String idTipoPropositura;
  String numeroPropositura;
  
  TabLayout tabLayout;
  
  ViewPager viewPager;
  
  int currentTABPosition = 0;
  
  PagerFragmentAdapter pagerFragmentAdapter;
  
  public Propositura propositura;
  
  
  @Override
  protected void onCreate(Bundle savedInstanceState) {
  
      super.onCreate(savedInstanceState);
  
      setContentView(R.layout.activity_propositura_details);
  
  
      if(savedInstanceState == null)
      {
          pagerFragmentAdapter = new PagerFragmentAdapter(getSupportFragmentManager());
      }
  
  
      intentWithCriterios = getIntent();
  
      idTipoPropositura = intentWithCriterios.getStringExtra("ID_TIPO_PROPOSITURA");
      numeroPropositura = intentWithCriterios.getStringExtra("NUMERO_PROPOSITURA");
  
      //CREATING THE LOADER
      // Get a reference to the LoaderManager, in order to interact with loaders.
      loaderManager = getSupportLoaderManager();
  
      loaderManager.initLoader(PROPOSITURA_DETAILS_LOADER_ID, null, ProposituraDetailsActivity.this);
  
  }
  
  
  private void updateUI()
  {
  
      viewPager = (ViewPager) findViewById(R.id.pager);
      tabLayout = (TabLayout) findViewById(R.id.tab_layout);
  
  
      if(pagerFragmentAdapter.getmFragmentTitles().indexOf("Propositura") == -1)
      {
          pagerFragmentAdapter.addFragment(new TabFragmentPropositura(), "Propositura");
      }
  
      if(propositura.getAlteracoes() != null)
      {
          if(pagerFragmentAdapter.getmFragmentTitles().indexOf("Alterações") == -1)
          {
              pagerFragmentAdapter.addFragment(new TabFragmentAlteracoes(), "Alterações");
          }
      }
  
      if(propositura.getAnexo() != null || propositura.getAnexoConsolidado() != null)
      {
          if(pagerFragmentAdapter.getmFragmentTitles().indexOf("Anexos") == -1)
          {
              pagerFragmentAdapter.addFragment(new TabFragmentAnexos(), "Anexos");
          }
      }
  
      viewPager.setAdapter(pagerFragmentAdapter);
      viewPager.setCurrentItem(currentTABPosition);
  
      tabLayout.setupWithViewPager(viewPager);
  
      viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
      tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
          @Override
          public void onTabSelected(TabLayout.Tab tab) {
              viewPager.setCurrentItem(tab.getPosition());
          }
  
          @Override
          public void onTabUnselected(TabLayout.Tab tab) {
  
          }
  
          @Override
          public void onTabReselected(TabLayout.Tab tab) {
  
          }
      });
  
  }
  
  @Override
  public Loader&lt;Propositura&gt; onCreateLoader(int id, Bundle bundle) {
  
      asyncDialog = new ProgressDialog(ProposituraDetailsActivity.this);
  
      asyncDialog.setMessage(getString(R.string.loading_propositura));
  
      asyncDialog.show();
  
      return new ProposituraDetailsLoader(this, getString(R.string.PROPOSITURA_DETAILS_URL), montaParametrosDePropositura());
  }
  
  @Override
  public void onLoadFinished(Loader&lt;Propositura&gt; loader, Propositura proposituraObtida) {
  
      if (proposituraObtida == null) {
          if(asyncDialog != null) {
              asyncDialog.dismiss();
          }
          ProposituraUtils.messageDialog(ProposituraDetailsActivity.this,getResources().getString(R.string.propositura_not_found_message));
      } else {
              if(asyncDialog != null)
              {
                  asyncDialog.dismiss();
              }
              propositura = proposituraObtida;
              updateUI();
      }
  
  }
  
  @Override
  public void onLoaderReset(Loader&lt;Propositura&gt; loader) {
  
  }
  </code></pre>
  
  <p>This is the layout for the main activity</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt;
  &lt;LinearLayout 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:orientation="vertical"
      tools:context=".ProposituraDetailsActivity"&gt;
  
  
      &lt;RelativeLayout
          android:layout_width="match_parent"
          android:layout_height="32dp"
          android:alpha="@android:integer/config_mediumAnimTime"
          android:paddingEnd="2dp"
          android:paddingLeft="0dp"
          android:paddingRight="0dp"
          android:paddingTop="10dp"&gt;
  
          &lt;ImageView
              android:id="@+id/back_to_listing_image"
              android:layout_width="30dp"
              android:layout_height="30dp"
              android:layout_alignParentLeft="true"
              android:layout_alignParentStart="true"
              android:layout_centerVertical="true"
              android:background="@drawable/ic_previousarrow"
              android:clickable="true" /&gt;
  
          &lt;TextView
              android:id="@+id/back_to_listing_btn"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:layout_centerVertical="true"
              android:layout_toEndOf="@id/back_to_listing_image"
              android:layout_toRightOf="@+id/back_to_listing_image"
              android:clickable="true"
              android:text="@string/back_to_listing"
              android:textAllCaps="true"
              android:textColor="@color/corVisualizacaoTexto" /&gt;
  
      &lt;/RelativeLayout&gt;
  
  
      &lt;android.support.design.widget.TabLayout
          android:id="@+id/tab_layout"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:background="?attr/colorPrimary"
          android:elevation="6dp"
          android:minHeight="?attr/actionBarSize"
          android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"/&gt;
  
      &lt;android.support.v4.view.ViewPager
          android:id="@+id/pager"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:layout_below="@id/tab_layout"/&gt;
  
  
  &lt;/LinearLayout&gt;
  </code></pre>
  
  <p>This is the PagerFragmentAdapter class</p>
  
  <pre><code>package br.gov.sp.camarasorocaba.legislacao;
  
  import android.support.v4.app.Fragment;
  import android.support.v4.app.FragmentManager;
  import android.support.v4.app.FragmentStatePagerAdapter;
  import android.view.ViewGroup;
  
  import java.util.ArrayList;
  import java.util.List;
  
  public class PagerFragmentAdapter extends FragmentStatePagerAdapter {
  
      private final ArrayList&lt;Fragment&gt; mFragments = new ArrayList&lt;&gt;();
  
      private final ArrayList&lt;String&gt; mFragmentTitles = new ArrayList&lt;&gt;();
  
      public PagerFragmentAdapter(FragmentManager fm) {
          super(fm);
      }
  
  
      public void addFragment(Fragment fragment, String title) {
          mFragments.add(fragment);
          mFragmentTitles.add(title);
      }
  
      @Override
      public Fragment getItem(int position) {
  
          return mFragments.get(position);
  
      }
  
      @Override
      public int getCount() {
          //return mNumOfTabs;
          return mFragments.size();
      }
  
      public List&lt;String&gt; getmFragmentTitles()
      {
          return this.mFragmentTitles;
      }
  
      @Override
      public CharSequence getPageTitle(int position) {
          return mFragmentTitles.get(position);
      }
  
      @Override
      public Object instantiateItem(ViewGroup container, int position)
      {
          Object fragmentReturned = super.instantiateItem(container, position);
          mFragments.set(position,(Fragment)fragmentReturned);
          return fragmentReturned;
      }
  
  }
  </code></pre>
  
  <p>This is the first fragment for showing the basic information :</p>
  
  <pre><code>package br.gov.sp.camarasorocaba.legislacao;
  
  import android.content.Context;
  import android.content.Intent;
  import android.content.pm.PackageManager;
  import android.content.pm.ResolveInfo;
  import android.net.Uri;
  import android.os.Bundle;
  import android.support.v4.app.Fragment;
  import android.support.v4.content.ContextCompat;
  import android.view.LayoutInflater;
  import android.view.MotionEvent;
  import android.view.View;
  import android.view.ViewGroup;
  
  
  public class TabFragmentPropositura extends Fragment {
  
      public ProposituraDetailsActivity proposituraDetailsActivity;
  
      private View viewPropositura;
  
  
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  
          proposituraDetailsActivity = (ProposituraDetailsActivity) getActivity();
  
          viewPropositura = inflater.inflate(R.layout.tab_fragment_propositura, container, false);
  
          updateUi(); //only basic operations are executed here
  
          return viewPropositura;
  
      }
  </code></pre>
  
  <p>This is the second fragment for showing the first list of objects contained in the main object. this fragment is only created if the first list of objects exist</p>
  
  <pre><code>package br.gov.sp.camarasorocaba.legislacao;
  
  import android.content.Intent;
  import android.os.Bundle;
  import android.support.v4.app.Fragment;
  import android.view.LayoutInflater;
  import android.view.MotionEvent;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.AdapterView;
  import android.widget.ListView;
  import android.widget.TextView;
  
  
  public class TabFragmentAlteracoes extends Fragment {
  
      public ProposituraDetailsActivity proposituraDetailsActivity;
  
      private View view;
  
      private AlteracaoAdapter alteracaoAdapter;
  
  
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  
          proposituraDetailsActivity = (ProposituraDetailsActivity) getActivity();
  
          view = inflater.inflate(R.layout.tab_fragment_alteracoes, container, false);
  
          updateUi(); //only basic operations are executed here
  
          return view;
  
      }
  </code></pre>
  
  <p>This is the third fragment for showing the second list of objects contained in the main object.  this fragment is only created if the first list of objects exist</p>
  
  <pre><code>package br.gov.sp.camarasorocaba.legislacao;
  
  import android.Manifest;
  import android.app.ProgressDialog;
  import android.content.Context;
  import android.content.DialogInterface;
  import android.content.Intent;
  import android.content.pm.PackageManager;
  import android.net.Uri;
  import android.os.Build;
  import android.os.Bundle;
  import android.os.Environment;
  import android.os.PowerManager;
  import android.support.v4.app.ActivityCompat;
  import android.support.v4.app.Fragment;
  import android.support.v4.content.ContextCompat;
  import android.support.v4.content.FileProvider;
  import android.view.LayoutInflater;
  import android.view.MotionEvent;
  import android.view.View;
  import android.view.ViewGroup;
  
  
  public class TabFragmentAnexos extends Fragment {
  
      public ProposituraDetailsActivity proposituraDetailsActivity;
  
      private View view;  
  
  
      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  
          //obtendo a atividade principal para acesso às variaveis
          proposituraDetailsActivity = (ProposituraDetailsActivity) getActivity();
  
          view = inflater.inflate(R.layout.tab_fragment_anexos, container, false);
  
          updateUi(); //only basic operations are executed here   
  
          return view;
  
      }
  </code></pre>