Android 中的应用程序单例使用

Application singleton use in Android

我有一个 facebook 初始化 sdk 调用,我需要它在应用程序启动时进行初始化:

我想使用我的应用程序 class 来做到这一点。例如:

public class App extends Application {

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

我有主要 activity 和 facebook 登录按钮:

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) {

        }
    });
}
}

如何调用我的应用程序单例?我如何让它的 onCreate() 工作?

使您的应用程序 class singleton 遵循 单例设计模式:

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());
    }
}

然后在任何其他地方使用它 class:

App.getInstance().initFBSdk();

如果这就是您要的..

当您扩展 android.app.Application class 时,您不必显式调用 onCreate。但请确保在 AndroidManifest.xml 中指定它, 像这样 android:name="fully-qualified name" 例如:android:name="com.example.MyApplication"

您不必实施单例模式,因为应用程序已经是单例,您的应用程序只有一个实例。 并且,要获取 Application 的 the 实例或您定义的 Application 的任何自定义子项,您只需调用 context.getApplication()

参考https://developer.android.com/reference/android/app/Application.html

我认为您正在尝试在 java 中创建一个线程安全的单例。 这是我们 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());
    }
}

这只是对其自身的引用。我们想为多线程实现一个单例。然后我们将创建另一个 class 将 App class 封装在其构造函数中,如下所示:

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;
    }
}

然后在您的 MainActivity class 中您可以导入静态实例并在您的代码中使用它:

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

例如,您可以在 MainActivity class 中使用它,只需像这样调用方法 initFacebookSdk()

public class MainActivity extends AppCompatActivity
{
    ...

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

        initFacebookSdk();

        ...
    }
}