Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Fragment onStop() being called directly after onStart() - WHY?

I'm having a strange problem with my app -

A have a Fragment Activity which contains a fragment - This fragment starts an AsyncTask onCreate() and cancels the AsyncTask onStop(). My problem arises because, although my Fragment stays running & isn't obscured it's onStop() is called almost directly after it's onCreate().

Does anyone know how to trace why this would be happening?

09-28 11:41:56.785: VERBOSE/SearchFragment1(924): onCreate()
09-28 11:41:56.796: VERBOSE/SearchFragment1(924): onStop()

EDIT

I've removed the code from the Fragment and I'm still absolutely baffled - The problem persists! I've added a few more lines of logging:

09-28 14:09:00.242: VERBOSE/SearchResultsFragment1(1789): onAttach()
09-28 14:09:00.242: VERBOSE/SearchResultsFragment1(1789): onCreate()
09-28 14:09:00.242: VERBOSE/SearchResultsFragment1(1789): onCreateView()
09-28 14:09:00.242: VERBOSE/SearchResultsFragment1(1789): onActivityCreated()
09-28 14:09:00.242: VERBOSE/SearchResultsFragment1(1789): onStart()
09-28 14:09:00.246: VERBOSE/SearchResultsFragment1(1789): onStop()
09-28 14:09:00.246: VERBOSE/SearchResultsFragment1(1789): onStart()
09-28 14:09:00.246: VERBOSE/SearchResultsFragment1(1789): onResume()

The above behaviour is... baffling. The code used in the Activity looks like this:

if(savedInstanceState == null) 
{
    try {
        FragmentTransaction transaction= getSupportFragmentManager().beginTransaction();    
        Fragment currentFragment= (Fragment)Class.forName(getIntent().getAction()).newInstance();
        transaction.replace(R.id.singlePane, currentFragment);  
        transaction.commit();
    } catch ...

This is the Fragment as it stands during debug:

private static final boolean LOGGING_ENABLED = true;
private static int global_creation_count = 0;
private int local_count = global_creation_count;

@Override
public void onAttach(Activity activity) {   
    super.onAttach(activity);
    if(LOGGING_ENABLED) Log.v(this.getClass().getSimpleName() + local_count, "onAttach()");
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    global_creation_count+=1;       
    if(LOGGING_ENABLED) Log.v(this.getClass().getSimpleName() + local_count, "onCreate()");
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    if(LOGGING_ENABLED) Log.v(this.getClass().getSimpleName() + local_count, "onCreateView()");
    return super.onCreateView(inflater, container, savedInstanceState);     
}

@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    if(LOGGING_ENABLED) Log.v(this.getClass().getSimpleName() + local_count, 
    "onActivityCreated()");
}

@Override
public void onStart() {
    super.onStart();
    if(LOGGING_ENABLED) Log.v(this.getClass().getSimpleName() + local_count, "onStart()");
}       

@Override
public void onResume() {
    super.onResume();
    if(LOGGING_ENABLED) Log.v(this.getClass().getSimpleName() + local_count, "onResume()");
}

// Fragment is active

@Override
public void onPause() {
    super.onPause();
    if(LOGGING_ENABLED) Log.v(this.getClass().getSimpleName() + local_count, "onPause()");
}   

@Override
public void onStop() {
    super.onStop();
    if(LOGGING_ENABLED) Log.v(this.getClass().getSimpleName() + local_count, "onStop()");
}   

@Override
public void onDestroyView() {
    super.onDestroyView();
    if(LOGGING_ENABLED) Log.v(this.getClass().getSimpleName() + local_count, "onDestroyView()");
}

@Override
public void onDestroy() {   
    super.onDestroy();
    if(LOGGING_ENABLED) Log.v(this.getClass().getSimpleName() + local_count, "onDestroy()");
}

@Override
public void onDetach() {    
    super.onDetach();
    if(LOGGING_ENABLED) Log.v(this.getClass().getSimpleName() + local_count, "onDetach()");
}   

EDIT2

From the code it seems that the onStop() is being called directly after onStart(). I've tried to see if it's being called at the same time as onStart() by adding a Thread.sleep(1000) in onCreateView(). The output is the same - which makes me beleive the onStop() is being called/caused directly from Fragment creation process.

EDIT3

Stacktrace when breaking on onStop(): enter image description here

I'm going to try and attach the source code and step through to discover where the problem is.

like image 447
Graeme Avatar asked Sep 28 '11 10:09

Graeme


1 Answers

Still don't know what it was trying to do... I researched on where to get the source code for the class's involved in called onStop() and found that the source for android-support-v4.jar comes packaged along with the jar in the SDK.

After attaching this source though I soon found it was out of sync and that my android-support-v4.jar was vastly different to the one shipped with the current version of the SDK.

Replacing the jar with the one packaged with the SDK fixes the problem instantly and no onStop() is called after onStart(). Not sure what bug was causing this but the latest version seems to fix it quite handily.

like image 175
Graeme Avatar answered Oct 26 '22 07:10

Graeme