DJ-ST
DJ-ST

Reputation: 129

AWS SDK References containing context - Android

I am using the AWS SDK for android in my android app, using DynamoDB, Cognito etc.

Currently I am using a single MainActivity class with many fragments, many of which are full screen. My MainActivity contains an AWSHelper class I made which contains all the references I need to communicate with DynamoDB, sign in with Cognito etc. The AWSHelper class also has a reference to the MainActivity that owns it, for changing fragments and Dialogs and anything that requires context. I was previously keeping a static reference to my AWSHelper class but I feel it just isn't the best or only way to use this AWSHelper class.

Please note: Most of the following objects were created with a reference to the context of MainActivity.

Here is an example of some references

private DynamoDBMapper dynamoDBMapper;
private AmazonDynamoDBClient ddbClient;
private CognitoUserPool userPool;
private CognitoUser cognitoUser;

//Created with a reference to context
userPool = new CognitoUserPool(mainActivity.getBaseContext(), POOL_ID, CLIENT_ID, CLIENT_SECRET, new ClientConfiguration());

I would like to use other activities, or make some of my current fragments into activities, but I haven't done so, because I don't know the best approach to maintain the references I currently have with DynamoDB and Cognito without recreating them or placing them as a static reference, but that is not attractive as these fields contain Context references, which is bad practice. The biggest reason though, it seems like a recipe for disaster to have a CognitoUserPool or other important reference that was created with MainActivity context, to be used when there is a new Activity in the foreground and the MainActivity context is no longer the one that should be used.

In my MainActivity class I have a reference AWSHelper awsHelper; to access and execute just about all my AWS related functions. In all my fragments that need to access AWS, in theonCreate(), I have

main = (MainActivity) getActivity; awsHelper = mainActivity.awsHelper

Here is a scenario, I am trying to open a user profile with the data stored in DynamoDB, I would typically call awsHelper.openProfile(user); The method openProfile() launches an AsyncTask that loads the profile, then changes the fragment to a ProfileFragment with all the data.

Remember my AWSHelper class is not a fragment and the methods inside it are necessary just about everywhere in the app.

Could anyone with experience with the AWS SDK for android elaborate on how they have done so?

Some sample apps such as the one from https://github.com/awslabs/aws-sdk-android-samples/tree/master/AmazonCognitoYourUserPoolsDemo/app/src/main/java/com/amazonaws/youruserpools seem to use the approach I was using previously - using a static reference. However this is a small sample app with 1 activity and much more simple.

My only other idea is to keep all the AWS references previously mentioned as a static reference, but recreate the AWSHelper with a new reference to the current context everytime I switch activities, this however still leaves me with the problem of the older MainActivity context still being referenced in CognitoUserPool etc.

Thanks for all the help in advance!

Upvotes: 0

Views: 111

Answers (1)

OneCricketeer
OneCricketeer

Reputation: 192043

The AWSHelper class also has a reference to the MainActivity that owns it

There's your mistake : binding that helper to one single Activity, when you really only need a Context and a FragmentManager.

Therefore, I'd suggest you create an Application class, add it to your manifest, and relocate your AWS classes there.

public class MyApplication extends Application {

    private AwsHelper aws;
    // etc

    public void onCreate(...) {
        userPool = new CognitoUserPool(this, POOL_ID, CLIENT_ID, CLIENT_SECRET, new ClientConfiguration());
    } 

Note that, like Activities, Application classes also extend Context, and you can use getApplicationContext(), or make your Application class hold the static references.

Worth pointing out, you should not store your APP_ID and SECRET_KEY in plaintext within your application, but that's a separate discussion

Upvotes: 2

Related Questions