의도를 사용하여 한 Android 활동에서 다른 활동으로 객체를 보내는 방법은 무엇입니까?


849

Intent 클래스 의 메소드를 사용하여 한 활동 에서 다른 활동 으로 사용자 정의 유형의 객체를 전달하는 putExtra()방법은 무엇입니까?


@UMMA-질문을 "커뮤니티 위키"로 계속 표시 할 필요가 없습니다. 여기 보라 : meta.stackexchange.com/questions/11740/...은
데이브 웹이

1
@Paresh : 제공 한 링크가 손상되었습니다. plz가 대안을 제공 할 수 있습니까?
antiplex


이 답변을 확인하십시오. stackoverflow.com/questions/8857546/…
Heitor Colangelo

나는 간단하고 우아한 방법을 발견했습니다. stackoverflow.com/a/37774966/6456129
Yessy

답변:


751

객체를 그냥지나 가면 Parcelable 이 이것을 위해 설계되었습니다. Java의 기본 직렬화를 사용하는 것보다 사용하는 데 약간의 노력이 필요하지만 더 빠릅니다 (즉, WAY가 빠릅니다).

문서에서 구현 방법에 대한 간단한 예는 다음과 같습니다.

// simple class that just has one member property as an example
public class MyParcelable implements Parcelable {
    private int mData;

    /* everything below here is for implementing Parcelable */

    // 99.9% of the time you can just ignore this
    @Override
    public int describeContents() {
        return 0;
    }

    // write your object's data to the passed-in Parcel
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mData);
    }

    // this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
    public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
        public MyParcelable createFromParcel(Parcel in) {
            return new MyParcelable(in);
        }

        public MyParcelable[] newArray(int size) {
            return new MyParcelable[size];
        }
    };

    // example constructor that takes a Parcel and gives you an object populated with it's values
    private MyParcelable(Parcel in) {
        mData = in.readInt();
    }
}

주어진 소포에서 검색 할 필드가 두 개 이상인 경우 입력 한 순서와 동일한 순서로 (FIFO 방식으로)이 작업을 수행해야합니다.

당신이 당신의 객체를 일단 구현 Parcelable그냥 당신에 넣어의 문제 텐트putExtra () :

Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);

그런 다음 getParcelableExtra ()를 사용하여 다시 가져올 수 있습니다 .

Intent i = getIntent();
MyParcelable myParcelableObject = (MyParcelable) i.getParcelableExtra("name_of_extra");

객체 클래스가 Parcelable 및 Serializable을 구현하는 경우 다음 중 하나에 캐스트해야합니다.

i.putExtra("parcelable_extra", (Parcelable) myParcelableObject);
i.putExtra("serializable_extra", (Serializable) myParcelableObject);

14
mData가 객체 (예 : JSONObject)이고 int가 아닌 경우 어떻게 구현됩니까?
피터 아지 타이

301
이 모든 것이 없으면 왜 객체를 전달할 수 없습니까? 이미 메모리에있는 객체를 전달하려고합니다.
ceklock

110
@tecnotron의 beacuse 앱은 다른 프로세스에 있으며 별도의 메모리 주소 공간이 있으므로 프로세스의 메모리 블록에 포인터 (참조)를 보내고 다른 프로세스에서 사용할 수있을 것으로 기대할 수 없습니다.
marcinj 2016 년

12
객체의 클래스를 직렬화 또는 구문 분석 할 수 없으면 어떻게해야합니까?
Amel Jose

11
@ceklock 그 이유는 다음과 같습니다. 활동이 메모리에서 뒤이어 나중에 종료되면 사용자가 최근 메뉴에서 액티비티를 열면 중단 된 위치에 활동을 작성해야합니다. 동일한 UI 여야합니다. 이 경우 오브젝트가 메모리에 없습니다. 그러나 의도는.
tasomaniac

194

객체를 일종의 문자열 표현으로 직렬화해야합니다. 가능한 문자열 표현 중 하나는 JSON이며 Android에서 JSON으로 직렬화하는 가장 쉬운 방법 중 하나는 Google GSON 입니다.

이 경우 문자열 반환 값을 입력하고 문자열 값을 (new Gson()).toJson(myObject);검색 fromJson하여 객체로 다시 변환 하는 데 사용 합니다.

그러나 객체가 매우 복잡하지 않은 경우 오버 헤드의 가치가 없으므로 객체의 별도 값을 전달하는 것을 고려할 수 있습니다.


19
fiXedd의 답변이 외부 라이브러리를 사용하지 않고도 동일한 문제를 해결하기 때문에 추측하기는 쉽습니다. fiXedd의 훌륭한 솔루션)
David Hedlund

5
나는 그것이 맞다고 생각합니다. 또한 JSON은 스레드 / 스레드가 아닌 클라이언트 / 서버에 더 적합한 프로토콜입니다.
mobibob

16
반드시 나쁜 생각은 아닙니다. Gson은 보내려는 모든 객체에 대해 소포를 구현하는 것보다 사용하기가 훨씬 간단합니다.
uvesten

7
내 응용 프로그램에서 gson을 사용하는 iam로 이것은 정말 쉽고 좋은 방법입니다!
Lars

