J'ai suivi ce lien et réussi à faire la classe singleton sous Android. http://www.devahead.com/blog/2011/06/extending-the-Android-application-class-and-dealing-with-singleton/
Le problème est que je veux un seul objet. comme si j'avais l'activité A et l'activité B. Dans l'activité A, j'accède à l'objet de Singleton class
. J'utilise l'objet et y ai apporté quelques modifications.
Lorsque je passe à l'activité B et que j'accède à l'objet à partir de Singleton Class, il m'a donné l'objet initialisé et ne conserve pas les modifications que j'ai apportées dans l'activité A. Existe-t-il un autre moyen de sauvegarder les modifications? S'il vous plaît aidez-moi des experts. C'est MainActivity
public class MainActivity extends Activity {
protected MyApplication app;
private OnClickListener btn2=new OnClickListener() {
@Override
public void onClick(View arg0) {
Intent intent=new Intent(MainActivity.this,NextActivity.class);
startActivity(intent);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Get the application instance
app = (MyApplication)getApplication();
// Call a custom application method
app.customAppMethod();
// Call a custom method in MySingleton
Singleton.getInstance().customSingletonMethod();
Singleton.getInstance();
// Read the value of a variable in MySingleton
String singletonVar = Singleton.customVar;
Log.d("Test",singletonVar);
singletonVar="World";
Log.d("Test",singletonVar);
Button btn=(Button)findViewById(R.id.button1);
btn.setOnClickListener(btn2);
}
}
C'est NextActivity
public class NextActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_next);
String singletonVar = Singleton.customVar;
Log.d("Test",singletonVar);
}
}
Singleton
Classe
public class Singleton
{
private static Singleton instance;
public static String customVar="Hello";
public static void initInstance()
{
if (instance == null)
{
// Create the instance
instance = new Singleton();
}
}
public static Singleton getInstance()
{
// Return the instance
return instance;
}
private Singleton()
{
// Constructor hidden because this is a singleton
}
public void customSingletonMethod()
{
// Custom method
}
}
et MyApplication
public class MyApplication extends Application
{
@Override
public void onCreate()
{
super.onCreate();
// Initialize the singletons so their instances
// are bound to the application process.
initSingletons();
}
protected void initSingletons()
{
// Initialize the instance of MySingleton
Singleton.initInstance();
}
public void customAppMethod()
{
// Custom application method
}
}
Lorsque j'exécute ce code, je reçois Hello, que j'ai initialisé dans Singleton
puis World, que je lui ai donné dans MainActivity
et qui affiche encore Hello dans NextActivity
dans logcat. Je veux qu'il montre à nouveau le monde dans NextActivity
. S'il vous plaît aidez-moi à corriger cela.
EDIT:
L'implémentation d'un Singleton dans Android n'est pas "sûre" ( voir ici ) et vous devriez utiliser une bibliothèque dédiée à ce type de modèle comme Dagger ou une autre bibliothèque DI pour gérer le cycle de vie et l'injection.
Pourriez-vous poster un exemple de votre code?
Jetez un oeil à cette Gist: https://Gist.github.com/Akayh/5566992
ça marche mais ça a été fait très vite:
MyActivity: définit le singleton pour la première fois + initialise l'attribut mString ("Hello") dans un constructeur privé et affiche la valeur ("Hello")
Définissez la nouvelle valeur sur mString: "Singleton"
Lancez activityB et affichez la valeur mString. "Singleton" apparaît ...
C'est simple, en Java, Android prend également en charge singleton. -
Singleton fait partie du modèle de conception de Gang of Four et est classé dans les modèles de conception.
-> Membre statique: contient l'instance de la classe singleton.
-> Constructeur privé: Ceci empêchera quiconque d'instancier la classe Singleton.
-> Méthode publique statique: Ceci fournit le point d'accès global à l'objet Singleton et renvoie l'instance à la classe appelante client.
utiliser getInstance () de la classe Singleton
public class Logger{
private static Logger objLogger;
private Logger(){
//ToDo here
}
public static Logger getInstance()
{
if (objLogger == null)
{
objLogger = new Logger();
}
return objLogger;
}
}
en utilisant singleton -
Logger.getInstance();
la réponse suggérée par rakesh est excellente, mais toujours avec une discription, Singleton dans Android est identique à Singleton en Java: le modèle de conception Singleton répond à toutes ces préoccupations. Avec le motif de conception Singleton, vous pouvez:
1) Assurez-vous qu'une seule instance d'une classe est créée
2) Fournir un point d'accès global à l'objet
3) Autoriser plusieurs instances dans le futur sans affecter les clients d'une classe singleton
Exemple de classe Singleton de base:
public class MySingleton
{
private static MySingleton _instance;
private MySingleton()
{
}
public static MySingleton getInstance()
{
if (_instance == null)
{
_instance = new MySingleton();
}
return _instance;
}
}
Comme @Lazy l'a déclaré dans cette réponse , vous pouvez créer un singleton à partir d'un modèle dans Android Studio. Il est à noter qu'il n'est pas nécessaire de vérifier si l'instance est nulle, car la variable statique ourInstance
est d'abord initialisée. En conséquence, l'implémentation de la classe singleton créée par Android Studio est aussi simple que le code suivant:
public class MySingleton {
private static MySingleton ourInstance = new MySingleton();
public static MySingleton getInstance() {
return ourInstance;
}
private MySingleton() {
}
}
Vous copiez la variable customVar
du singleton dans une variable singletonVar
et sa modification n'affecte pas la valeur d'origine du singleton.
// This does not update singleton variable
// It just assigns value of your local variable
Log.d("Test",singletonVar);
singletonVar="World";
Log.d("Test",singletonVar);
// This actually assigns value of variable in singleton
Singleton.customVar = singletonVar;
Je mets ma version de Singleton ci-dessous:
public class SingletonDemo {
private static SingletonDemo instance = null;
private static Context context;
/**
* To initialize the class. It must be called before call the method getInstance()
* @param ctx The Context used
*/
public static void initialize(Context ctx) {
context = ctx;
}
/**
* Check if the class has been initialized
* @return true if the class has been initialized
* false Otherwise
*/
public static boolean hasBeenInitialized() {
return context != null;
}
/**
* The private constructor. Here you can use the context to initialize your variables.
*/
private SingletonDemo() {
// Use context to initialize the variables.
}
/**
* The main method used to get the instance
*/
public static synchronized SingletonDemo getInstance() {
if (context == null) {
throw new IllegalArgumentException("Impossible to get the instance. This class must be initialized before");
}
if (instance == null) {
instance = new SingletonDemo();
}
return instance;
}
@Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException("Clone is not allowed.");
}
}
Notez que la méthode initialize peut être appelée dans la classe principale (Splash) et que la méthode getInstance peut être appelée à partir d'autres classes. Cela résoudra le problème lorsque la classe appelante requiert le singleton, mais elle n’a pas le contexte.
Enfin, la méthode hasBeenInitialized est utilisée pour vérifier si la classe a été initialisée. Cela évitera que différentes instances aient des contextes différents.
La manière la plus propre et la plus moderne d’utiliser des singletons dans Android consiste simplement à utiliser le cadre Dependency Injection appelé Dagger 2 . Ici vous avez une explication des portées possibles que vous pouvez utiliser. Singleton est l'un de ces domaines. L'injection de dépendance n'est pas si facile, mais vous devrez investir un peu de votre temps pour le comprendre. Cela facilite également les tests.