5

I have a facebook initialize sdk call and I need it to initialize the moment application is launched:

I want to use my Application class to do that. for example:

public class App extends Application {

@Override
public void onCreate() {
    super.onCreate();
    FacebookSdk.sdkInitialize(getApplicationContext());
}
}

I have the main activity with the facebook login button:

public class MainActivity extends AppCompatActivity {
@BindView(R.id.login_button)
LoginButton loginButton;

private CallbackManager callbackManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);

    callbackManager = CallbackManager.Factory.create();
    loginButton.registerCallback(callbackManager, new FacebookCallback<LoginResult>() {
        @Override
        public void onSuccess(LoginResult loginResult) {

        }

        @Override
        public void onCancel() {

        }

        @Override
        public void onError(FacebookException error) {

        }
    });
}
}

How do I call my Application singleton? How do I make its onCreate() work?

Ackman
  • 1,562
  • 6
  • 31
  • 54

3 Answers3

26

When you extend android.app.Application class, you do not have to call onCreate explicitly. But make sure you specify it in AndroidManifest.xml, like this android:name="fully-qualified name" eg: android:name="com.example.MyApplication"

You don't have to implement Singleton pattern cause Application IS ALREADY A SINGLETON, there is only one instance of your Application. And, to get the instance of Application or the any custom child of Application you defined, you can simply call context.getApplication().

Reference https://developer.android.com/reference/android/app/Application.html

Seeker
  • 1,030
  • 10
  • 10
4

To make your App class singleton follow the Singleton design pattern:

public class App
  {
    // Create the instance
    private static App instance;
    public static App getInstance()
    {
         if (instance== null) {
                synchronized(App.class) {
                        if (instance == null)
                                instance = new App();
                        }
                }
                // Return the instance
                return instance;
    }

    private App()
    {
        // Constructor hidden because this is a singleton
    }

    public void initFBSdk()
    {
        FacebookSdk.sdkInitialize(getApplicationContext());
    }
}

Then to use it in any other class:

App.getInstance().initFBSdk();

If this is what you are asking for..

Android
  • 1,420
  • 4
  • 13
  • 23
Anmol
  • 448
  • 2
  • 6
  • 4
    How should android start your app if it cannot instanciate the app obj ? – NikkyD Jul 27 '17 at 13:57
  • 1
    Application constructor should be accessible for Android. You shouldn't hide it. – marciowb Jul 29 '17 at 16:41
  • Making the constructor private throws `java.lang.IllegalAccessException: access to constructor not allowed` error during app launch. Also `this` within `synchronized()` shows error `cannot be referenced from a static context` – Tu Shams Feb 14 '18 at 19:15
  • 2
    This is general Singleton Design Pattern in Java, which will not work in Android "Application Class", as Application class is called by ART through its Constructor hence constructor can not be private. To initialize SDK at the application launch, just init in onCreate, and it will work as Application class is run prior to any Activity/service. – Anmol Mar 30 '18 at 16:47
-2

I think you are trying to make a thread safe singleton in java. Here is the code that you need for our App class:

public class App extends Application 
{
    private static App instance;

    public static App getAppInstance() { return instance; }

    @Override
    public void onCreate() 
    {
        super.onCreate();
        instance = this;
    }   

    public void initFacebookSdk()
    {
        FacebookSdk.sdkInitialize(getApplicationContext());
    }
}

This only makes a reference to itself. We want to implement a Singleton for Multithreading. Then we will create another class that encapsulates the App class in its constructor, like this:

public class SingletonApp
{
    private static App appInstance = null;
    private static SingletonApp instance = null;
    private static final Object mutex = new Object();

    public static SingletonApp getInstance() 
    {
        SingletonApp r = instance;
        if (r == null) {
            synchronized (mutex) {  // While we were waiting for the sync, another 
                r = instance;       // thread may have instantiated the object.
                if (r == null) {  
                    r = new SingletonApp();
                    instance = r;
                }
            }
        }

        return r;
    }

    private SingletonDemo()
    {
       // Direct access the Application context calling
       appInstance = App.getAppInstance();
    }

    public static getAppInstance()
    {
       return getInstance().appInstance;
    }
}

Then in your MainActivity class you can import the static instance and use it on your code:

import static your.package.name.SingletonApp.getAppInstance;

For example, you can use it in your MainActivity class just calling the method initFacebookSdk() like this:

public class MainActivity extends AppCompatActivity
{
    ...

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

        initFacebookSdk();

        ...
    }
}
Teocci
  • 7,189
  • 1
  • 50
  • 48
  • 2
    Private application constructor won't work because system will not be able to instantiate it. – Mbengue Assane Jul 15 '17 at 17:54
  • @MbengueAssane do you think that or is an statement? if is an statement I will ask you to test it first before to comment incorrectly and misleading users. Thanks – Teocci Jul 15 '17 at 18:06
  • 1
    Tested ! I got an error : `java.lang.IllegalAccessException: private App() is not accessible from class android.app.Instrumentation` – Mbengue Assane Jul 17 '17 at 02:45
  • I posted a solution that use in my projects. Anyways I updated my solution – Teocci Jul 17 '17 at 05:27