16
멋진 대답, 완벽한 솔루션이 될 것이지만 String s = (new Gson().toJson(client));다음과Cli client = new Gson().fromJson(s, Cli.class);
호아킨 Iurchuk

155

의도를 통해 직렬화 가능한 객체를 보낼 수 있습니다

// send where details is object
ClassName details = new ClassName();
Intent i = new Intent(context, EditActivity.class);
i.putExtra("Editing", details);
startActivity(i);


//receive
ClassName model = (ClassName) getIntent().getSerializableExtra("Editing");

And 

Class ClassName implements Serializable {
} 

2
의도를 통해 Parcelable 객체를 보낼 수도 있습니다.
tony gil

6
"Serializable은 안드로이드에서 만화 적으로 느리다. 실제로 경계선은 쓸모가 없다." 봐 stackoverflow.com/questions/5550670/...
세라핌의

활동이 이미 실행중인 경우 startActivity (i)를 수행해야합니까? ? 내 말은, 액티비티 A 호출 액티비티 B를 만들 수 있고 데이터를 액티비티 A로 반환 할 수 있습니까? 혼란스러워?
Francisco Corrales Morales

3
@Seraphim의 성능은 많은 객체를 직렬화하는 경우 중요하지만 한 객체를 직렬화하는 데 1ms 또는 10ms가 걸리는 경우 사용자는 알지 못합니다. 인 텐트 엑스트라가 이미 Serializable있지만 그렇지 않은 경우 Parcelable, 번거롭게 할 가치가 거의 없습니다 Parcelable.
Kevin Krumwiede

67

응용 프로그램 내에서 데이터를 전달할 경우 "전역"(정적 클래스와 같은)을 사용하십시오.

여기에 무엇 다이앤 Hackborn : 문제에 대해 말을했다 - (구글 안드로이드 소프트웨어 엔지니어 hackbod가)

활동이 동일한 프로세스에서 실행 중임을 알고있는 상황에서는 글로벌을 통해 데이터를 공유 할 수 있습니다. 예를 들어, 전역을 가질 HashMap<String, WeakReference<MyInterpreterState>> 수 있고 새로운 MyInterpreterState를 만들 때 고유 한 이름을 만들어 해시 맵에 넣을 수 있습니다. 해당 상태를 다른 활동으로 보내려면 단순히 고유 이름을 해시 맵에 넣고 두 번째 활동이 시작되면 수신 한 이름으로 해시 맵에서 MyInterpreterState를 검색 할 수 있습니다.


25
예, 우리가 이러한 인 텐트를 사용할 수 있다는 것이 이상하다는 것을 알게 된 후 최고 엔지니어가 데이터에 글로벌을 사용하도록 지시합니다. 그러나 그것은 말 입에서 똑바로 있습니다.
Richard Le Mesurier

1
여기서 약한 굴절은 가비지 수집의 희생자가 아닐까요?
uLYsseus

1
@uLYsseus는 그것이 아이디어라고 생각합니다. 일단 당신이 활동에서 그들과 함께 끝나면 ... 관련 활동이 파괴되면 그것을 허용 할 것입니다
Peter Ajtai

1
@RichardLeMesurier 나는 똑같은 생각을했지만 Dianne Hackborn의 위의 Google 그룹스 게시물을 살펴 보았고 암시 적 의도를 사용할 때 실제로 글로벌에서 유일한 문제는 패키지 외부에서 활동을 시작할 수 있다고 언급했습니다. ). Dianne이 언급했듯이 이러한 활동은 전달하는 사용자 정의 유형에 대한 지식이 거의 없기 때문입니다. 내가 그것을 읽은 후, 그것이 왜 글로벌이 그 상황에서 그렇게 나쁜 길이 아닌지 분명하게 해 주었고, 다른 사람들도 호기심이 생길 경우 공유 할 것이라고 생각했습니다.
BMB

의도는 다른 컴퓨터로 전달 될 수있을 정도로 오버 엔지니어링되었습니다. 메모리 사용, CPU 사용, 배터리 사용 등 좋지 않은 이유는 무엇입니까? 마지막 하나는 특히 디자인 선택을 뒷받침에 상당히 당황하게 만들었습니다. 좋은 아이디어라고 주장하는 사람들이 있습니다. 대개 "google이 그렇게 말했기 때문"입니다.
Lassi Kinnunen

49

클래스는 Serializable 또는 Parcelable을 구현해야합니다.

public class MY_CLASS implements Serializable

완료되면 putExtra에서 객체를 보낼 수 있습니다

intent.putExtra("KEY", MY_CLASS_instance);

startActivity(intent);

엑스트라를 얻으려면 당신이해야 할 일

Intent intent = getIntent();
MY_CLASS class = (MY_CLASS) intent.getExtras().getSerializable("KEY");

클래스가 Parcelable을 구현하는 경우 다음을 사용하십시오.

MY_CLASS class = (MY_CLASS) intent.getExtras().getParcelable("KEY");

나는 그것이 도움이되기를 바랍니다 : D


