Android全局变量


293

我如何创建全局变量,在应用程序的生命周期中保持剩余值,而不管运行哪个活动。


以及为什么我们应该使用set and get(Jeff Gilfelt的方法)?为什么我们只将值直接设置为变量?像这样:public volatile static String x; 并设置值:GeneralClass.x = value;
Dr.jacky 2014年

Answers:


531

您可以扩展基android.app.Application类并添加成员变量,如下所示:

public class MyApplication extends Application {

    private String someVariable;

    public String getSomeVariable() {
        return someVariable;
    }

    public void setSomeVariable(String someVariable) {
        this.someVariable = someVariable;
    }
}

在您的android清单中,您必须声明实现android.app.Application的类(将android:name=".MyApplication"属性添加到现有的application标记中):

<application 
  android:name=".MyApplication" 
  android:icon="@drawable/icon" 
  android:label="@string/app_name">

然后,在您的活动中,您可以像这样获取并设置变量:

// set
((MyApplication) this.getApplication()).setSomeVariable("foo");

// get
String s = ((MyApplication) this.getApplication()).getSomeVariable();

4
很棒的帮助,我真的很喜欢。
d-man 2010年

6
不幸的是,它对我不起作用。请确认之后,清单中将有两个<application>标记。对?因为在某些地方我听到有人说我们必须将其添加到现有的应用程序标签中。请帮忙 !!
Adil Malik

9
@AdilMalik您必须将android:name标签添加到现有的应用程序标签中
Marijn

2
为什么不创建一个带有公共静态字段的类而不需要访问上下文呢?
Laserson 2014年

50
这应该是不正确的答案,因为它可能导致意外行为以及由于清理内存而导致NPE。developerphil.com/dont-store-data-in-the-application-object
巴库2015年

43

您可以这样使用Singleton Pattern

package com.ramps;

public class MyProperties {
private static MyProperties mInstance= null;

public int someValueIWantToKeep;

protected MyProperties(){}

public static synchronized MyProperties getInstance() {
        if(null == mInstance){
            mInstance = new MyProperties();
        }
        return mInstance;
    }
}

在您的应用程序中,您可以通过以下方式访问您的单身人士:

MyProperties.getInstance().someValueIWantToKeep

28
如果活动暂停并且用户启动了另一个应用程序,并且在该内存不足期间该怎么办,这就是为什么当用户恢复应用程序并发现此静态引用为null时android删除了此静态对象的原因?
d-man

4
静态对于单独流程中的活动是无用的。
ateiob 2012年

3
如果您的实例被垃圾回收,这将无法正常工作。因此代码块if(null == mInstance){mInstance = new MyProperties(); }将起作用,并且将返回新实例,这将重置属性
Lalith B

1
@ Mr.Hyde Singleton并不是唯一的,就是我们需要知道在Singleton中保留什么。如果我们保留巨大的位图数组或某些集合,则可能会很危险。记下您在Singleton中保留的内容。
Lalith B 2014年

1
我知道我来晚了,但对于将来的读者,我们可以将值存储在SharedPreferences,SQLLite数据库或内部存储器文件中。即使关闭了应用程序,这些都将具有数据持久性。
powernit

15

此全局变量适用于我的项目:

public class Global {
    public static int ivar1, ivar2;
    public static String svar1, svar2;
    public static int[] myarray1 = new int[10];
}


//  How to use other or many activity
Global.ivar1 = 10;

int i = Global.ivar1;

2
但是,您如何将其传递给多个活动呢?
Zapnologica

15
当应用程序挂起且设备内存不足时,Android VM可能会将这些静态信息(至少是字符串和数组)清除为零。
安东

4
@mahasam我不认为static应该是正确的方法...如果它只是活动,则应该通过Application上下文。否则,如上述其他答案所述。静态将强烈地耦合代码,并且还降低了可测试性
Punith Raj

14

您可以使用应用程序首选项。只要您传递Context对象,就可以从任何活动或代码段访问它们,并且它们对于使用它们的应用程序是私有的,因此您不必担心公开应用程序特定的值,除非您处理路由设备。即使这样,您也可以使用哈希或加密方案来保存值。同样,这些首选项从应用程序运行到下一个存储。 是一些代码示例,您可以查看。


我已经更新了链接。该项目托管在Google Code上,我们知道该项目已关闭。链接来自Github。
r1k0 2015年

8

您可以通过几种不同的方法来实现自己的要求。

