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.

Mykroft
  • 13,077
  • 13
  • 44
  • 72
Alyoshak
  • 2,696
  • 10
  • 43
  • 70
  • 3
    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? – Karakuri Dec 02 '16 at 03:23
  • @Karakuri, I added the information you requested. I hope it is enough. – Alyoshak Dec 02 '16 at 05:31
  • In the sequence of events you posted, which `Activity` is logging each method? – Bryan Dec 02 '16 at 19:34
  • @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. – Alyoshak Dec 02 '16 at 21:53
  • 1
    If you are planning to call `setResult()`, you must start the activity with `startActivityForResult()`, not `startActivity()`. – natario Dec 05 '16 at 17:54
  • Which is the super class of `ScanningActivity`? – ozbek Dec 06 '16 at 11:05
  • ActionBarActivity is the super class of ScanningActivity. ScanningActivity is launched from GradeActivity code. – Alyoshak Dec 06 '16 at 13:37
  • Can you post the life-cycle callbacks for GradeActivity AND ScanningActivity? Also, where in the GradeActivity is ScanningActivity being opened? – Hahn Dec 06 '16 at 21:17
  • @Hahn -- Hang tight. Got a bug preventing me from reproducing it right now. Stay tuned. I will post both of your requests asap. – Alyoshak Dec 07 '16 at 00:40
  • I think you are starting activity again when after finish ScanningActivity. Need to know from where you are starting ScanningActivity. – Qamar Dec 08 '16 at 12:53
  • No need to add try catch in starting activity with explicit intent. – Qamar Dec 08 '16 at 12:55
  • @Qamar -- 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. – Alyoshak Dec 08 '16 at 17:02
  • @Alyoshak 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. – Abhinav Puri Dec 09 '16 at 07:37
  • @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. – Alyoshak Dec 09 '16 at 16:00
  • 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. – Alyoshak Dec 09 '16 at 23:04
  • Hey, you must be doing something wrong in 'onActivityResult' and you may have accidentally fixed it : ) – AZ_ Dec 12 '16 at 15:40
  • 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. – Alyoshak Dec 12 '16 at 15:52

2 Answers2

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.

Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
Anis BEN NSIR
  • 2,555
  • 20
  • 29
  • 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? – Alyoshak Dec 12 '16 at 18:07
  • 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. – Anis BEN NSIR Dec 12 '16 at 18:26
  • 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. ??? – Alyoshak Dec 12 '16 at 20:12
  • 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? – Anis BEN NSIR Dec 12 '16 at 20:19
  • 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. – Alyoshak Dec 12 '16 at 22:06
  • So remove the setResult (RESULT_CANCELED) from ScanningActivity will solve the issue. – Anis BEN NSIR Dec 12 '16 at 22:09
  • 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? – Alyoshak Dec 12 '16 at 23:34
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;
                }
            }
         }
    . . .
}
kgsharathkumar
  • 1,369
  • 1
  • 19
  • 36