6
클래스 Serializable가 잘못 구현해야합니다 . 클래스는 Parcelable예를 들어 구현할 수 있습니다 .
Marc Plano-Lesay 2013 년

Parcelable과 Serializable @Kernald의 차이점은 무엇입니까? 처리 시간 측면에서 더 느리거나 모범 사례가 아닌 것입니까?
gumuruh

하지만 Serializable표준 자바 인터페이스, Parcelable안드로이드 다릅니다. 성능 측면에서 Parcelable이 더 효율적입니다. developerphil.com/parcelable-vs-serializable
Marc Plano-Lesay

35

빠른 요구에 대한 짧은 답변

1. 클래스를 직렬화 가능하게 구현하십시오.

내부 클래스가 있으면 Serializable에 구현하는 것을 잊지 마십시오!

public class SportsData implements  Serializable
public class Sport implements  Serializable

List<Sport> clickedObj;

2. 당신의 물건을 의도에 두십시오

 Intent intent = new Intent(SportsAct.this, SportSubAct.class);
            intent.putExtra("sport", clickedObj);
            startActivity(intent);

3. 다른 활동 클래스에서 물건을받습니다.

Intent intent = getIntent();
    Sport cust = (Sport) intent.getSerializableExtra("sport");


Parcelable 인터페이스를 구현하여 동일한 것을 달성 할 수 있습니다. Parcelable 인터페이스는 코드 크기 때문에 Serializable에 비해 구현하는 데 더 많은 시간이 걸립니다. 그러나 Serializable보다 빠른 성능을 발휘하고 더 적은 리소스를 사용합니다.
Kwnstantinos Nikoloutsos

27

객체 클래스가를 구현하는 경우 Serializable다른 작업을 수행 할 필요가 없으면 직렬화 가능한 객체를 전달할 수 있습니다.
그것이 내가 사용하는 것입니다.


24

클래스에서 직렬화 가능

public class Place implements Serializable{
        private int id;
        private String name;

        public void setId(int id) {
           this.id = id;
        }
        public int getId() {
           return id;
        }
        public String getName() {
           return name;
        }

        public void setName(String name) {
           this.name = name;
        }
}

그런 다음이 객체를 의도적으로 전달할 수 있습니다

     Intent intent = new Intent(this, SecondAct.class);
     intent.putExtra("PLACE", Place);
     startActivity(intent);

두 번째 활동에서는 다음과 같은 데이터를 얻을 수 있습니다

     Place place= (Place) getIntent().getSerializableExtra("PLACE");

그러나 데이터가 커지면이 방법이 느려집니다.


16

다른 클래스 나 활동에서 변수 나 객체에 액세스 할 수있는 몇 가지 방법이 있습니다.

A. 데이터베이스

B. 공유 환경 설정.

C. 객체 직렬화.

D. 공통 데이터를 보유 할 수있는 클래스는 사용자에 따라 공통 유틸리티로 명명 될 수 있습니다.

E. 의도 및 소포 가능 인터페이스를 통한 데이터 전달.

프로젝트 요구에 따라 다릅니다.

A. 데이터베이스

SQLite는 안드로이드에 내장 된 오픈 소스 데이터베이스입니다. SQLite는 SQL 구문, 트랜잭션 및 준비된 명령문과 같은 표준 관계형 데이터베이스 기능을 지원합니다.

튜토리얼-http: //www.vogella.com/articles/AndroidSQLite/article.html

B. 공유 환경 설정

사용자 이름을 저장한다고 가정하십시오. 이제 Key Username, Value Value 라는 두 가지가 있습니다 .

보관 방법

 // Create object of SharedPreferences.
 SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
 //now get Editor
 SharedPreferences.Editor editor = sharedPref.edit();
 //put your value
 editor.putString("userName", "stackoverlow");

 //commits your edits
 editor.commit();

putString (), putBoolean (), putInt (), putFloat (), putLong ()을 사용하여 원하는 dtatype을 저장할 수 있습니다.

가져 오는 방법

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
String userName = sharedPref.getString("userName", "Not Available");

http://developer.android.com/reference/android/content/SharedPreferences.html

C. 객체 직렬화

객체 상태 화는 객체 상태를 저장하여 네트워크를 통해 보내거나 목적에 맞게 사용할 수있는 경우에 사용됩니다.

Java Bean을 사용하여 필드 중 하나로 저장하고 getter 및 setter를 사용하십시오.

JavaBean은 속성이있는 Java 클래스입니다. 속성을 프라이빗 인스턴스 변수로 생각하십시오. 비공개이기 때문에 클래스 외부에서 액세스 할 수있는 유일한 방법은 클래스의 메서드를 사용하는 것입니다. 속성 값을 변경하는 메서드를 setter 메서드라고하며 속성 값을 검색하는 메서드를 getter 메서드라고합니다.

public class VariableStorage implements Serializable  {

    private String inString ;

    public String getInString() {
        return inString;
    }

    public void setInString(String inString) {
        this.inString = inString;
    }


}

를 사용하여 메일 방법에서 변수를 설정하십시오.

VariableStorage variableStorage = new VariableStorage();
variableStorage.setInString(inString);

