Android中的Singleton

use*_*292 70 singleton android

我已经按照这个链接成功地在Android中制作了单例类. http://www.devahead.com/blog/2011/06/extending-the-android-application-class-and-dealing-with-singleton/

问题是我想要一个对象.就像我有活动A和活动B.在活动AI中从Singleton访问对象class.我使用该对象并对其进行了一些更改.

当我移动到Activity B并从Singleton Class访问该对象时,它给了我初始化的对象,并且不保留我在Activity A中所做的更改.还有其他方法可以保存更改吗?请高手帮帮我.这是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);
    }

}
Run Code Online (Sandbox Code Playgroud)

}

这是 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);
        }
  }
Run Code Online (Sandbox Code Playgroud)

Singleton

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
     }
 }
Run Code Online (Sandbox Code Playgroud)

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
    }
}
Run Code Online (Sandbox Code Playgroud)

当我运行这段代码时,我得到了Hello,我已经在Singleton当时的World中初始化了我给了它MainActivity并再次NextActivity在logcat中显示Hello .我希望它再次向世界展示NextActivity.请帮我纠正一下.

Laz*_*azy 59

提示:创建单例类在Android Studio中,右键单击项目并打开菜单:

New -> Java Class -> Choose Singleton from dropdown menu
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

  • 不再可用 (4认同)

Aka*_*ayh 46

编辑:

在Android中实现Singleton是不安全的,您应该使用专用于这种模式的库,如Dagger或其他DI库来管理生命周期和注入.


你能从你的代码中发布一个例子吗?

看看这个要点:https://gist.github.com/Akayh/5566992

它工作但很快就完成了:

MyActivity:第一次设置单例+在私有构造函数中初始化mString属性("Hello")并显示值("Hello")

将新值设置为mString:"Singleton"

启动activityB并显示mString值."单身人士"出现......

  • 只是一个抬头,这是*不*线程安全!永远,记住墨菲定律.使线程安全的一种方法是在`getInstance()`方法中使用`synchronized` keyworkd. (6认同)
  • 这只是因为字符串是在singletonVar中复制而不是对它的引用.如果直接更改静态变量如下:Singleton.customVar ="World"; 这是工作. (3认同)
  • @Akayh你能解释为什么Singleton在Android上不安全吗?是否安全只对活动不安全或在应用上不安全? (3认同)

Rak*_*esh 31

很简单,作为java,Android也支持单例. -

Singleton是Gang of Four设计模式的一部分,它被归类为创造性设计模式.

- >静态成员:这包含单例类的实例.

- >私有构造函数:这将阻止任何其他人实例化Singleton类.

- >静态公共方法:这提供了对Singleton对象的全局访问点,并将实例返回给客户端调用类.

  1. 创建私有实例
  2. 创建私有构造函数
  3. 使用Singleton类的getInstance()

    public class Logger{
    private static Logger   objLogger;
    private Logger(){
    
            //ToDo here
    
    }
    public static Logger getInstance()
    {
        if (objLogger == null)
       {
          objLogger = new Logger();
       }
       return objLogger;
       }
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

同时使用单身人士 -

Logger.getInstance();
Run Code Online (Sandbox Code Playgroud)


ash*_*h.n 18

rakesh提出的答案很好,但仍有一些描述Android中的Singleton与Java中的Singleton相同:Singleton设计模式解决了所有这些问题.使用Singleton设计模式,您可以:

1)确保只创建一个类的一个实例

2)提供对象的全局访问点

3)将来允许多个实例,而不会影响单例类的客户端

一个基本的Singleton类示例:

public class MySingleton
{
    private static MySingleton _instance;

    private MySingleton()
    {

    }

    public static MySingleton getInstance()
    {
        if (_instance == null)
        {
            _instance = new MySingleton();
        }
        return _instance;
    }
}
Run Code Online (Sandbox Code Playgroud)


Ada*_*dam 12

正如@Lazy在本回答中所述,您可以在Android Studio中从模板创建单例.值得注意的是,不需要检查实例是否为null,因为ourInstance首先初始化静态变量.因此,Android Studio创建的单例类实现就像下面的代码一样简单:

public class MySingleton {
    private static MySingleton ourInstance = new MySingleton();

    public static MySingleton getInstance() {
        return ourInstance;
    }

    private MySingleton() {
    }
}
Run Code Online (Sandbox Code Playgroud)


Dus*_*san 5

您正在将单例复制customVarsingletonVar变量中,并且更改该变量不会影响单例中的原始值.

// 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;
Run Code Online (Sandbox Code Playgroud)