Search code examples
androidtwitter4jandroid-lifecycleactivity-lifecycledata-persistence

Android data is lost onCreate() after startActivity() for callback


I have an android app which connects to twitter via twitter4j. In an activity there is a share button and a TextView. The flow is like below;

  1. User opens the activity starting onCreate() which populates the TextView
  2. User clicks "Share"
  3. Twitter activity is started for oAuth, user types account credentials and gives permission to my app
  4. User gets redirected to the activity again starting onCreate()

My problem is that the value of the TextView get lost after second onCreate().

- onCreate()
.
.
point = getIntent().getExtras().getInt("point");
.
.

- shareButton.onClick()
.
.              
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse(requestToken.getAuthenticationURL()));// open twitter for authentication

intent .putExtra("point", point);
startActivityForResult(intent , 1);
}
});
thread.start();
.
.

Things i have tried so far;

  • using startActivityForResult() instead of startActivity()
  • using intent.putExtra() before startActivity() and calling getIntent().getExtras().getInt("point") in onCreate() but there is no such data
  • using onSaveInstanceState() and onRestoreInstanceState() but savedInstanceState is null

Please tell me how i can persist this data after twitter callback. I can use database or shared preferences or something like that but is there another way?

Thanks in advance.

EDIT:

When the program goes to twitter and come back, it starts again from onCreate() just like when the orientation changes. When the orientation changes "Bundle savedInstanceState" has value but in my case has no value.

How can i get savedInstanceState -which i set before manually- in the second run of onCreate() after return of the twitter callback?

EDIT 2:

Some people in this site is really weird. I posted the answer below as a new post but someone deleted it claiming "the new post should include the answer". You know what, that post has the real answer. Don't act like this without reading all of it. I'm writing that below as an edit.

Thank you very much for your answer (@rod_torres). I have tried your solution (with and without i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)) and in both cases i couldn't achieve. The life cycle when i set singleTop was like below;

onCreate() -> Twitter -> onCreate()

onNewIntent() wasn't called after come back from Twitter. The activity was recreated as a new instance so I can go back with back button in the order above.

I tried with singleTask and it worked (The answer of my question is this, for someone who deleted my post without reading this part). it didn't create a new instance of the activity and onNewIntent() was called . When I click back button, I got redirected the previous activity of my app, not the task of the Browser (Twitter) although Twitter was the previous activity. The flow was like;

onCreate() -> Twitter -> onCreate(with bundles) -> onNewIntent()

Activity A -> Activity B -> Twitter -> Activity B (same with previous)

when I go back from Activity B;

Activity A -> Browser

It seems singleTask mode brought my app's task to the foreground with all activities in it and brought the other app's (Browser) task to back stack. Am I right?

But still I couldn't understand why your solution didn't worked for me. I have read a lot of documentation about this and I think it should have been worked.

Also, I'm not sure if I should use singleTask. Could be there something wrong I haven't take into account yet, any disadvantages?


Solution

  • As you point out in the edit the Activity is recreated. To make the app not recreate the Activity add in the Manifest the parameter launchMode with the value "singleTop" to the Activity from where you will be using twitter4j

    <activity
            android:name=".SecondActivity"
            android:label="@string/title_activity_second"
            android:launchMode="singleTop">
    

    Also, when you call that activity add the flag FLAG_ACTIVITY_CLEAR_TOP:

    Intent i = new Intent(this, SecondActivity.class);
    i.putExtra("string","Second Activity Biches");
    i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(i); 
    

    For more information:

    http://www.intridea.com/blog/2011/6/16/android-understanding-activity-launchmode https://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TOP