그런 다음 객체 직렬화를 사용하여이 객체를 직렬화하고 다른 클래스에서이 객체를 직렬화 해제하십시오.

직렬화에서 객체는 객체의 유형과 객체에 저장된 데이터 유형에 대한 정보뿐만 아니라 객체의 데이터를 포함하는 일련의 바이트로 표현 될 수 있습니다.

직렬화 된 객체가 파일에 기록 된 후에는 파일에서 읽혀지고 역 직렬화 될 수 있습니다. 즉 객체와 해당 데이터를 나타내는 유형 정보 및 바이트를 사용하여 객체를 메모리에 다시 만들 수 있습니다.

이 튜토리얼을 원하면이 링크를 참조하십시오.

http://javawithswaranga.blogspot.in/2011/08/serialization-in-java.html

다른 클래스에서 변수 가져 오기

D. 공통 유틸리티

프로젝트에 자주 필요한 공통 데이터를 포함 할 수있는 스스로 수업을 만들 수 있습니다.

견본

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

E. 의도를 통한 데이터 전달

이 데이터 전달 옵션에 대해서는이 학습서를 참조하십시오.

http://shri.blog.kraya.co.uk/2010/04/26/android-parcel-data-to-pass-between-activities-using-parcelable-classes/


인 텐트를 통해 데이터를 전달하는 방법에 대해서는 (E)에서 언급 한 유용한 자습서입니다.
remrick

16

안드로이드 번들을 사용 하여이 작업을 수행 할 수 있습니다.

다음과 같이 수업에서 번들을 만듭니다.

public Bundle toBundle() {
    Bundle b = new Bundle();
    b.putString("SomeKey", "SomeValue");

    return b;
}

그런 다음이 번들을 INTENT와 함께 전달하십시오. 이제 번들을 전달하여 클래스 객체를 다시 만들 수 있습니다

public CustomClass(Context _context, Bundle b) {
    context = _context;
    classMember = b.getString("SomeKey");
}

이것을 커스텀 클래스에서 선언하고 사용하십시오.


1
직접 소포 가능 구현, IMHO를 선호합니다. 번들은 Parcelable 자체를 구현하므로 직접 구현하는 데 따르는 모든 문제를 피하면서 성능을 향상시킬 수 있습니다. 대신 키-값 쌍을 사용하여 단순한 순서에 의존하는 것보다 훨씬 강력한 데이터를 저장하고 검색 할 수 있습니다.
Risadinha

Parcelable은 나에게 복잡해 보입니다. 위의 대답에서 클래스의 toBundle 메소드를 사용하여 객체를 번들로 변환 한 다음 생성자를 사용하여 번들을 클래스 객체로 변환 할 수 있습니다.
om252345

이 솔루션은 의도를 통해 단일 객체를 전달하는 경우에만 실행 가능합니다.
TheIT

json과 비슷하지만 json은 가볍습니다.
David

검색 할 때 객체가 동일한 객체입니까 아니면 사본입니까?
Markus

15

소포 도움을 주셔서 감사하지만 하나의 선택적 솔루션을 찾았습니다.

 public class getsetclass implements Serializable {
        private int dt = 10;
    //pass any object, drwabale 
        public int getDt() {
            return dt;
        }

        public void setDt(int dt) {
            this.dt = dt;
        }
    }

활동 하나에서

getsetclass d = new getsetclass ();
                d.setDt(50);
                LinkedHashMap<String, Object> obj = new LinkedHashMap<String, Object>();
                obj.put("hashmapkey", d);
            Intent inew = new Intent(SgParceLableSampelActivity.this,
                    ActivityNext.class);
            Bundle b = new Bundle();
            b.putSerializable("bundleobj", obj);
            inew.putExtras(b);
            startActivity(inew);

활동 2에서 데이터 가져 오기

 try {  setContentView(R.layout.main);
            Bundle bn = new Bundle();
            bn = getIntent().getExtras();
            HashMap<String, Object> getobj = new HashMap<String, Object>();
            getobj = (HashMap<String, Object>) bn.getSerializable("bundleobj");
            getsetclass  d = (getsetclass) getobj.get("hashmapkey");
        } catch (Exception e) {
            Log.e("Err", e.getMessage());
        }

1
좋은 답변이지만 코딩 표준을 높이십시오 ... 경쟁에서 Serializable을 가져 오지만 +1이지만 Parcellables는 훨씬 빠릅니다 ...
Amit

13

강력하고 간단한 API와 함께 Gson을 사용하여 활동간에 객체를 보냅니다.

// This is the object to be sent, can be any object
public class AndroidPacket {

    public String CustomerName;

   //constructor
   public AndroidPacket(String cName){
       CustomerName = cName;
   }   
   // other fields ....


    // You can add those functions as LiveTemplate !
    public String toJson() {
        Gson gson = new Gson();
        return gson.toJson(this);
    }

    public static AndroidPacket fromJson(String json) {
        Gson gson = new Gson();
        return gson.fromJson(json, AndroidPacket.class);
    }
}

보내려는 객체에 추가하는 2 개의 기능

용법

