Variabel global Android

293

Bagaimana saya bisa membuat variabel global menjaga nilai tetap di sekitar siklus hidup aplikasi terlepas dari aktivitas yang berjalan.

b-man
sumber
Dan mengapa kita harus menggunakan set dan dapatkan (asnwer Jeff Gilfelt) ?! Mengapa kami hanya menetapkan nilai langsung ke variabel? seperti ini: public String x volatile statis; dan untuk menetapkan nilai: GeneralClass.x = nilai;
Dr.jacky

Jawaban:

531

Anda dapat memperluas android.app.Applicationkelas dasar dan menambahkan variabel anggota seperti:

public class MyApplication extends Application {

    private String someVariable;

    public String getSomeVariable() {
        return someVariable;
    }

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

Di manifes Android Anda, Anda harus mendeklarasikan kelas yang menerapkan android.app.Application (tambahkan android:name=".MyApplication"atribut ke tag aplikasi yang ada):

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

Kemudian dalam aktivitas Anda, Anda bisa mendapatkan dan mengatur variabel seperti:

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

// get
String s = ((MyApplication) this.getApplication()).getSomeVariable();
Jeff Gilfelt
sumber
4
bantuan luar biasa, saya benar-benar melamar.
d-man
6
Sayangnya itu tidak bekerja untuk saya. Harap konfirmasi bahwa setelah ini kami akan memiliki dua tag <aplikasi> dalam manifes. Baik? Karena di beberapa tempat saya mendengar orang mengatakan bahwa kami harus menambahkan ini ke tag aplikasi yang ada. Tolong bantu !!
Adil Malik
9
@AdilMalik Anda harus menambahkan android: tag nama ke tag aplikasi yang ada
Marijn
2
Mengapa tidak membuat kelas dengan bidang statis publik tanpa perlu mengakses konteks?
Laserson
51
Ini seharusnya bukan jawaban yang benar karena dapat menyebabkan perilaku yang tidak terduga dan NPE karena pembersihan memori. developerphil.com/dont-store-data-in-the-application-object
bakua
43

Anda dapat menggunakan Singleton Patternseperti ini:

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

Dalam aplikasi Anda, Anda dapat mengakses singleton Anda dengan cara ini:

MyProperties.getInstance().someValueIWantToKeep
Landai
sumber
28
Bagaimana jika aktivitas berhenti dan pengguna memulai aplikasi lain dan selama memeory itu rendah itu sebabnya android menghapus objek statis ini ketika pengguna melanjutkan aplikasi dan menemukan referensi statis ini null ???
d-man
4
Statis tidak berguna di seluruh aktivitas dalam proses terpisah.
ateiob
3
ini tidak akan berfungsi jika instance Anda adalah sampah yang dikumpulkan. jadi blok kode if (null == mInstance) {mInstance = new MyProperties (); } akan berfungsi dan instance baru akan dikembalikan, yang akan mengatur ulang properti
Lalith B
1
@ Mr.Hyde Singleton tidak sia-sia, hanya saja kita perlu tahu apa yang harus disimpan di dalam Singleton, Jika kita menyimpan array bitmap besar atau beberapa koleksi, maka itu bisa menjadi berbahaya. Catat apa yang Anda simpan di dalam Singleton.
Lalith B
1
Saya tahu saya agak terlambat tetapi untuk pembaca di masa mendatang, kami dapat menyimpan nilai dalam SharedPreferences, Database SQLLite, atau file memori Internal. Ini semua akan memiliki kegigihan data bahkan jika aplikasi ditutup.
powernit
15

Variabel global ini berfungsi untuk proyek saya:

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
sumber
2
Namun, bagaimana Anda meneruskannya ke beberapa aktivitas?
Zapnologica
15
Statika ini (setidaknya string dan array) dapat dibatalkan oleh VM Android saat aplikasi ditangguhkan dan perangkat memiliki memori rendah.
Anton
4
@mahasam saya tidak berpikir statis harus menjadi cara yang benar ... jika hanya kegiatannya, itu harus melalui konteks Aplikasi. Cara lain seperti yang diberikan dalam jawaban lain di atas. statis akan sangat pasangan kode, dan juga mengurangi testability
Punith Raj
14

Anda dapat menggunakan preferensi aplikasi. Mereka dapat diakses dari aktivitas atau bagian kode apa pun selama Anda meneruskan objek Konteks, dan mereka pribadi untuk aplikasi yang menggunakannya, jadi Anda tidak perlu khawatir tentang mengekspos nilai-nilai spesifik aplikasi, kecuali jika Anda berurusan dengan dialihkan perangkat. Meski begitu, Anda bisa menggunakan skema hashing atau enkripsi untuk menyimpan nilai. Juga, preferensi ini disimpan dari aplikasi yang dijalankan ke yang berikutnya. Berikut adalah beberapa contoh kode yang dapat Anda lihat.

r1k0
sumber
Saya telah memperbarui tautannya. Project dihosting di Google Code dan seperti yang kita tahu sudah ditutup. Tautan berasal dari Github.
r1k0
8

Ada beberapa cara berbeda untuk mencapai apa yang Anda minta.

1.) Perpanjang kelas aplikasi dan instantiate controller Anda dan objek model di sana.

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

}

