-4

I have empty Splash activity serving as entry point to the Android application and invoking appropriate activities if Branch data is received.

In case of Branch callback error or missing or unrecognized data it invokes default Main activity.

It all works well if device has Internet connectivity, but in case of failure onInitFinished callback is called twice in a row (once with empty data set and once triggering error), invoking Main activity twice.

public class SplashActivity extends AppCompatActivity
{
    Branch.BranchReferralInitListener branchCallback;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash_activity);
        Log.d("XAPP", "Splash");

        branchCallback = new Branch.BranchReferralInitListener()
        {
            @Override
            public void onInitFinished(JSONObject referringParams, BranchError error)
            {
                Log.d("XAPP", "Branch init session");
                if (error == null)
                {
                    Log.d("XAPP", referringParams.toString());
                    // run different activities depending on the parameters
                    ....
                    else
                    {
                        // fallback to Main activity
                        Intent intent = new Intent(SplashActivity.this, MainActivity.class);
                        startActivity(intent);
                    } 
                }
                else
                {
                    Log.i("XAPP", error.getMessage());
                    Intent intent = new Intent(SplashActivity.this, MainActivity.class);
                    startActivity(intent);
                }
                finish();
            }
        };
    }

    @Override
    protected void onStart()
    {
        super.onStart();
        Log.d("XAPP", "onStart");
        Branch branch = Branch.getInstance();
        branch.initSession(branchCallback);
    }
}

Resulting logcat when application runs without being connected to the Internet (after it has been previously - at some point - opened through Branch deep link and Branch data has been initialized):

D/XAPP: Splash
D/XAPP: onStart
D/XAPP: Branch init session
D/XAPP: {"+is_first_session":false,"+clicked_branch_link":false}
D/XAPP: Branch init session
I/XAPP: Trouble initializing Branch.  Branch API Error: poor network connectivity. Please try again later.

Splash activity is declared as singleTask activity and is started only once.

Relevant parts of AndroidManifest:

<uses-permission android:name="android.permission.INTERNET"/>
...
    <activity
        android:name=".SplashActivity"
        android:launchMode="singleTask"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.FullScreen">

        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>

        <!-- Branch URI Scheme -->
        <intent-filter>
            <data android:host="open" android:scheme="xxxx"/>

            <action android:name="android.intent.action.VIEW"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <category android:name="android.intent.category.BROWSABLE"/>
        </intent-filter>
    </activity>

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.FullScreen">
    </activity>

Relevant parts of the Gradle:

android {
    compileSdkVersion 26
    buildToolsVersion '27.0.3'
    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 26
    ...

dependencies {
    compile('io.branch.sdk.android:library:2.14.4') {
        exclude module: 'answers-shim'
    }

I could solve the issue by making Main activity singleTask or removing the Splash activity altogether - by moving branching into Main activity, but those solutions are not viable options in this particular case.

One of the possible solutions would also be adding some boolean flag to recognize onInitFinished has already been called, but I would like to avoid that one if possible.

My main concern in this situation and actual question is not how to hack the thing to make it work, but why is onInitFinished called twice and is there a flaw in my Branch callback implementation?

Dalija Prasnikar
  • 27,212
  • 44
  • 82
  • 159

2 Answers2

1

I tested with your SplashActivity in a sample app and the callback was fired only once.

Here is my repo.

Please test with this app to check if you can replicate the behavior

In order to compile the app: 1. Add the URI scheme from your Branch dashboard to the Android Manifest 2. Add the Branch key for your app to the Manifest 3. Add your link domain to the app link filter in the Manifest.

Also, I would suggest upgrading the Branch SDK to the latest version i.e. 2.14.4.

If you have a slightly varied implementation, could you either share your Manifest file here. If not, you could also write into integrations@branch.io where the team could help you efficiently.

Amruta Deshmukh
  • 985
  • 5
  • 10
  • I am using the latest library 2.14.4. The possible difference is that my application has already been opened through deep link, and when there is no Internet connectivity, opening application triggers onInitFinished event twice. If application is freshly installed, then behavior is different and it triggers onInitFinished only with error. However subsequent opening of the application does not trigger anything and application gets stuck in the Splash screen. – Dalija Prasnikar Jan 10 '18 at 09:34
  • I can reproduce the same issue with your project. I had to add INTERNET permission and singleTask to SplashActivity. But those were the only changes (besides adding my schemes and branch key). However, while I was testing and comparing the projects, suddenly everything started to work fine in both projects - triggering only error path without Internet connection. Few hours later, same code started to trigger onInitFinished event twice in both projects. Something else is going on here. – Dalija Prasnikar Jan 10 '18 at 13:45
  • Interesting, so now the issue is no longer reproducible? – Amruta Deshmukh Jan 10 '18 at 16:06
  • Let me try your use case (i.e. opening the app via deeplink once and then opening it without any internet). – Amruta Deshmukh Jan 10 '18 at 16:09
  • @DalijaPrasnikar I made the changes and ran your use case again. I was still unable to reproduce. Could you confirm if the issue is resolved or are you still facing it. – Amruta Deshmukh Jan 10 '18 at 18:29
  • It is probably some weird combination that triggers the behavior and then it can be reproduced every time until some other weird behavior stops it. When that happens both applications, yours and mine exhibit same behavior (they have same key and package name so they replace each other on the device). – Dalija Prasnikar Jan 10 '18 at 19:11
  • Issue is not solved, but I will have to dig deeper to find the exact circumstances that triggers it - if I can. – Dalija Prasnikar Jan 10 '18 at 19:13
  • @DalijaPrasnikar let me know if you figure out the exact steps to reproduce. – Amruta Deshmukh Jan 10 '18 at 20:54
-1

Single Task launch mode is required!

The reason for this is because if there is no singleTask Activity instance in the system yet, a new one would be created and simply placed on top of the stack in the same Task. If you are using the Single Task mode as is, it should not restart your entire app. The Single Task mode instantiates the Main/Splash Activity only if it does not exist in the Activity Stack. If the Activity exists in the background, every subsequent intent to the Activity just brings it to the foreground.

  • This is not the answer to the question. I know how singleTask works. I just cannot use it in this case for Main activity. Splash activity is singleTask activity and if you look at the logs it is called only once. Point of the questions is why is the callback event called twice that eventually results in Main activity also being called twice – Dalija Prasnikar Jan 09 '18 at 10:38