A에서 B로 객체 보내기

    // Convert the object to string using Gson
    AndroidPacket androidPacket = new AndroidPacket("Ahmad");
    String objAsJson = androidPacket.toJson();

    Intent intent = new Intent(A.this, B.class);
    intent.putExtra("my_obj", objAsJson);
    startActivity(intent);

B로 받기

@Override
protected void onCreate(Bundle savedInstanceState) {        
    Bundle bundle = getIntent().getExtras();
    String objAsJson = bundle.getString("my_obj");
    AndroidPacket androidPacket = AndroidPacket.fromJson(objAsJson);

    // Here you can use your Object
    Log.d("Gson", androidPacket.CustomerName);
}

나는 거의 모든 프로젝트에서 사용하며 성능 문제가 없습니다.


고마워요, 이로 인해 시간이 많이 걸리지 않았습니다.
Hristo Stoyanov

10

나는 같은 문제로 어려움을 겪었다. 정적 클래스를 사용하여 원하는 데이터를 HashMap에 저장하여 해결했습니다. 맨 위에 onCreates onCreates 메소드를 재정의 한 표준 Activity 클래스의 확장을 사용하여 데이터 전송 및 데이터 지우기를 숨 깁니다. 방향 처리와 같은 일부 우스운 설정을 변경해야합니다.

주석 : 다른 활동에 전달 될 일반 객체를 제공하지 않으면 엉덩이가 아프다. 무릎을 꿇고 100 미터를 이기길 바라고 있습니다. "Parcable"은 충분한 대체물이 아닙니다. 새롭고 새로운 레이어를 소개하고 싶지 않기 때문에 기술이없는 API에이 인터페이스를 구현하고 싶지 않습니다. 어떻게 할 수 있습니까? 현대 패러다임 ...


9

첫 번째 활동에서 :

intent.putExtra("myTag", yourObject);

그리고 두 번째로 :

myCustomObject myObject = (myCustomObject) getIntent().getSerializableExtra("myTag");

사용자 정의 객체를 직렬화 가능하게 만드는 것을 잊지 마십시오.

public class myCustomObject implements Serializable {
...
}

소포 가능은 Serializable보다 낫습니다! Android 코드에서 Serializable을 사용하지 마십시오!
Filipe Brito

7

이를 수행하는 또 다른 방법은 Application객체 (android.app.Application) 를 사용하는 것 입니다. AndroidManifest.xml파일 에서 이것을 다음과 같이 정의하십시오 .

<application
    android:name=".MyApplication"
    ...

그런 다음 모든 활동에서 이것을 호출하고 객체를 Application클래스에 저장할 수 있습니다 .

FirstActivity에서 :

MyObject myObject = new MyObject();
MyApplication app = (MyApplication) getApplication();
app.setMyObject(myObject);

SecondActivity에서 다음을 수행하십시오.

MyApplication app = (MyApplication) getApplication();
MyObject retrievedObject = app.getMyObject(myObject);

응용 프로그램 수준 범위를 가진 개체가있는 경우, 즉 응용 프로그램 전체에서 사용해야하는 경우에 유용합니다. Parcelable당신이 범위가 제한되는 경우, 또는 객체의 범위를 통해 명시 적으로 제어하려면 방법은 더 나은 아직도있다.

Intents그래도 사용하지 마십시오 . 그들이 당신에게 적합한 지 모르겠습니다. 내가 이것을 사용한 또 다른 방법 int은 객체의 식별자가 인 텐트를 통해 보내고 객체의 맵에있는 Application객체를 검색하는 것 입니다.


1
이 객체가 변수가 될 수 있기 때문에, 앱의 수명주기에 따라 정적 객체에 대해 이야기하면 당신이 작동 할 수 있지만 몇 번 우리가 또는 있도록 웹 서비스를 사용하여 생성 할 수 있습니다 개체를 passiing 필요가 일을 할 수있는 권리 방법이 아니다 stackoverflow.com / a / 2736612 / 716865
Muhannad A.Alhariri

Map식별자를 사용하여 객체를 저장하고 검색 하는 응용 프로그램 범위를 가져와 웹 서비스에서 생성 된 객체와 함께 성공적으로 사용했습니다 . 이 접근법의 유일한 실제 문제는 안드로이드가 잠시 후에 메모리를 지우므로 onResume에서 null을 확인해야한다는 것입니다 (의도에 전달 된 객체는 유지되지만 확실하지는 않습니다). 그 외에도 나는 이것이 상당히 열등한 것으로 보지 않습니다.
Saad Farooq

이것이 가장 좋은 대답입니다. 다른 활동이 동일한 데이터 모델을 참조 할 수있는 방법을 보여줍니다. 이것을 발견하는데 오래 걸렸습니다!
Markus

6

예를 들어 클래스 모델 (Object)에서 Serializable을 구현하십시오.

public class MensajesProveedor implements Serializable {

    private int idProveedor;


    public MensajesProveedor() {
    }

    public int getIdProveedor() {
        return idProveedor;
    }

    public void setIdProveedor(int idProveedor) {
        this.idProveedor = idProveedor;
    }


}

그리고 첫 활동

MensajeProveedor mp = new MensajeProveedor();
Intent i = new Intent(getApplicationContext(), NewActivity.class);
                i.putExtra("mensajes",mp);
                startActivity(i);

