Использование одноэлементного приложения в Android

У меня есть вызов sdk для инициализации facebook, и он мне нужен для инициализации в момент запуска приложения:

Я хочу использовать для этого свой класс 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 ()?


person Ackman    schedule 04.04.2017    source источник
comment
Тег android-studio предназначен для вопросов об инструменте   -  person EJoshuaS - Reinstate Monica    schedule 04.04.2017
comment
класс приложения запускается при запуске приложения, так в чем ваша проблема? вы хотите запустить его вручную?   -  person Saeed-rz    schedule 04.04.2017


Ответы (3)


Чтобы класс вашего приложения singleton соответствовал шаблону проектирования 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());
    }
}

Затем использовать его в любом другом классе:

App.getInstance().initFBSdk();

Если это то, о чем вы просите ..

person Anmol    schedule 04.04.2017
comment
Как Android должен запускать ваше приложение, если он не может создать экземпляр приложения obj? - person NikkyD; 27.07.2017
comment
Конструктор приложения должен быть доступен для Android. Вы не должны этого скрывать. - person marciowb; 29.07.2017
comment
Если сделать конструктор закрытым, во время запуска приложения возникает java.lang.IllegalAccessException: access to constructor not allowed ошибка. Также this в synchronized() показывает ошибку cannot be referenced from a static context - person Tu Shams; 14.02.2018
comment
Это общий шаблон проектирования Singleton в Java, который не будет работать в классе приложений Android, поскольку класс приложения вызывается ART через его конструктор, поэтому конструктор не может быть частным. Чтобы инициализировать SDK при запуске приложения, просто запустите onCreate, и он будет работать, поскольку класс Application запускается до любого действия / службы. - person Anmol; 30.03.2018

Когда вы расширяете класс android.app.Application, вам не нужно явно вызывать onCreate. Но убедитесь, что вы указали его в AndroidManifest.xml, например, android: name = "полное имя", например: android: name = "com.example.MyApplication"

Вам не нужно реализовывать шаблон Singleton, потому что Приложение УЖЕ ОДИНОЧНОЕ, существует только один экземпляр вашего приложения. А чтобы получить экземпляр Application или любой пользовательский дочерний элемент Application, который вы определили, вы можете просто вызвать context.getApplication ().

Ссылка https://developer.android.com/reference/android/app/Application.html

person Seeker    schedule 04.04.2017

Я думаю, вы пытаетесь создать потокобезопасный синглтон в 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();

        ...
    }
}
person Teocci    schedule 20.06.2017
comment
Конструктор частного приложения не будет работать, потому что система не сможет его создать. - person Mbengue Assane; 15.07.2017
comment
@MbengueAssane как вы думаете, это заявление? Если это утверждение, я попрошу вас сначала протестировать его, прежде чем комментировать некорректно и вводить пользователей в заблуждение. Спасибо - person Teocci; 15.07.2017
comment
Проверено! Получил ошибку: java.lang.IllegalAccessException: private App() is not accessible from class android.app.Instrumentation - person Mbengue Assane; 17.07.2017
comment
Я выложил решение, которое использую в своих проектах. В любом случае я обновил свое решение - person Teocci; 17.07.2017