Biến toàn cầu Android


293

Làm cách nào tôi có thể tạo biến toàn cục giữ các giá trị xung quanh vòng đời của ứng dụng bất kể hoạt động nào đang chạy.


Và tại sao chúng ta nên sử dụng set và get (asnwer của Jeff Gilfelt)?! Tại sao chúng ta chỉ đặt giá trị trực tiếp cho biến? như thế này: chuỗi tĩnh dễ bay hơi công khai x; và để đặt giá trị: GeneralClass.x = value;
Dr.jacky

Câu trả lời:


531

Bạn có thể mở rộng android.app.Applicationlớp cơ sở và thêm các biến thành viên như vậy:

public class MyApplication extends Application {

    private String someVariable;

    public String getSomeVariable() {
        return someVariable;
    }

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

Trong tệp kê khai Android của bạn, bạn phải khai báo lớp triển khai android.app.Application (thêm android:name=".MyApplication"thuộc tính vào thẻ ứng dụng hiện có):

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

Sau đó, trong các hoạt động của bạn, bạn có thể nhận và đặt biến như vậy:

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

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

4
giúp đỡ tuyệt vời, tôi thực sự áp dụng.
d-man

6
Thật không may, nó không làm việc cho tôi. Vui lòng xác nhận rằng sau này chúng tôi sẽ có hai thẻ <application> trong bảng kê khai. Đúng? Bởi vì tại một số nơi tôi nghe người ta nói rằng chúng ta phải thêm cái này vào thẻ ứng dụng hiện có. Xin vui lòng giúp đỡ !!
Adil Malik

9
@AdilMalik Bạn phải thêm thẻ android: name vào thẻ ứng dụng hiện có
Marijn

2
Tại sao không chỉ tạo một lớp với các trường tĩnh công khai mà không cần truy cập vào một bối cảnh?
Laserson

50
Đây không phải là câu trả lời chính xác vì nó có thể dẫn đến hành vi không dự đoán được và NPE do dọn dẹp bộ nhớ. developerphil.com/dont-store-data-in-the-application-object
bakua

43

Bạn có thể sử dụng Singleton Patternnhư thế này:

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

Trong ứng dụng của bạn, bạn có thể truy cập singleton của mình theo cách này:

MyProperties.getInstance().someValueIWantToKeep

28
Điều gì sẽ xảy ra nếu hoạt động tạm dừng và người dùng bắt đầu một ứng dụng khác và trong thời gian đó, đó là lý do tại sao Android loại bỏ đối tượng tĩnh này khi người dùng tiếp tục ứng dụng và tìm thấy tham chiếu tĩnh này null ???
d-man

4
Một tĩnh là vô dụng trên các hoạt động trong các quy trình riêng biệt.
ateiob

3
điều này sẽ không hoạt động nếu cá thể của bạn là rác được thu thập. vì vậy khối mã if (null == mInstance) {mInstance = new MyProperIES (); } sẽ hoạt động và phiên bản mới sẽ được trả về, sẽ thiết lập lại các thuộc tính
Lalith B

1
@ Mr.Hyde Singleton không vô dụng, chỉ là chúng ta cần biết những gì cần giữ bên trong Singleton, Nếu chúng ta giữ các mảng bitmap lớn hoặc một số bộ sưu tập thì nó có thể trở nên nguy hiểm. Ghi lại những gì bạn giữ trong Singleton.
Lalith B

1
Tôi biết tôi đến hơi muộn nhưng đối với những độc giả tương lai, chúng tôi có thể lưu trữ các giá trị trong SharedPreferences, Cơ sở dữ liệu SQLLite hoặc tệp Bộ nhớ trong. Tất cả những thứ này sẽ có dữ liệu bền bỉ ngay cả khi ứng dụng bị đóng.
powernit

15

Biến toàn cầu này hoạt động cho dự án của tôi:

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
Nhưng sau đó, làm thế nào để bạn vượt qua nó cho nhiều hoạt động?
Zapnologica

15
Các thống kê này (ít nhất là chuỗi và mảng) có thể bị vô hiệu hóa bởi máy ảo Android khi ứng dụng bị treo và thiết bị có bộ nhớ thấp.
Anton

4
@mahasam Tôi không nghĩ tĩnh nên là cách đúng đắn ... nếu hoạt động duy nhất của nó, thì nó phải thông qua ngữ cảnh Ứng dụng. Khác một cách đơn lẻ như được đưa ra trong các câu trả lời khác ở trên. static sẽ kết hợp mã một cách mạnh mẽ và cũng làm giảm khả năng kiểm tra
Punith Raj

14

Bạn có thể sử dụng tùy chọn ứng dụng. Chúng có thể truy cập được từ bất kỳ hoạt động hoặc đoạn mã nào miễn là bạn truyền vào đối tượng Ngữ cảnh và chúng là riêng tư đối với ứng dụng sử dụng chúng, vì vậy bạn không cần lo lắng về việc phơi bày các giá trị cụ thể của ứng dụng, trừ khi bạn xử lý các định tuyến thiết bị. Thậm chí, bạn có thể sử dụng các lược đồ băm hoặc mã hóa để lưu các giá trị. Ngoài ra, các tùy chọn này được lưu trữ từ một ứng dụng chạy tiếp theo. Dưới đây là một số ví dụ mã mà bạn có thể xem xét.


Tôi đã cập nhật liên kết. Dự án đã được lưu trữ trên Google Code và như chúng tôi biết đã bị đóng cửa. Liên kết là từ Github.
r1k0

8

Có một vài cách khác nhau bạn có thể đạt được những gì bạn đang yêu cầu.

1.) Mở rộng lớp ứng dụng và khởi tạo bộ điều khiển và các đối tượng mô hình của bạn ở đó.

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

}

