Variável global do Android

293

Como posso criar variáveis ​​globais para manter valores permanentes em todo o ciclo de vida do aplicativo, independentemente da atividade em execução.

d-man
fonte
E por que devemos usar set e get (a resposta de Jeff Gilfelt) ?! Por que apenas definimos valor diretamente para variável? assim: public volatile static String x; e para definir o valor: GeneralClass.x = value;
Dr.jacky

Respostas:

531

Você pode estender a android.app.Applicationclasse base e adicionar variáveis ​​de membro da seguinte forma:

public class MyApplication extends Application {

    private String someVariable;

    public String getSomeVariable() {
        return someVariable;
    }

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

No manifesto do Android, você deve declarar a classe implementando android.app.Application (adicione o android:name=".MyApplication"atributo à tag do aplicativo existente):

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

Em suas atividades, você pode obter e definir a variável da seguinte maneira:

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

// get
String s = ((MyApplication) this.getApplication()).getSomeVariable();
Jeff Gilfelt
fonte
4
ajuda incrível, eu realmente aplico.
que você
6
Infelizmente não está funcionando para mim. Confirme que, depois disso, teremos duas tags <application> em manifesto. Certo? Porque em alguns lugares ouvi pessoas dizendo que precisamos adicionar isso à tag de aplicativo existente. Por favor ajude !!
Adil Malik
9
@AdilMalik Você deve adicionar a tag android: name à tag de aplicativo existente #
Marijn 13/03
2
Por que não criar apenas uma classe com campos estáticos públicos sem a necessidade de acessar um contexto?
Laserson
51
Essa resposta não deve ser correta, pois pode levar a comportamentos imprevisíveis e ao NPE devido à limpeza da memória. developerphil.com/dont-store-data-in-the-application-object
bakua
43

Você pode usar um Singleton Patterncomo este:

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;
    }
}

Na sua aplicação, você pode acessar seu singleton desta maneira:

MyProperties.getInstance().someValueIWantToKeep
Rampas
fonte
28
E se a atividade pausasse e o usuário iniciasse outro aplicativo e, durante essa memória, era baixo, é por isso que o Android removeu esse objeto estático quando o usuário reiniciou o aplicativo e encontrou esta referência estática nula ???
d-man
4
Uma estática é inútil entre as atividades em processos separados.
ateiob
3
isso não funcionará se sua instância for coletada como lixo. então o bloco de código if (null == mInstance) {mInstance = new MyProperties (); } Irá funcionar e nova instância irá ser devolvido, que irá repor as propriedades
Lalith B
1
@ Mr.Hyde Singleton não é inútil, é apenas que precisamos saber o que manter dentro do Singleton. Se mantivermos enormes conjuntos de matrizes de bitmap ou algumas coleções, isso pode se tornar perigoso. Anote o que você mantém dentro do Singleton.
precisa
1
Sei que estou um pouco atrasado, mas para futuros leitores, podemos armazenar valores em SharedPreferences, SQLLite Database ou An Internal memory file. Todos eles terão persistência de dados, mesmo se o aplicativo estiver fechado.
Powernit
15

Essa variável global funciona para o meu projeto:

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;
mahasam
fonte
2
Mas então como você o passa para várias atividades?
Zapnologica
15
Essas estáticas (pelo menos, sequência e matriz) podem ser anuladas pela VM do Android quando o aplicativo é suspenso e o dispositivo tem pouca memória.
Anton
4
@ Mahasam eu não acho que a estática deve ser o caminho certo ... se suas únicas atividades, deve ser via contexto de aplicativo. Caso contrário, como indicado em outras respostas acima. estática será fortemente par o código, e também reduz a capacidade de teste
Punith Raj
14

Você pode usar as preferências do aplicativo. Eles são acessíveis a partir de qualquer atividade ou parte do código, desde que você transmita o objeto Context, e são privados para o aplicativo que os utiliza, portanto, você não precisa se preocupar em expor valores específicos do aplicativo, a menos que lide com roteados. dispositivos. Mesmo assim, você pode usar esquemas de hash ou criptografia para salvar os valores. Além disso, essas preferências são armazenadas de um aplicativo executado para o próximo. Aqui estão alguns exemplos de código que você pode ver.

r1k0
fonte
Eu atualizei o link. O projeto foi hospedado no Google Code e, como sabemos, foi encerrado. O link é do Github.
R1k0
8