1.)扩展应用程序类,并在那里实例化控制器和模型对象。

public class FavoriteColorsApplication extends Application {

    private static FavoriteColorsApplication application;
    private FavoriteColorsService service;

    public FavoriteColorsApplication getInstance() {
        return application;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        application = this;
        application.initialize();
    }

    private void initialize() {
        service = new FavoriteColorsService();
    }

    public FavoriteColorsService getService() {
        return service;
    }

}

然后,您可以随时从您的自定义Application对象调用您的单例:

public class FavoriteColorsActivity extends Activity {

private FavoriteColorsService service = null;
private ArrayAdapter<String> adapter;
private List<String> favoriteColors = new ArrayList<String>();

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

    service = ((FavoriteColorsApplication) getApplication()).getService();
    favoriteColors = service.findAllColors();

    ListView lv = (ListView) findViewById(R.id.favoriteColorsListView);
    adapter = new ArrayAdapter<String>(this, R.layout.favorite_colors_list_item,
            favoriteColors);
    lv.setAdapter(adapter);
}

2)您可以让您的控制器仅创建其自身的单例实例:

public class Controller {
    private static final String TAG = "Controller";
    private static sController sController;
    private Dao mDao;

    private Controller() {
        mDao = new Dao();    
    }

    public static Controller create() {
        if (sController == null) {
            sController = new Controller();
        }
        return sController;
    }
}

然后,您可以只从任何Activity或Fragment调用create方法,如果尚不存在,它将创建一个新的控制器,否则它将返回先前存在的控制器。

3.)最后,在Square创建了一个漂亮的框架,可为您在Android中注入依赖项。它被称为匕首。我不会在这里介绍如何使用它,但是如果您需要这种东西,它会非常巧妙。

我希望我就如何完成您希望的事情给出了足够的细节。


6

像这样尝试:

创建一个共享数据类:

SharedData.java

import android.app.Application;

/**
 * Created by kundan on 6/23/2015.
 */
public class Globals {


    private static Globals instance = new Globals();

    // Getter-Setters
    public static Globals getInstance() {
        return instance;
    }

    public static void setInstance(Globals instance) {
        Globals.instance = instance;
    }

    private String notification_index;


    private Globals() {

    }


    public String getValue() {
        return notification_index;
    }


    public void setValue(String notification_index) {
        this.notification_index = notification_index;
    }



}

在要设置/获取数据的类中全局声明/初始化类的实例(在onCreate()方法前使用此代码):

Globals sharedData = Globals.getInstance();

设置数据:

sharedData.setValue("kundan");

获取数据:

String n = sharedData.getValue();

4

您可以这样创建Global Class

public class GlobalClass extends Application{

    private String name;
    private String email;

    public String getName() {
        return name;
    }

    public void setName(String aName) {
        name = aName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String aEmail) {
        email = aEmail;
    }
}

然后在清单中定义它:

<application
    android:name="com.example.globalvariable.GlobalClass" ....

现在,您可以将值设置为全局变量,如下所示:

final GlobalClass globalVariable = (GlobalClass) getApplicationContext();
globalVariable.setName("Android Example context variable");

您可以这样获得这些值:

final GlobalClass globalVariable = (GlobalClass) getApplicationContext();
final String name  = globalVariable.getName();

请从此博客中找到完整的示例 全局变量


3
// My Class Global Variables  Save File Global.Java
public class Global {
    public static int myVi; 
    public static String myVs;
}

// How to used on many Activity

Global.myVi = 12;
Global.myVs = "my number";
........
........
........
int i;
int s;
i = Global.myVi;
s = Global.myVs + " is " + Global.myVi;

1
为什么要在同一问题中发布两个答案?您可以将其编辑为一个。
库努

2

我检查了类似的答案,但此处给出的答案不符合我的需求。从我的角度来看,我发现了您正在寻找的东西。唯一可能的问题是安全(或可能不是),因为我对安全一无所知。

我建议使用Interface(不需要在构造函数中使用Class等),因为您只需创建类似以下内容的代码:

public interface ActivityClass {

    public static final String MYSTRING_1 = "STRING";

    public static final int MYINT_1 = 1;

}

然后,您可以使用以下命令访问班级中的所有地方:

int myInt = ActivityClass.MYINT_1;
String myString = ActivityClass.MYSTRING_1;

1

