0

I'd like to make an initialization request when my app starts up. I then want to use the response in my MainActivity. I don't want to make that request in the Activity and then deal with the Activity lifecycle when the phone gets rotated.

So I was thinking of deriving from Application and making the request there. But what's the best way to send the response data to the my launcher Activity?

Is there a "best practice" solution here?

user313724
  • 3,425
  • 4
  • 19
  • 15

2 Answers2

2

You could try using a library like Event Bus in order to receive the data inside your activity once your request task is complete. By doing this you wouldn't have to worry about where the call is made from or if your activity is rotated or recreated.

If the data is specificly for your MainActivity I would recommend having the request be triggered from there for the sake of keeping things coupled.

wesjpaul
  • 240
  • 1
  • 9
1

If you're looking for best practices, you shouldn't extend an Application class for this.

There is many ways to persist your request state on screen rotation.

Consider to use a retained Fragment. This approach is deeply discussed:
Understanding Fragment's setRetainInstance(boolean)
Further understanding setRetainInstance(true)

All you need to do is this:

1. Fragment class

public class RequestFragment extends Fragment {

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

        // This will be a guarantee that request is sent only once, 
        // because fragment won't be recreated on screen rotation:
        setRetainInstance(true);

        // Pereform sending request here.
    }

}

2. Activity class

public class MainActivity extends AppCompatActivity {

    private final static TAG_FRAGMENT = "persistent_fragment";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        FragmentManager fm = getSupportFragmentManager();

        // Create fragment if it doesn't exist yet.
        if (fm.findFragmentByTag(TAG_FRAGMENT) == null) {
            fm.beginTransaction()
                    .add(new RequestFragment(), TAG_FRAGMENT)
                    .commit();
        }
    }

}


But if you strongly decided to perform the request in Application onCreate() method, you have to implement an observable object that responds to activity which is subscribed to it, because you can't access an Activity from the Application class.

You can try this:

1. ResponseObservable class

public class ResponseObservale {

    private MainActivity activity;
    private Response response;

    public void sendRequest() {
         // perform your async request here.
    }

    /* 
     * Consider this method as a point where the response is delivered.
     * It can be done in onPostExecute of AsyncTask or somewhere else,
     * depending on your implementation.
     */
    public void onResponse(Response response) {
        this.response = response;
        publishResponse();
    }

    public void onActivityCreated(MainActivity activity) {
        this.activity = activity;
        if (response != null) {
            publishResponse();
        }
    }

    private void publishResponse() {
        if (activity != null) {
            activity.obtainResponse(response);
        }
    }

    public void onActivityDestroy() {
         activity = null;
    }

}

2. Application class

public class MyApplication extends Application {

    private ResponseObservable observable;

    @Override
    public void onCreate() {
        super.onCreate();
        observable = new ResponseObservable();
        observable.sendRequest();
    }

    public ResponseObservable getObservable() {
        return observable;
    }

}

3. Activity class

public class MainActivity extends AppCompatActivity {

    private ResponseObserbale observable;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        MyApplication app = (MyApplication) getApplicationContext();
        observable = app.getObservable();
        observable.onActivityCreated(this);
    }

    public void obtainResponse(Response response) {
        // Manage your response here.
    }

    @Override
    protected void onDestroy() {
        observable.onActivityDestroy();
    }

}


Don't forget to declare your Application class in AndroidManifest.xml:

<application
    android:name="com.yournamespace.appname.MyApplication"
    android:icon="@drawable/icon"
    android:label="@string/app_name">
Community
  • 1
  • 1
konata
  • 168
  • 1
  • 4
  • 10