Existem algumas maneiras diferentes de conseguir o que está pedindo.

1.) Estenda a classe de aplicativo e instancie seu controlador e modele objetos lá.

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;
    }

}

Em seguida, você pode chamar o seu singleton a partir do objeto Application personalizado a qualquer momento:

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.) Você pode fazer com que seu controlador crie apenas uma instância singleton:

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;
    }
}

Então você pode simplesmente chamar o método create a partir de qualquer Atividade ou Fragmento e ele criará um novo controlador se ainda não existir, caso contrário, ele retornará o controlador preexistente.

3.) Finalmente, existe uma estrutura elegante criada na Square que fornece injeção de dependência no Android. É chamado Dagger . Não vou falar sobre como usá-lo aqui, mas é muito bom se você precisar desse tipo de coisa.

Espero ter dado detalhes suficientes sobre como você pode fazer o que está esperando.

Dan Mikita
fonte
6

Tente assim:

Crie uma classe de dados compartilhada:

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;
    }



}

Declarou / Inicia uma instância da classe globalmente nas classes em que você deseja definir / obter dados (usando este código antes do onCreate()método): -

Globals sharedData = Globals.getInstance();

Definir dados:

sharedData.setValue("kundan");

Obter dados:

String n = sharedData.getValue();
kumar kundan
fonte
4

Você pode criar um Global Classcomo este:

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;
    }
}

Em seguida, defina-o no manifesto:

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

Agora você pode definir valores para a variável global como esta:

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

Você pode obter esses valores assim:

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

Por favor, encontre um exemplo completo deste blog Global Variables

san88
fonte
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;
mahasam
fonte
1
Por que você está postando duas respostas na mesma pergunta? Você pode editá-lo para um.
Kunu 8/15
2

Procurei respostas semelhantes, mas as que foram fornecidas aqui não atendem às minhas necessidades. Encontro algo que, do meu ponto de vista, é o que você está procurando. O único ponto preto possível é uma questão de segurança (ou talvez não), já que eu não sei sobre segurança.

Sugiro usar Interface (não é necessário usar Class com construtor e assim ...), pois você só precisa criar algo como:

public interface ActivityClass {

    public static final String MYSTRING_1 = "STRING";

    public static final int MYINT_1 = 1;

}

Em seguida, você pode acessar todos os lugares das suas aulas usando o seguinte:

int myInt = ActivityClass.MYINT_1;
String myString = ActivityClass.MYSTRING_1;
Alexandre
fonte
1

Tecnicamente, isso não responde à pergunta, mas eu recomendaria usar o banco de dados Room em vez de qualquer variável global. https://developer.android.com/topic/libraries/architecture/room.html Mesmo se você estiver 'apenas' precisando armazenar uma variável global e isso não é grande coisa e não, mas usar o banco de dados da sala é o mais elegante , maneira nativa e bem suportada de manter valores em torno do ciclo de vida da atividade. Isso ajudará a evitar muitos problemas, especialmente a integridade dos dados. Entendo que o banco de dados e a variável global são diferentes, mas use o Room para manter a manutenção do código, a estabilidade do aplicativo e a integridade dos dados.

hexágono
fonte
1

Use SharedPreferences para armazenar e recuperar variáveis ​​globais.

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

Se possível, você deve declarar as variáveis ​​que precisa manter ativas que não foram limpas pelo Garbage Collector ou Descarregar pelo OS no arquivo .so Para fazer isso, você deve codificar por C / C ++ e compilar no arquivo .so lib e carregue-o na sua MainActivity.

Tran Huu Phuoc
fonte
1
O código nativo é uma maneira dolorosa de armazenar dados na RAM e não o faz melhor do que as staticvariáveis Java .
Jerry101
Não vejo o objetivo dessa abordagem. Você pode elaborar, caso em que é uma boa ideia?
Muta2
-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;
    }
}
user2054528
fonte
-5

Fácil!!!!

As variáveis ​​que você deseja acessar como variável global, podem declará-las como variáveis ​​estáticas. E agora, você pode acessar essas variáveis ​​usando

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;

É isso aí! ;)

Dinesh Padwal
fonte
não tenho certeza por que isso foi tão votado; comparando com algumas outras respostas votadas pela rede, vejo que isso corretamente (iirc) usa synchronizedna estática, getInstance()enquanto outras não. votado de acordo.
user2297550