我已经关注此链接并成功在Android中制作了单例类。 http://www.devahead.com/blog/2011/06/extending-the-android-application-class-and-dealing-with-singleton/
问题是我想要一个对象。就像我有活动A和活动B.在活动A中我从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);
}
}
这是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
班级
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
}
}
和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
}
}
当我运行这段代码时,我得到了我已经在Singleton
中初始化的Hello,然后是我在MainActivity
中给出的World,并再次在logcat中显示NextActivity
中的Hello。
我想让它在NextActivity
再次显示世界。
请帮我纠正一下。
答案 0 :(得分:58)
提示:创建单例类在Android Studio中,右键单击项目并打开菜单:
Private Sub cmdLogin_Click()
'Check to see if data is entered into the Username combo box
Dim strMyUsername As String
Dim RS As Recordset
If IsNull(Me.cbo_Employee) Or Me.cbo_Employee = "" Then
MsgBox "You Must enter a Username.", vbOKOnly, "Required Data"
Me.cbo_Employee.SetFocus
Exit Sub
End If
strMyUsername = Me.cbo_Employee.Value
'Check to see if data is entered into the password box
If IsNull(Me.txt_Password) Or Me.txt_Password = "" Then
MsgBox "You must enter a Password.", vbOKOnly, "Required Data"
Me.txt_Password.SetFocus
Exit Sub
End If
Set RS = CurrentDb.OpenRecordset("SELECT * FROM [Employees Table] WHERE [Username] = '" & strMyUsername & "'", dbOpenSnapshot)
'Check value of password in Employees Table to see if this matches value chosen in combo box
If Me.txt_Password.Value <> Nz(RS!Password) Then
MsgBox "Password Invalid. Please Try Again", vbOKOnly, "Invalid Entry!"
Me.txt_Password.SetFocus
Me.txt_Password = Null
intLogonAttempts = intLogonAttempts + 1
'If user enters incorrect password 3 times database will shutdown
If intLogonAttempts >= 3 Then
MsgBox "You do not have access to this database. Please contact your system administrator.", vbCritical, "Restricted Access!"
Application.Quit
End If
Else
Me.txt_Password = Null
'Open correct form
Dim strAccessLevel As String
strAccessLevel = RS!Admins
If strAccessLevel = "Admin" Then
MsgBox "Welcome " & RS!EmployeeName
DoCmd.Close
DoCmd.OpenForm "A"
ElseIf strAccessLevel = "Manager" Then
MsgBox "Welcome " & RS!EmployeeName
DoCmd.Close
DoCmd.OpenForm "B"
ElseIf strAccessLevel = "User" Then
MsgBox "Welcome " & RS!EmployeeName
DoCmd.Close
DoCmd.OpenForm "C"
End If
End If
End Sub
答案 1 :(得分:44)
编辑:
在Android中实现Singleton并不安全,您应该使用专用于此类模式的库,如Dagger或其他DI库来管理生命周期和注入。
你能从你的代码中发布一个例子吗?
看看这个要点:https://gist.github.com/Akayh/5566992
它有效,但很快就完成了:
MyActivity:首次设置单例+在私有构造函数中初始化mString属性(“Hello”)并显示值(“Hello”)
将新值设置为mString:“Singleton”
启动activityB并显示mString值。 “单身人士”出现......
答案 2 :(得分:30)
Singleton是Gang of Four设计模式的一部分,它被归类为创作设计模式。
- &GT;静态成员:它包含单例类的实例。
- &GT;私有构造函数:这将阻止任何其他人实例化Singleton类。
- &GT;静态公共方法:这提供了对Singleton对象的全局访问点,并将实例返回给客户端调用类。
使用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;
}
}
使用单身人士 -
Logger.getInstance();
答案 3 :(得分:18)
1)确保只创建一个类的一个实例
2)提供对象的全局访问点
3)将来允许多个实例而不影响a 单身人士的客户
一个基本的Singleton类示例:
public class MySingleton
{
private static MySingleton _instance;
private MySingleton()
{
}
public static MySingleton getInstance()
{
if (_instance == null)
{
_instance = new MySingleton();
}
return _instance;
}
}
答案 4 :(得分:12)
正如@ this answer中所述@Lazy所述,您可以在Android Studio中的模板中创建单例。值得注意的是,不需要检查实例是否为null,因为静态ourInstance
变量首先被初始化。因此,Android Studio创建的单例类实现就像下面的代码一样简单:
public class MySingleton {
private static MySingleton ourInstance = new MySingleton();
public static MySingleton getInstance() {
return ourInstance;
}
private MySingleton() {
}
}
答案 5 :(得分:5)
您正在将单身customVar
复制到singletonVar
变量中,并且更改该变量不会影响单身中的原始值。
// 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;
答案 6 :(得分:2)
我把我的Singleton版本放在下面:
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.");
}
}
请注意,可以在主类(Splash)中调用方法初始化,并且可以从其他类调用方法getInstance。当调用者类需要单例但它没有上下文时,这将解决问题。
最后,方法hasBeenInitialized用于检查类是否已初始化。这将避免不同的实例具有不同的上下文。
答案 7 :(得分:1)
在Android中使用单例的最干净和最现代的方法就是使用名为Dependency Injection的Dagger 2框架。 Here您可以解释可以使用的范围。 Singleton是这些范围之一。依赖注入并不那么容易,但你应该投入一点时间来理解它。它还使测试更容易。