두 번째 활동 (NewActivity)

        MensajesProveedor  mensajes = (MensajesProveedor)getIntent().getExtras().getSerializable("mensajes");

행운을 빕니다!!


6
public class SharedBooking implements Parcelable{

    public int account_id;
    public Double betrag;
    public Double betrag_effected;
    public int taxType;
    public int tax;
    public String postingText;

    public SharedBooking() {
        account_id = 0;
        betrag = 0.0;
        betrag_effected = 0.0;
        taxType = 0;
        tax = 0;
        postingText = "";
    }

    public SharedBooking(Parcel in) {
        account_id = in.readInt();
        betrag = in.readDouble();
        betrag_effected = in.readDouble();
        taxType = in.readInt();
        tax = in.readInt();
        postingText = in.readString();
    }

    public int getAccount_id() {
        return account_id;
    }
    public void setAccount_id(int account_id) {
        this.account_id = account_id;
    }
    public Double getBetrag() {
        return betrag;
    }
    public void setBetrag(Double betrag) {
        this.betrag = betrag;
    }
    public Double getBetrag_effected() {
        return betrag_effected;
    }
    public void setBetrag_effected(Double betrag_effected) {
        this.betrag_effected = betrag_effected;
    }
    public int getTaxType() {
        return taxType;
    }
    public void setTaxType(int taxType) {
        this.taxType = taxType;
    }
    public int getTax() {
        return tax;
    }
    public void setTax(int tax) {
        this.tax = tax;
    }
    public String getPostingText() {
        return postingText;
    }
    public void setPostingText(String postingText) {
        this.postingText = postingText;
    }
    public int describeContents() {
        // TODO Auto-generated method stub
        return 0;
    }
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeInt(account_id);
        dest.writeDouble(betrag);
        dest.writeDouble(betrag_effected);
        dest.writeInt(taxType);
        dest.writeInt(tax);
        dest.writeString(postingText);

    }

    public static final Parcelable.Creator<SharedBooking> CREATOR = new Parcelable.Creator<SharedBooking>()
    {
        public SharedBooking createFromParcel(Parcel in)
        {
            return new SharedBooking(in);
        }
        public SharedBooking[] newArray(int size)
        {
            return new SharedBooking[size];
        }
    };

}

데이터 전달 :

Intent intent = new Intent(getApplicationContext(),YourActivity.class);
Bundle bundle = new Bundle();
i.putParcelableArrayListExtra("data", (ArrayList<? extends Parcelable>) dataList);
intent.putExtras(bundle);
startActivity(intent);

데이터 검색 :

Bundle bundle = getIntent().getExtras();
dataList2 = getIntent().getExtras().getParcelableArrayList("data");

5

내가 찾은 가장 쉬운 솔루션은 getters setter가있는 정적 데이터 멤버가있는 클래스를 만드는 것입니다.

한 활동에서 설정하고 해당 오브젝트에서 다른 활동에서 가져옵니다.

활동 A

mytestclass.staticfunctionSet("","",""..etc.);

활동 b

mytestclass obj= mytestclass.staticfunctionGet();

1
또는 creata 직렬화 가능 클래스를 사용하여 전달하려는 모든 활동에 전달하십시오.
UMAR

9
뚱뚱한 물건을 넣지 마십시오. 해당 개체의 수명은 응용 프로그램의 수명과 동일합니다. 절대로 뷰를 저장하지 마십시오. 이 방법은 또한 메모리 누수를 보장합니다.
Reno

1
이 답변은 메모리와 리소스 최적화 측면에서 유용하지만 더 나은 솔루션은 아닙니다.
Atul Bhardwaj

1
이것은 전역 변수를 도입하여 OOP 원칙을 위반합니다. 설정 여부에 관계없이 어떤 상태에서 많은 스레드가 사용하는지 알지 못 하므로이 복잡성을 처리해야합니다. 이러한 변수를 언제 해제해야할지 모르기 때문에 일반적으로 메모리 누수가 양호합니다. 말할 것도없이, 어플리케이션의 다른 모듈들 사이에 하드 다이렉트 커플 링이 도입되었습니다.
07

2
WTF? 다른 두 가지는 훨씬 우수합니다.
IcyFlame

4

putExtra (Serializable ..) 및 getSerializableExtra () 메소드를 사용하여 클래스 유형의 오브젝트를 전달하고 검색 할 수 있습니다. 클래스 직렬화 가능을 표시하고 모든 멤버 변수도 직렬화 가능해야합니다.


4

안드로이드 응용 프로그램 만들기

파일 >> 새로운 >> 안드로이드 어플리케이션

프로젝트 이름 입력 : android-pass-object-to-activity

팩스 : com.hmkcode.android

다른 defualt 선택을 유지하고 Finish에 도달 할 때까지 Next로 이동하십시오.

앱 생성을 시작하기 전에 한 활동에서 다른 활동으로 오브젝트를 보내는 데 사용할 POJO 클래스 "Person"을 작성해야합니다. 클래스가 Serializable 인터페이스를 구현하고 있습니다.

Person.java

