30

My launcher icon currently starts the login activity. I've stored the logged in status in SharedPreferences. Is there any way to properly skip the login activity and go straight to the main activity without any UI glitches. All existing solutions involving finish() in onCreate() cause the login activity title to be briefly visible or some other brief blank screen UI glitch.

Monstieur
  • 7,746
  • 9
  • 43
  • 72

6 Answers6

46

Have a launcher acitivy with no UI that decides to open the MainActivity or the LoginActivity. You can declare no UI with:

android:theme="@android:style/Theme.NoDisplay"

Two other possible solutions:

Just do it the other way around: make your mainActivity your launcher and make it check whether the user is logged in. Then redirect to the loginActivity when this is not the case.

Another way is to work with fragments. Have a base activity that can load both the mainFragment and the loginFragment. For reference: https://developer.android.com/training/basics/fragments/index.html

wvdz
  • 15,266
  • 3
  • 43
  • 82
  • 1
    Then the login activity glitches the first time the app loads. I want a perfect UI. – Monstieur Jun 03 '14 at 07:54
  • In that case you may want to consider using fragments. – wvdz Jun 03 '14 at 08:04
  • My main activity is already a fragment container with a complex layout for portrait, landscape, tablets etc. I won't complicate it further just to do something as trivial as directly launching it. I can't believe there is no solution to this. – Monstieur Jun 03 '14 at 08:46
  • Added a third possible solution. – wvdz Jun 03 '14 at 09:08
  • 4
    Theme.NoDisplay does exactly what I want. There is absolutely no glitch when launching the first activity. If I don't start another Activity, the launcher doesn't flicker even for an instant as if the icon does absolutely nothing! – Monstieur Jun 04 '14 at 12:16
  • Great! I moved the third solution to the top. – wvdz Jun 04 '14 at 12:37
  • @Locutus Can you please provide the code stub for how you checked whether the user is logged in and move directly to the mainactivity; I am also facing similar ui glitches. Right now, my login activity is the default launch activity. Would appreciate if you please post some code. Thanks! – Ali_Waris Apr 13 '16 at 05:58
  • @Ali_Waris I created a separate launcher activity with `Theme.NoDisplay` and just called `startActivity` for the login / main activity depending on the logged in state. – Monstieur Apr 13 '16 at 09:24
  • @Locutus But my login logic is present in one of the fragment. So even if I make the launch activity to no ui splash and then navigate to main activity, but how will the login code execute now? As the fragment logic for login will not be executed. – Ali_Waris Apr 13 '16 at 09:38
  • I store the logged in state in shared preferences so that it can be read from the simple launcher activity. – Monstieur Apr 13 '16 at 14:07
  • 2
    If I use Theme.NoDisplay, I am getting this exception and my app is crashing: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity. – Ali_Waris Apr 15 '16 at 02:35
  • @Ali_Waris You need to use Activity instead of AppCompatActivity. – ken Feb 07 '17 at 05:05
3

You can create a Base Activity that will check if the user's username and password is already in the SharedPreferences and starts the activity if it exist hence not.

example:

public class BeanStalkBaseActivity extends SherlockActivity{

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);


    if(SavedPreference.getUserName(this).length() == 0)
    {
        Intent intent = new Intent(this,LoginActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        finish();
        startActivity(intent);
    }else
    {
        Intent intent = new Intent(this,MainActivity.class);
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        finish();
        startActivity(intent);
    }

}

}

BeanStalkBaseActivity should be your Launcher as it only serve as a checker.

Rod_Algonquin
  • 25,268
  • 6
  • 47
  • 61
  • Doesn't work. Read the question. I don't want the initial activity's title visible even for a millisecond. This causes a blank screen for a brief time before loading the second activity. – Monstieur Jun 03 '14 at 07:51
  • @Locutus remove the Thread.sleep(500); that is the cause as I commented it as Dont mind – Rod_Algonquin Jun 03 '14 at 07:56
  • No it's not. The activity still shows briefly as it's rendered on the screen. – Monstieur Jun 03 '14 at 08:43
  • 1
    remove setContentView(R.layout.activity_main); but the best approach is to have MainActivity and LoginActivity, the laucher activity should be MainAcitivty, before setContentView in MainAcitivity check if need to login ... – AndroidCoolestRulest Feb 09 '16 at 17:59
1

You can also check for login status during your splash screen activity if you have one. Splash screens are great for letting users know the app hasn't stalled when it's loading and can also be used to redirect the app to the appropriate screen.

I followed this great guide my first time making one: https://www.bignerdranch.com/blog/splash-screens-the-right-way/

Ben
  • 641
  • 1
  • 7
  • 15
1

If you check whether the user is already logged in or not inside the main activity or the current activity and then switch to another activity if logged in, this will lead to UI glitches, i.e. your current activity will show up for a second or half and then it will switch to the target activity.

You can do this like :

  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mAuth = FirebaseAuth.getInstance();
    if (mAuth.getCurrentUser() != null) {

        Toast.makeText(MainActivity.this, "Already Logged In", 
        Toast.LENGTH_LONG).show();
        Intent intent = new Intent(MainActivity.this, Home.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(intent);

    } else {
        getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
        WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.activity_main);

        BtnSignUp = findViewById(R.id.btnSignUp);
        BtnLogIn = findViewById(R.id.btnLogIn);


        BtnSignUp.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Intent signUp = new Intent(MainActivity.this, SignUpActivity.class);
                startActivity(signUp);

            }
        });

        BtnLogIn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Intent logIn = new Intent(MainActivity.this, Login.class);
                startActivity(logIn);
            }
        });
    }
}
Bhawna
  • 26
  • 3
0

In main activity just check if user is not null then fire up home

firebaseAuth = FirebaseAuth.getInstance();

FirebaseUser user = firebaseAuth.getCurrentUser();

if (user != null) {
    finish();
    startActivity(new Intent(MainActivity.this, UserHomeActivity.class));
}
Paul Chu
  • 1,209
  • 3
  • 16
  • 23
0

If there is someone looking for what to use instead of

android:theme="@android:style/Theme.NoDisplay"

use

android:theme="@style/TextAppearance.AppCompat.Display4"

do not forget to add finish() to your activity before startActivity(intent)

ZootHii
  • 31
  • 6