Android中应用单例的使用

5
我有一个Facebook初始化SDK的调用,我需要在启动Moment应用程序时进行初始化:
我想使用我的Application类来实现。例如:
public class App extends Application {

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

我有一个主要活动,其中包含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()方法生效?


1
android-studio 标签用于关于该工具的问题。 - EJoshuaS - Stand with Ukraine
应用程序类在应用启动时运行,那么你的问题是什么?你想手动运行它吗? - Saeed-rz
3个回答

26

当你扩展android.app.Application类时,你不必显式调用onCreate方法。但一定要在AndroidManifest.xml文件中指定,如此android:name="完整类名", 例如:android:name="com.example.MyApplication"

你不需要实现Singleton模式,因为Application已经是一个单例类,只有一个应用程序实例。 并且,要获取Application或自定义Application子类的任何实例,只需简单地调用context.getApplication()

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


4
为使您的App类成为单例,请遵循单例设计模式
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());
    }
}

然后在任何其他类中使用它:

App.getInstance().initFBSdk();

如果这就是您要询问的内容...

4
如果Android无法实例化应用程序对象,该如何启动您的应用程序? - NikkyD
1
应用程序构造函数应该对Android可访问。您不应该将其隐藏。 - marciowb
将构造函数设为私有会在应用程序启动时抛出“java.lang.IllegalAccessException:不允许访问构造函数”的错误。此外,在synchronized()内部使用this会显示错误“无法从静态上下文引用”。 - Tu Shams
2
这是Java中通用的Singleton设计模式,但在Android的“Application Class”中不起作用,因为ART通过其构造函数调用Application类,因此构造函数不能是私有的。要在应用程序启动时初始化SDK,只需在onCreate中进行初始化即可,因为Application类在任何Activity/Service之前运行。 - Anmol

-2

我想你正在尝试在Java中创建一个线程安全的单例模式。 以下是我们的App类所需的代码:

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

这只是对自身的引用。我们想要实现一个用于多线程的单例模式。然后,我们将创建另一个类,在其构造函数中封装App类,像这样:

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类中,你可以导入静态实例并在你的代码中使用它:

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

例如,您可以在您的MainActivity类中调用方法initFacebookSdk()来使用它,就像这样:

public class MainActivity extends AppCompatActivity
{
    ...

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

        initFacebookSdk();

        ...
    }
}

2
私有应用程序构造函数无法工作,因为系统将无法实例化它。 - Mbengue Assane
@MbengueAssane,你认为这是陈述还是假设?如果这是一个陈述,我会要求你先测试一下再发表评论,以免误导用户。谢谢。 - Teocci
1
测试过了!我收到了一个错误: java.lang.IllegalAccessException: private App() is not accessible from class android.app.Instrumentation - Mbengue Assane
我发布了一个在我的项目中使用的解决方案。无论如何,我更新了我的解决方案。 - Teocci

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接