package com.hmkcode.android;
import java.io.Serializable;

public class Person implements Serializable{

    private static final long serialVersionUID = 1L;

    private String name;
    private int age;

        // getters & setters....

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }   
}

두 가지 활동을위한 두 가지 레이아웃

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >

<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
    <TextView
        android:id="@+id/tvName"
        android:layout_width="100dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:gravity="center_horizontal"
        android:text="Name" />

    <EditText
        android:id="@+id/etName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"

        android:ems="10" >
        <requestFocus />
    </EditText>
</LinearLayout>

<LinearLayout
     android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">
<TextView
    android:id="@+id/tvAge"
    android:layout_width="100dp"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:gravity="center_horizontal"
    android:text="Age" />
<EditText
    android:id="@+id/etAge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ems="10" />
</LinearLayout>

<Button
    android:id="@+id/btnPassObject"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:text="Pass Object to Another Activity" />

</LinearLayout>

activity_another.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
 >

<TextView
    android:id="@+id/tvPerson"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:layout_gravity="center"
    android:gravity="center_horizontal"
 />

</LinearLayout>

두 가지 활동 수업

1) 활동 Main.java

package com.hmkcode.android;

import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class MainActivity extends Activity implements OnClickListener {

Button btnPassObject;
EditText etName, etAge;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    btnPassObject = (Button) findViewById(R.id.btnPassObject);
    etName = (EditText) findViewById(R.id.etName);
    etAge = (EditText) findViewById(R.id.etAge);

    btnPassObject.setOnClickListener(this);
}

@Override
public void onClick(View view) {

    // 1. create an intent pass class name or intnet action name 
    Intent intent = new Intent("com.hmkcode.android.ANOTHER_ACTIVITY");

    // 2. create person object
    Person person = new Person();
    person.setName(etName.getText().toString());
    person.setAge(Integer.parseInt(etAge.getText().toString()));

    // 3. put person in intent data
    intent.putExtra("person", person);

    // 4. start the activity
    startActivity(intent);
}

}

2) 다른 활동 .java

package com.hmkcode.android;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;

public class AnotherActivity extends Activity {

TextView tvPerson;

@Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_another);

    // 1. get passed intent 
    Intent intent = getIntent();

    // 2. get person object from intent
    Person person = (Person) intent.getSerializableExtra("person");

    // 3. get reference to person textView 
    tvPerson = (TextView) findViewById(R.id.tvPerson);

    // 4. display name & age on textView 
    tvPerson.setText(person.toString());

}
}

4

구글의 Gson 라이브러리를 사용하면 객체를 다른 액티비티로 전달할 수 있습니다. 실제로 우리는 json 문자열 형태로 객체를 변환하고 다른 액티비티로 전달한 후 다시 다음과 같이 객체로 다시 변환합니다

