Why is a call to finish() causing onCreate() to be called, starting a new Activity?
Asked Answered
D

2

14

(Yes, I've already looked at existing questions related to this problem.)

I am calling finish() from my Activity's Up button listener. But although onDestroy() does get around to being called, first onPause() is called and then, surprisingly, onCreate(), which is causing real problems. Why is a new ScanningActivity being launched by a call to the finish() method of ScanningActivity?

I am logging invocations of all the life cycle functions and the order is this:

 inside onClick() Listener for up button.
         Inside onPause()
         Inside onCreate()  // this is what's hosing everything
         Inside onStart()
         Inside onResume()
         Inside onWindowFocusChanged()
         Inside onStop()
         Inside onDestroy()

Why am I getting this sequence of events following a call to finish()? Here's the ScanningActivity code that calls finish(), notice, in an onclick listener (which is assigned within the onCreate() method):

@Override
public void onCreate(Bundle savedInstanceState)
{
    . . .

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) 
        {
            Log.i("ScanningActivity", "inside onClick() -- Listener for up button being executed.");

            android.widget.LinearLayout layt = (android.widget.LinearLayout) vCustView;

            View vTemp = layt.findViewById(R.id.scanning_up);
            if (null != vTemp)
            {
                Button btnUp = (Button) vTemp;
                if (!btnUp.getText().equals("End"))  
                {
                    setResult(RESULT_CANCELED);

                    finish();
                    return;
                }
            }
         }
    . . .
}

As per Karakuri's request here is the manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.calypso.myandroid">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    //
    <uses-permission android:name="android.permission.SET_DEBUG_APP" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

        <uses-feature android:name="android.hardware.camera" />
        <uses-feature android:name="android.hardware.camera.autofocus" />

        <uses-permission android:name="android.permission.CAMERA" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ail_logo"
        android:label="@string/app_name"
        android:theme="@style/AssistTheme">
        <activity
            android:name=".HomeScreenActivity"
            android:label="@string/title_activity_home_screen"
            android:screenOrientation="portrait">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".GradeActivity"
            android:label="@string/title_activity_grade_assessment"
            android:screenOrientation="portrait"
            android:parentActivityName=".HomeScreenActivity"
            android:noHistory="true"
            />
        <activity
            android:name=".ScanningActivity"
            android:label="@string/title_activity_scanning"
            android:screenOrientation="portrait"
            android:parentActivityName=".GradeActivity"
            />
    </application>


</manifest>

... and here is the calling code, which initially launches ScanningActivity from inside the GradeActivity:

if (bFinishedSuccessfully)
{
    try
    {
        Log.i("GradeActivity", "SOMEHOW THIS IS AGAIN STARTING THE ScanningActivity!!!");

        Intent intent = new Intent(this, ScanningActivity.class);
        intent.putExtra("SessionInfo", m_hmActivate);
        startActivity(intent);
    }
    catch (Exception ex)
    {
        Log.i("GradeActivity", "ex: " + ex.getMessage());
    }
}

UPDATE: I modified the manifest a bit and the calling code, slightly, in an attempt to fix this, but to no avail. The behavior is still exactly as described originally. I've updated the question with the mods.

