Trace
Trace

Reputation: 18869

Interrupt super.onCreate() in super class

I have a base Activity in which I want to check authentication for all Activities that require to be logged in, both onCreate and onResume:

For example HomeActivity:

public class HomeActivity extends AccountRequiredActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_home);
    }

}

public class AccountRequiredActivity extends LifecycleActivity {
    private final int INTENT_REQUEST_CODE = 1;

    @Inject
    ViewModelProvider.Factory viewModelFactory;

    private AccountViewModel accountViewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        AndroidInjection.inject(this);
        accountViewModel = ViewModelProviders.of(this, viewModelFactory).get(AccountViewModel.class);
        checkAuthentication();
    }

    @Override
    protected void onResume() {
        super.onResume();
        checkAuthentication();
    }

    private void checkAuthentication() {
        // Check if authenticated synchronously
        if(!accountViewModel.isAuthenticated()) {
            getLogin();
        };
    }

    private void getLogin() {
        Intent intent = new Intent(this, LoginActivity.class);
        startActivityForResult(intent, INTENT_REQUEST_CODE);
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == INTENT_REQUEST_CODE) {
            if (resultCode == Activity.RESULT_OK) {
                // The login is ok, continue
            } else {
                getLogin();
            }
        }

    }
}

LoginActivity is a separate activity that manages the login flow (connection to FB server and my own).

There are 2 problems with this code.
The first problem is that when isAuthenticated is false, I don't want the method to return to the calling child Activity (in this case, HomeActivity) because setContentView of Home should not be set.
The second problem is that onActivityResultis called asynchronously (as is the login flow in LoginActivity as a matter of fact.

How do I fix this code so that I'm able to make the auth check in the base class, while only continuing to call setContentView when the authentication succeeds?

Upvotes: 2

Views: 293

Answers (1)

David Wasser
David Wasser

Reputation: 95588

In the base Activity do something like this:

@Override
protected final void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Do your authentication stuff here
    if (auth is successfull) {
        // Call derived Activity's "doOnCreate()" to set content view, etc.
        doOnCreate(savedInstanceState);
    } else {
        // Here you can do whatever you need to do in case the auth fails
    }
}

Declaring the method final prevents derived activities from overriding it.

Also create an abstract method doOnCreate() in the base Activity that each derived Activity needs to override.

Each derived Activity should NOT override onCreate(), but implement doOnCreate() and implement all of its initialization there.

Upvotes: 1

Related Questions