안드로이드 전역 변수


293

전역 변수 유지를 작성하는 방법은 실행중인 활동에 관계없이 응용 프로그램의 수명주기 동안 값을 유지합니다.


그리고 왜 set and get을 사용해야합니까 (Jeff Gilfelt 's asnwer) ?! 왜 값을 직접 변수로 설정합니까? 이와 같이 : public volatile static String x; 그리고 값을 설정하려면 : GeneralClass.x = value;
Dr.jacky 2016

답변:


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.app.Application을 구현하는 클래스를 선언해야합니다 ( android:name=".MyApplication"기존 애플리케이션 태그에 속성 추가 ).

<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

6
불행히도 그것은 나를 위해 작동하지 않습니다. 이 후에 매니페스트에 두 개의 <application> 태그가 있는지 확인하십시오. 권리? 어떤 곳에서는 사람들이 이것을 기존 애플리케이션 태그에 추가해야한다는 말을 들었습니다. 도와주세요 !!
Adil Malik

9
@AdilMalik 기존 애플리케이션 태그에 android : name 태그를 추가해야합니다.
Marijn

2
컨텍스트에 액세스 할 필요없이 공개 정적 필드로 클래스를 작성하는 것이 어떻습니까?
Laserson

50
메모리 정리로 인해 예기치 않은 동작과 NPE가 발생할 수 있으므로 정답이 아니어야합니다. developerphil.com/dont-store-data-in-the-application-object
bakua

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

3
인스턴스가 가비지 수집되면 작동하지 않습니다. 따라서 코드 블록 if (null == mInstance) {mInstance = new MyProperties (); }가 작동하고 새 인스턴스가 반환되어 속성이 재설정됩니다.
Lalith B

1
@ Mr.Hyde Singleton은 우리가 Singleton 내부에 무엇을 보관해야하는지 알아야한다는 것만으로는 쓸모가 없습니다. 거대한 비트 맵 배열 또는 일부 컬렉션을 유지하면 위험 할 수 있습니다. 싱글 톤 안에 보관하는 내용을 기록해 두십시오.
Lalith B

1
나는 조금 늦었지만 장래 독자들을 위해 SharedPreferences, SQLLite Database 또는 Internal memory 파일에 값을 저장할 수 있다는 것을 알고 있습니다. 응용 프로그램을 닫아도 데이터 지속성이 유지됩니다.
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에서 이러한 정적 요소 (최소한 문자열 및 배열)가 무효화 될 수 있습니다.
Anton

4
@mahasam 정적이 올바른 방법이어야한다고 생각하지 않습니다 ... 유일한 활동이라면 응용 프로그램 컨텍스트를 통해야합니다. 위의 다른 답변에서 주어진 단일 방법. static은 코드를 강력하게 결합하고 테스트 가능성을 감소시킵니다.
Punith Raj

14

응용 프로그램 환경 설정을 사용할 수 있습니다. Context 객체를 전달하는 한 모든 액티비티 또는 코드에서 액세스 할 수 있으며이를 사용하는 애플리케이션 전용이므로 라우팅을 처리하지 않는 한 애플리케이션 특정 값 노출에 대해 걱정할 필요가 없습니다. 장치. 그럼에도 불구하고 해싱 또는 암호화 체계를 사용하여 값을 저장할 수 있습니다. 또한 이러한 기본 설정은 응용 프로그램 실행에서 다음 실행으로 저장됩니다. 다음 은 살펴볼 수있는 코드 예제입니다.


링크를 업데이트했습니다. 프로젝트는 Google 코드에서 호스팅되었으며 종료 된 것으로 알고 있습니다. 링크는 Github에서 온 것입니다.
r1k0

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

그런 다음 모든 액티비티 또는 프래그먼트에서 create 메소드를 호출하면 새 컨트롤러가 존재하지 않으면 새 컨트롤러를 작성하고 그렇지 않으면 기존 컨트롤러를 리턴합니다.

3.) 마지막으로 Square에서 매끄러운 프레임 워크가 생성되어 Android 내에서 종속성 주입을 제공합니다. Dagger 라고 합니다. 여기서 사용하는 방법에 대해서는 다루지 않겠지 만, 그런 종류의 것이 필요하다면 매우 매끄 럽습니다.

나는 당신이 원하는 것을 어떻게 할 수 있는지에 관해 충분히 자세하게 설명하기를 바랍니다.


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();

이 블로그에서 전체 예제를 찾으십시오. Global Variables


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
같은 질문에 두 개의 답변을 올리는 이유는 무엇입니까? 하나로 편집 할 수 있습니다.
Kunu

2

비슷한 답변을 확인했지만 여기에 제공된 답변이 필요에 맞지 않습니다. 내 관점에서, 당신이 찾고있는 것을 발견합니다. 유일하게 가능한 블랙 포인트는 보안에 대해 모르기 때문에 보안 문제입니다.

인터페이스를 사용하는 것이 좋습니다 (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

가급적 가비지 콜렉터 또는 OS에서 언로드하여 파일에서 명확하지 않은 변수를 선언해야합니다. 그렇게하려면 C / C ++로 코딩하고 .so lib 파일로 컴파일해야합니다. MainActivity에로드하십시오.


1
네이티브 코드는 RAM에 데이터를 저장하는 고통스러운 방법이며 Java static변수 보다 낫습니다 .
Jerry101

나는이 접근법의 요점을 보지 못합니다. 어떤 경우에 이것이 좋은 생각인지 자세히 설명 할 수 있습니까?
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

쉬운!!!!

전역 변수로 액세스하려는 변수를 정적 변수로 선언 할 수 있습니다. 이제는 다음을 사용하여 해당 변수에 액세스 할 수 있습니다.

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;

그게 다야! ;)


왜 그렇게 많이 다운 피트되었는지 확실하지 않습니다. 다른 net-upvoted 답변과 비교하면이 (iirc)가 synchronized정적으로 사용 getInstance()되는 반면 다른 사람들은 그렇지 않습니다. 그에 따라 upvoted.
user2297550
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.