Dukey answered 2/12, 2016 at 2:57 Comment(17)
The code you've posted doesn't provide enough information. Can you show us your AndroidManifest? Also, it looks like this activity is started for a result. Perhaps you should include some code form the calling activity as well?Sulfanilamide
@Karakuri, I added the information you requested. I hope it is enough.Dukey
In the sequence of events you posted, which Activity is logging each method?Cypro
@Bryian -- ScanningActivity. The one in whose code I call finish() and the one that is almost immediately relaunched by it. I tried to edit question to make that clearer. Make suggestions if you want for sake of the community.Dukey
If you are planning to call setResult(), you must start the activity with startActivityForResult(), not startActivity().Husted
Which is the super class of ScanningActivity?Bales
ActionBarActivity is the super class of ScanningActivity. ScanningActivity is launched from GradeActivity code.Dukey
Can you post the life-cycle callbacks for GradeActivity AND ScanningActivity? Also, where in the GradeActivity is ScanningActivity being opened?Lots
@Lots -- Hang tight. Got a bug preventing me from reproducing it right now. Stay tuned. I will post both of your requests asap.Dukey
I think you are starting activity again when after finish ScanningActivity. Need to know from where you are starting ScanningActivity.Baer
No need to add try catch in starting activity with explicit intent.Baer
@Baer -- maybe I am, but it wasn't from the only explicit call to start the ScanningActivity. I put a log statement right before the only place that that happens and it was not getting called. I'm almost to where I can try to reproduce this again.Dukey
@Dukey Were you able to reproduce this ? If so, post complete code every line even import statements, so that I can reproduce in my app too and help you. Also, if you are using Android studio just right click on your java file or xml file and click on History, and you will get back the older code which produced this error.Bandeen
@Abhinav -- Thank you. I am almost able to attempt reproducing this, and will definitely update here with results. I will address this soon bc I want to reward the bonus before the time expires.Dukey
Bad news. By the time I finished adding the fix I can no longer produce the error. I got some initial attention, but even though I met their requests they fell silent. Then I had to extensively rework some code from a team member in GradeActivity. Now, I no longer get the error, even though I could repeat it every single time. A real bummer.Dukey
Hey, you must be doing something wrong in 'onActivityResult' and you may have accidentally fixed it : )Upanishad
Something was causing a re-launch of ScanningActivity when I dismissed the activity with finish(). If I get time I can perhaps reproduce it by pulling old code from repository, but have to move project forward. Again, a bummer bc I think this issue could be a help to the community over time.Dukey
C
1

I think that the problem is on your manifest,the android:noHistory="true" parameters added to GradeActivity. The setResult() on ScanningActivity will try to create the parent Activity GradeActivity. I think that if you don't need to keep GradeActivity on your navigation stack, you have to start the ScanningActivity from your HomeScreenActivity using startActivityForResult.

Condolence answered 12/12, 2016 at 11:4 Comment(7)
Really? Well, I cannot start ScanningActivity directly from HomeScreenActivity bc a critical needed step is accomplished in GradeActivity along the way to ScanningActivity. But if a failure occurs along the way, the user must go all the way back to HomeScreenActivity. Is there reason to believe using noHistory causes my kind of problem?Dukey
Well, witch activity is handling the result back from ScanningActivity? GrateActivity is destroyed when ScanningActivity is resumed, so, when you call setResult, the android activity manager will try to post back to the calling activity so it create a new instance of GrateActivity. The solution is to start from HomeScreenActivity using a custum result from GrateActivity or to remove the noHistory parameter from GradeActivity and finish it when needed.Condolence
I'm not sure how it is figuring out how to go back to HomeScreenActivity but it is, which is what I need to happen. Perhaps because it cannot find an instance of GradeActivity it looks further back and finds the activity that called GradeActivity (HomeScreenActivity) and returns to there. ???Dukey
well, if i understand le navigation of your application(HomeSreenActivity--> GradeActivity --> ScanningActivity --> back to HomeScreenActivity), do you need a result from ScanningActivity? if so, where you are handling it? have you tested the result back from ScanningActivity?Condolence
No sir, no result needed. When ScanningActivity ends I want it to go back to the HomeScreenActivity period. HomeScreenActivity does not look for a result.Dukey
So remove the setResult (RESULT_CANCELED) from ScanningActivity will solve the issue.Condolence
I think you're probably right, and that was my original mistake. Can you say anything about why unnecessarily calling setResult() can cause the activity to re-launch?Dukey
I
1

Use setResult(RESULT_OK); instead of setResult(RESULT_CANCELED); inside of the Click listener.

Like:

@Override
public void onCreate(Bundle savedInstanceState)
{
    . . .

    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) 
        {
            Log.i("ScanningActivity", "inside onClick() -- Listener for up button being executed.");

            android.widget.LinearLayout layt = (android.widget.LinearLayout) vCustView;

            View vTemp = layt.findViewById(R.id.scanning_up);
            if (null != vTemp)
            {
                Button btnUp = (Button) vTemp;
                if (!btnUp.getText().equals("End"))  
                {
                    setResult(RESULT_OK);

                    finish();
                    return;
                }
            }
         }
    . . .
}
Isiah answered 12/12, 2016 at 11:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.