Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Re-initializing Twitter Fabric after long idle time android app

So my Android app has the following components: a LoginActivity, a MainActivity which uses a Navigation Drawer, a bunch of various fragments which are handled by the Nav Drawer in Main Activity.

In the LoginActivity, I set up TwitterAuthConfig and also feed that into Fabric.with(....Twitter(authConfig)...), basically doing what they say to do in the documentation: Fabric integration documentation

After the user navigates through LoginActivity and successfully logins in, it goes to Main Activity which opens up the Navigation Drawer and lets them select which Fragment they want to go to. The LoginActivity calls this.finish() after starting the MainActivity.

My problem is that one of the Fragments I have uses an Embedded Twitter Timeline which needs Fabric authentication via the Fabric.with() call. This works fine the first time, but once I leave the app and it stays in the background for a while, I believe onDestroy() is called and then the Fabric instance is removed.

Therefore, when I open it back up again from the background, it has the following error:

07-09 15:59:55.179    7933-7933/com.writers.myapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.writers.myapp, PID: 7933
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.writers.myapp/com.writers.myapp.MainActivity}: java.lang.IllegalStateException: Must Initialize Fabric before using singleton()
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2329)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)
        at android.app.ActivityThread.access$900(ActivityThread.java:147)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
 Caused by: java.lang.IllegalStateException: Must Initialize Fabric before using singleton()
        at io.fabric.sdk.android.Fabric.singleton(Fabric.java:265)
        at io.fabric.sdk.android.Fabric.getKit(Fabric.java:516)
        at com.twitter.sdk.android.tweetui.TweetUi.checkInitialized(TweetUi.java:120)
        at com.twitter.sdk.android.tweetui.TweetUi.getInstance(TweetUi.java:69)
        at com.twitter.sdk.android.tweetui.TwitterListTimeline$Builder.<init>(TwitterListTimeline.java:108)
        at com.myapp.newstimeline.TimelineFragment.onCreateView(TimelineFragment.java:49)
        at android.support.v4.app.Fragment.performCreateView(Fragment.java:1789)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:955)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1138)
        at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1120)
        at android.support.v4.app.FragmentManagerImpl.dispatchActivityCreated(FragmentManager.java:1929)
        at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:547)
        at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1220)
        at android.app.Activity.performStart(Activity.java:5949)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2292)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2389)
        at android.app.ActivityThread.access$900(ActivityThread.java:147)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1296)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5254)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
07-09 15:59:55.203     775-1192/? W/ActivityManager﹕ Force finishing activity com.writers.myapp/.MainActivity

Any idea how to fix this problem?

  • Should I be adding an additional Fabric.with() statement in MainActivity?
  • Should I be catching IllegalStateException? If so, where?
  • Am I doing this all wrong?

Thanks for your help in advance!

like image 611
stellarowl12 Avatar asked Jul 09 '15 23:07

stellarowl12


2 Answers

I would suggest you to have a BaseActivity and make all your Activities extend that BaseActivity.

in onCreate function of that base, initialize Fabric instance if it is not initialized like this:

public class BaseActivity extends Activity {

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

    if (!Fabric.isInitialized()) {
        Fabric.with(....Twitter(authConfig)...)
    }
    //Do other stuff. 
}

That way you will make sure that it is always initialized.

like image 87
tasomaniac Avatar answered Oct 31 '22 04:10

tasomaniac


Fabric has a static method called isInitialized(). So the solution is to check if fabric is initialized before loading Twitter Timeline.

Example :

if (!Fabric.isInitialized()) { 
  TwitterAuthConfig authConfig = new TwitterAuthConfig(TWITTER_KEY,TWITTER_SECRET);
        Fabric.with(getActivity(), new Twitter(authConfig));
    }

// load Twitter Timelines        
like image 24
AhmedZah Avatar answered Oct 31 '22 02:10

AhmedZah