Kemudian Anda dapat memanggil singleton Anda dari objek Aplikasi kustom Anda kapan saja:

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.) Anda dapat membuat controller Anda cukup membuat instance singleton itu sendiri:

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

Kemudian Anda bisa memanggil metode create dari Activity atau Fragment apa saja dan itu akan membuat controller baru jika belum ada, jika tidak maka akan mengembalikan controller yang sudah ada sebelumnya.

3.) Akhirnya, ada kerangka kerja apik yang dibuat di Square yang memberikan Anda injeksi ketergantungan dalam Android. Itu disebut belati . Saya tidak akan membahas cara menggunakannya di sini, tetapi sangat apik jika Anda memerlukan hal semacam itu.

Saya harap saya memberikan detail yang cukup tentang bagaimana Anda dapat melakukan apa yang Anda harapkan.

Dan Mikita
sumber
6

Coba Seperti Ini:

Buat kelas data bersama:

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



}

Menyatakan / menginisiasi instance kelas secara global di kelas-kelas tempat Anda ingin mengatur / mendapatkan data (menggunakan kode ini sebelum onCreate()metode): -

Globals sharedData = Globals.getInstance();

Setel data:

sharedData.setValue("kundan");

Dapatkan data:

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

Anda dapat membuat yang Global Classseperti ini:

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

Kemudian definisikan dalam manifes:

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

Sekarang Anda dapat mengatur nilai ke variabel global seperti ini:

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

Anda bisa mendapatkan nilai-nilai seperti ini:

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

Silakan temukan contoh lengkap dari blog Global Variables ini

san88
sumber
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
sumber
1
Mengapa Anda memposting dua jawaban dalam pertanyaan yang sama? Anda dapat mengeditnya menjadi satu.
Kunu
2

Saya memeriksa jawaban yang sama, tetapi yang diberikan di sini tidak sesuai dengan kebutuhan saya. Saya menemukan sesuatu yang, dari sudut pandang saya, adalah apa yang Anda cari. Satu-satunya titik hitam yang mungkin adalah masalah keamanan (atau mungkin tidak) karena saya tidak tahu tentang keamanan.

Saya sarankan menggunakan Antarmuka (tidak perlu menggunakan Kelas dengan konstruktor dan sebagainya ...), karena Anda hanya perlu membuat sesuatu seperti:

public interface ActivityClass {

    public static final String MYSTRING_1 = "STRING";

    public static final int MYINT_1 = 1;

}

Kemudian Anda dapat mengakses di mana saja di dalam kelas Anda dengan menggunakan yang berikut:

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

Secara teknis ini tidak menjawab pertanyaan, tetapi saya akan merekomendasikan menggunakan database Room daripada variabel global. https://developer.android.com/topic/libraries/architecture/room.html Bahkan jika Anda 'hanya' perlu menyimpan variabel global dan itu bukan masalah besar dan apa yang tidak, tetapi menggunakan database Room adalah yang paling elegan , cara yang asli dan didukung dengan baik untuk menjaga nilai-nilai di sekitar siklus hidup kegiatan. Ini akan membantu mencegah banyak masalah, terutama integritas data. Saya mengerti bahwa basis data dan variabel global berbeda tetapi tolong gunakan Kamar demi pemeliharaan kode, stabilitas aplikasi dan integritas data.

heksikel
sumber
1

Gunakan SharedPreferences untuk menyimpan dan mengambil variabel global.

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

Jika memungkinkan, Anda harus mendeklarasikan variabel yang Anda perlukan agar tetap hidup yang belum dihapus oleh Garbage Collector atau Unload by OS dalam file .so Untuk melakukannya, Anda harus kode dengan C / C ++ dan mengkompilasi ke file .so lib dan muat di MainActivity Anda.

Tran Huu Phuoc
sumber
1
Kode asli adalah cara menyakitkan untuk menyimpan data dalam RAM, dan melakukannya tidak lebih baik dari staticvariabel Java .
Jerry101
Saya tidak melihat inti dari pendekatan ini. Bisakah Anda menguraikan dalam hal ini ide yang bagus?
miva2
-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;
    }
}
pengguna2054528
sumber
-5

Mudah!!!!

Variabel yang ingin Anda akses sebagai variabel global, Anda dapat mendeklarasikannya sebagai variabel statis. Dan sekarang, Anda dapat mengakses variabel-variabel itu dengan menggunakan

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;

Itu dia! ;)

Dinesh Padwal
sumber
tidak yakin mengapa itu begitu banyak diturunkan; membandingkan dengan beberapa jawaban net-upvoted saya melihat bahwa ini benar (iirc) menggunakan synchronizedstatis getInstance()sedangkan yang lain tidak. diputuskan sesuai.
user2297550