Sau đó, bạn có thể gọi singleton từ đối tượng Ứng dụng tùy chỉnh của mình bất cứ lúc nào:

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.) Bạn có thể có bộ điều khiển của mình chỉ cần tạo một cá thể đơn lẻ của chính nó:

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

Sau đó, bạn chỉ có thể gọi phương thức tạo từ bất kỳ Activity hoặc Fragment nào và nó sẽ tạo một bộ điều khiển mới nếu nó chưa tồn tại, nếu không nó sẽ trả về bộ điều khiển có sẵn.

3.) Cuối cùng, có một khung khéo léo được tạo ra tại Square cung cấp cho bạn nội dung phụ thuộc vào Android. Nó được gọi là Dao găm . Tôi sẽ không đi vào làm thế nào để sử dụng nó ở đây, nhưng sẽ rất trơn tru nếu bạn cần loại đó.

Tôi hy vọng tôi đã cung cấp đủ chi tiết liên quan đến cách bạn có thể làm những gì bạn đang hy vọng.


6

Hãy thử như thế này:

Tạo một lớp dữ liệu chia sẻ:

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



}

Khai báo / Khởi tạo một thể hiện của lớp trên toàn cầu trong các lớp mà bạn muốn đặt / nhận dữ liệu (sử dụng mã này trước onCreate()phương thức): -

Globals sharedData = Globals.getInstance();

Đặt dữ liệu:

sharedData.setValue("kundan");

Lấy dữ liệu:

String n = sharedData.getValue();

4

Bạn có thể tạo Global Classnhư thế này:

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

Sau đó xác định nó trong tệp kê khai:

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

Bây giờ bạn có thể đặt giá trị cho biến toàn cục như thế này:

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

Bạn có thể nhận được những giá trị như thế này:

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

Vui lòng tìm ví dụ đầy đủ từ blog này Biến toàn cầu


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
Tại sao bạn đang đăng hai câu trả lời trong cùng một câu hỏi? Bạn có thể chỉnh sửa nó thành một.
Kunu

2

Tôi đã kiểm tra câu trả lời tương tự, nhưng những câu được đưa ra ở đây không phù hợp với nhu cầu của tôi. Tôi tìm thấy một cái gì đó, theo quan điểm của tôi, là những gì bạn đang tìm kiếm. Điểm đen duy nhất có thể là vấn đề bảo mật (hoặc có thể không) vì tôi không biết về bảo mật.

Tôi đề nghị sử dụng Giao diện (không cần sử dụng Class với hàm tạo và vì vậy ...), vì bạn chỉ phải tạo một cái gì đó như:

public interface ActivityClass {

    public static final String MYSTRING_1 = "STRING";

    public static final int MYINT_1 = 1;

}

Sau đó, bạn có thể truy cập mọi nơi trong các lớp học của mình bằng cách sử dụng như sau:

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

1

Về mặt kỹ thuật, điều này không trả lời câu hỏi, nhưng tôi khuyên bạn nên sử dụng cơ sở dữ liệu Room thay vì bất kỳ biến toàn cục nào. https://developer.android.com/topic/lologists/arch architecture / room.html Ngay cả khi bạn 'chỉ' cần lưu trữ một biến toàn cục và nó không phải là vấn đề lớn và không, nhưng sử dụng cơ sở dữ liệu Room là thanh lịch nhất , cách bản địa và được hỗ trợ tốt để giữ các giá trị xung quanh vòng đời của hoạt động. Nó sẽ giúp ngăn ngừa nhiều vấn đề, đặc biệt là tính toàn vẹn của dữ liệu. Tôi hiểu rằng cơ sở dữ liệu và biến toàn cục là khác nhau nhưng vui lòng sử dụng Room vì mục đích bảo trì mã, tính ổn định của ứng dụng và tính toàn vẹn dữ liệu.


1

Sử dụng SharedPreferences để lưu trữ và truy xuất các biến toàn cục.

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

0

Nếu có thể, bạn nên khai báo các biến mà bạn cần để duy trì sự sống chưa được Garbage Collector hoặc Unload by OS trong tệp .so thực hiện, bạn phải mã hóa bằng C / C ++ và biên dịch thành tệp .so lib và tải nó trong MainActivity của bạn.


1
Mã riêng là một cách đau đớn để giữ dữ liệu trong RAM và làm như vậy không tốt hơn các staticbiến Java .
Jerry101

Tôi không thấy quan điểm của phương pháp này. Bạn có thể giải thích trong trường hợp này là một ý tưởng tốt?
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;
    }
}

-5

Dễ dàng!!!!

Những biến bạn muốn truy cập là biến toàn cục, bạn có thể khai báo chúng là biến tĩnh. Và bây giờ, bạn có thể truy cập các biến đó bằng cách sử dụng

tên lớp.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;

Đó là nó! ;)


không chắc chắn tại sao nó bị hạ cấp quá nhiều; so sánh với một số câu trả lời nâng cấp mạng khác tôi thấy rằng điều này (iirc) chính xác sử dụng synchronizedtrên tĩnh getInstance()trong khi những câu trả lời khác thì không. nâng cao tương ứng.
dùng2297550
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.