이 같은 빈 클래스를 고려하십시오

 public class Example {
    private int id;
    private String name;

    public Example(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

예제 클래스의 객체를 전달해야합니다

Example exampleObject=new Example(1,"hello");
String jsonString = new Gson().toJson(exampleObject);
Intent nextIntent=new Intent(this,NextActivity.class);
nextIntent.putExtra("example",jsonString );
startActivity(nextIntent);

읽기 위해서는 NextActivity에서 역 동작을해야합니다

 Example defObject=new Example(-1,null);
    //default value to return when example is not available
    String defValue= new Gson().toJson(defObject);
    String jsonString=getIntent().getExtras().getString("example",defValue);
    //passed example object
    Example exampleObject=new Gson().fromJson(jsonString,Example .class);

gradle 에이 의존성을 추가하십시오

compile 'com.google.code.gson:gson:2.6.2'


3

나는 이것이 늦었지만 매우 간단하다는 것을 알고 있습니다. 당신이하는 일은 클래스가 Serializable을 구현하도록하십시오.

public class MyClass implements Serializable{

}

다음과 같은 의도를 전달할 수 있습니다

Intent intent=......
MyClass obje=new MyClass();
intent.putExtra("someStringHere",obje);

간단하게 전화하려면

MyClass objec=(MyClass)intent.getExtra("theString");

2

어쨌든 모델 계층의 게이트웨이 역할을하는 싱글 톤 클래스 (fx Service)가있는 경우 getter 및 setter가있는 해당 클래스의 변수를 사용하여 해결할 수 있습니다.

활동 1에서 :

Intent intent = new Intent(getApplicationContext(), Activity2.class);
service.setSavedOrder(order);
startActivity(intent);

활동 2 :

private Service service;
private Order order;

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

    service = Service.getInstance();
    order = service.getSavedOrder();
    service.setSavedOrder(null) //If you don't want to save it for the entire session of the app.
}

서비스 중 :

private static Service instance;

private Service()
{
    //Constructor content
}

public static Service getInstance()
{
    if(instance == null)
    {
        instance = new Service();
    }
    return instance;
}
private Order savedOrder;

public Order getSavedOrder()
{
    return savedOrder;
}

public void setSavedOrder(Order order)
{
    this.savedOrder = order;
}

이 솔루션에는 해당 객체의 직렬화 또는 기타 "패키징"이 필요하지 않습니다. 그러나 어쨌든 이런 종류의 아키텍처를 사용하는 경우에만 유용합니다.


이 방법의 단점은 무엇입니까? 너무 논리적이고 슬림 해 보입니다. 나는 항상 당신이 그렇게해서는 안된다는 것을 읽었지만 잘못 될 수있는 것에 대해 좋은 설명을 얻지 못했습니다.
Markus

주석을 더 이상 편집 할 수 없기 때문에 이것이 사본 대신 객체에 대한 참조를 얻는 유일한 해결책이 아닙니까? 사본이 아닌 동일한 객체를 검색해야합니다!
Markus

나는 이것이 높은 커플 링으로 인해 다소 권장되지 않는다고 생각합니다. 그러나 네, 내가 알 수있는 한,이 방법은 실제 객체가 필요한 경우 가장 실용적입니다. 프로그래밍에서 항상 그렇듯이 원하는 것은 무엇이든 할 수 있으며 신중하게 수행하기를 원합니다. 이 솔루션은 저에게 효과적이며 어쨌든 해당 아키텍처를 사용하기 때문에 선호합니다.
Kitalda

실제로 Application 클래스를 확장하고 데이터 모델을 거기에 저장했습니다. 인 텐트에서는 Application 클래스에서 원래 객체를 검색하는 데 사용할 수있는 데이터 객체의 ID 만 릴레이했습니다. 또한 확장 응용 프로그램 클래스는 표준 리스너 개념을 통해 데이터 모델이 변경되면 데이터 모델을 사용하는 모든 오브젝트에 알립니다. 나는 이것이 전체 응용 프로그램에서 데이터 모델을 공유 해야하는 경우에만 적합하지만 그 경우에는 정적 클래스와 필드가 필요하지 않습니다.
Markus

2

IMHO가 객체를 소포하는 가장 쉬운 방법. 소포를 만들려는 객체 위에 주석 태그를 추가하기 만하면됩니다.

라이브러리의 예는 https://github.com/johncarl81/parceler입니다.

@Parcel
public class Example {
    String name;
    int age;

    public Example(){ /*Required empty bean constructor*/ }

    public Example(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public String getName() { return name; }

    public int getAge() { return age; }
}

2

먼저 클래스에서 Parcelable 을 구현 하십시오. 그런 다음 이와 같은 객체를 전달하십시오.

SendActivity.java

ObjectA obj = new ObjectA();

// Set values etc.

Intent i = new Intent(this, MyActivity.class);
i.putExtra("com.package.ObjectA", obj);

startActivity(i);

ReceiveActivity.java

Bundle b = getIntent().getExtras();
ObjectA obj = b.getParcelable("com.package.ObjectA");

패키지 문자열은 필요하지 않으며 두 활동 모두에서 문자열이 동일해야합니다.

참고


2

Bundle Object를 통해이 액티비티 패스 매개 변수에서 다른 액티비티 시작

Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("USER_NAME", "xyz@gmail.com");
startActivity(intent);

다른 활동 검색 (YourActivity)

String s = getIntent().getStringExtra("USER_NAME");

이것은 간단한 종류의 데이터 유형에 적합합니다. 그러나 활동 사이에 복잡한 데이터를 전달하려면 먼저 직렬화해야합니다.

여기 직원 모델이 있습니다

class Employee{
    private String empId;
    private int age;
    print Double salary;

    getters...
    setters...
}

Google이 제공하는 Gson lib를 사용하여 이와 같은 복잡한 데이터를 직렬화 할 수 있습니다

String strEmp = new Gson().toJson(emp);
Intent intent = new Intent(getBaseContext(), YourActivity.class);
intent.putExtra("EMP", strEmp);
startActivity(intent);

Bundle bundle = getIntent().getExtras();
    String empStr = bundle.getString("EMP");
            Gson gson = new Gson();
            Type type = new TypeToken<Employee>() {
            }.getType();
            Employee selectedEmp = gson.fromJson(empStr, type);

2

콜틴에서

build.gradle에 kotlin 확장을 추가하십시오.

apply plugin: 'kotlin-android-extensions'

android {
    androidExtensions {
        experimental = true
   }
}

그런 다음 이와 같이 데이터 클래스를 작성하십시오.

@Parcelize
data class Sample(val id: Int, val name: String) : Parcelable

의도와 함께 객체 전달

val sample = Sample(1,"naveen")

val intent = Intent(context, YourActivity::class.java)
    intent.putExtra("id", sample)
    startActivity(intent)

의도적으로 객체 얻기

val sample = intent.getParcelableExtra("id")

아직 실험 중입니까?
ShadeToD

2

가장 쉽고 Java하는 방법은 : pojo / model 클래스에서 직렬화 가능 구현

성능보기를 위해 Android에 권장 : 모델 소포 가능


1

가장 간단한 방법은 항목이 문자열 인 경우 다음을 사용하는 것입니다.

intent.putextra("selected_item",item)

수신 :

String name = data.getStringExtra("selected_item");

3
그것의 문자열, 정수 등에 만 있지만 객체를 원하고 정적 객체를 사용하는 것이 가능합니다.
UMAR
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.