从技术上讲,这不能解决问题,但是我建议您使用Room数据库而不是任何全局变量。 https://developer.android.com/topic/libraries/architecture/room.html 即使您只需要存储全局变量,也没什么大不了的,没什么,但是使用Room数据库是最优雅的方法,这是一种在活动的整个生命周期内保持价值的原生且受良好支持的方法。这将有助于防止许多问题,尤其是数据完整性。我了解数据库和全局变量是不同的,但是为了代码维护,应用程序稳定性和数据完整性,请使用Room。


1

使用SharedPreferences存储和检索全局变量。

SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
String userid = preferences.getString("userid", null);

0

如果可能的话,应该在文件.so中声明垃圾收集器或OS尚未清除的,需要保持活动的变量。为此,必须使用C / C ++进行编码并编译为.so lib文件,然后将其加载到您的MainActivity中。


1
本机代码是一种将数据保存在RAM中的痛苦方式,而且这样做没有Java static变量更好。
2014年

我看不出这种方法的意义。您能否详细说明在哪种情况下这是一个好主意?
miva2 '16

-1
import android.app.Application;

public class Globals extends Application
{
    private static Globals instance = null;
    private static int RecentCompaignID;
    private static int EmailClick;
    private static String LoginPassword;
    static String loginMemberID;
    private static String CompaignName = "";
    private static int listget=0;
    //MailingDetails
    private static String FromEmailadd="";
    private static String FromName="";
    private static String ReplyEmailAdd="";
    private static String CompaignSubject="";
    private static int TempId=0;
    private static int ListIds=0;

    private static String HTMLContent="";
    @Override
    public void onCreate() 
    {
        super.onCreate();
        instance = this;
    }

    public static Globals getInstance()
    {
        return instance;
    }

    public void setRecentCompaignID(int objRecentCompaignID)
    {
        RecentCompaignID = objRecentCompaignID;
    }

    public int getRecentCompaignID() 
    {
        return RecentCompaignID;
    }

    public void setLoginMemberID(String objloginMemberID) 
    {
        loginMemberID = objloginMemberID;
    }

    public String getLoginMemberID() 
    {
        return loginMemberID;
    }

    public void setLoginMemberPassword(String objLoginPassword)
    {
        LoginPassword = objLoginPassword;
    }

    public String getLoginMemberPassword()
    {
        return LoginPassword;
    }

    public void setEmailclick(int id)
    {
        EmailClick = id;
    }

    public int getEmailClick() 
    {
        return EmailClick;
    }
    public void setCompaignName(String objCompaignName)
    {
        CompaignName=objCompaignName;
    }
    public String getCompaignName()
    {
        return CompaignName;
    }
    public void setlistgetvalue(int objlistget)
    {
        listget=objlistget;
    }
    public int getlistvalue()
    {
        return listget;
    }
    public void setCompaignSubject(String objCompaignSubject)
    {
         CompaignSubject=objCompaignSubject;
    }
    public String getCompaignSubject()
    {
        return CompaignSubject;
    }
    public void setHTMLContent(String objHTMLContent)
    {
        HTMLContent=objHTMLContent;
    }
    public String getHTMLContent()
    {
        return HTMLContent;
    }
    public void setListIds(int objListIds)
    {
        ListIds=objListIds;
    }
    public int getListIds()
    {
        return ListIds;
    }
    public void setReplyEmailAdd(String objReplyEmailAdd)
    {
        ReplyEmailAdd=objReplyEmailAdd;
    }
    public String getReplyEmailAdd()
    {
        return ReplyEmailAdd;
    }
    public void setFromName(String objFromName)
    {
        FromName=objFromName;
    }
    public String getFromName()
    {
        return FromName;
    }
    public void setFromEmailadd(String objFromEmailadd)
    {
        FromEmailadd=objFromEmailadd;
    }
    public String getFromEmailadd()
    {
        return FromEmailadd;
    }
}

-5

简单!!!!

您要访问的那些变量为全局变量,可以将它们声明为静态变量。现在,您可以使用来访问这些变量

classname.variablename;

public class MyProperties {
private static MyProperties mInstance= null;

static int someValueIWantToKeep;

protected MyProperties(){}

public static synchronized MyProperties getInstance(){
    if(null == mInstance){
        mInstance = new MyProperties();
    }
    return mInstance;
}

}

MyProperites.someValueIWantToKeep;

而已!;)


不知道为什么它被否决了那么多;与其他一些网络支持的答案相比,我看到这正确地(iirc)synchronized在静态上使用,getInstance()而其他人则没有。相应地投票支持。
user2297550
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.