Android에서 한 활동에서 다른 활동으로 오브젝트를 전달하는 방법


779

고객 클래스 의 객체 를 하나 에서 보내고 Activity다른 것으로 표시 하려고 노력하고 있습니다 Activity.

고객 클래스의 코드 :

public class Customer {

    private String firstName, lastName, Address;
    int Age;

    public Customer(String fname, String lname, int age, String address) {

        firstName = fname;
        lastName = lname;
        Age = age;
        Address = address;
    }

    public String printValues() {

        String data = null;

        data = "First Name :" + firstName + " Last Name :" + lastName
        + " Age : " + Age + " Address : " + Address;

        return data;
    }
}

객체 Activity를 다른 객체로 보내고 다른 데이터를 표시하고 싶습니다 Activity.

어떻게하면 되나요?


1
아마도 당신은 대중의 의견을 고려하여 받아 들여진 대답을 바꿔야 할 것입니다.
Rohit Vipin Mathews

객체를 Pacelable 또는 Serializable로 설정했지만 다른 변수를 추가 할 때마다 Pacelable 또는 Serializable에 대해 가져오고 설정하려면 함수에 모두 추가해야합니다. 그래서 활동과 조각간에 DataCache를 전송하도록했습니다. github.com/kimkevin/AndroidDataCache 객체를 전송하는 것은 매우 쉽습니다.
kimkevin

답변:


886

하나의 옵션은 사용자 정의 클래스가 Serializable인터페이스를 구현하게 한 다음 메소드 의 putExtra(Serializable..)변형을 사용하여 추가 목적으로 객체 인스턴스를 전달할 수 있습니다 Intent#putExtra().

의사 코드 :

//To pass:
intent.putExtra("MyClass", obj);

// To retrieve object in second Activity
getIntent().getSerializableExtra("MyClass");

참고 : 기본 사용자 정의 클래스의 각 중첩 클래스가 직렬화 예외를 피하기 위해 직렬화 가능 인터페이스를 구현했는지 확인하십시오. 예를 들면 다음과 같습니다.

class MainClass implements Serializable {

    public MainClass() {}

    public static class ChildClass implements Serializable {

        public ChildClass() {}
    }
}

126
@OD : 내 방어에서는 이것이 최선의 선택이라고 말한 적이 없다. OP는 방금 다른 대안을 요청했으며 대안을 제안했습니다. 어쨌든 고마워.
Samuh

83
Serializable이 좋은 옵션이 아닌 이유는 무엇입니까? 그것은 잘 알려진 인터페이스이며 사람들의 클래스가 이미 그것을 구현했을 가능성이 높습니다 (예를 들어 ArrayList는 이미 직렬화 가능합니다). 단순히 한 클래스에서 다른 클래스로 전달하기 위해 추가 코드를 추가하기 위해 데이터 오브젝트를 변경해야하는 이유는 무엇입니까? 그것은 나쁜 디자인처럼 보입니다. 어느 정도 수준에서는 성능에 영향을 줄 수 있다고 생각할 수 있지만 99 %의 경우 사람들이 적은 양의 데이터를 전달하므로 신경 쓰지 않을 것이라고 생각합니다. 간결하고 휴대 성이 더 좋은 경우도 있습니다.
Nate

16
@ 산더 :이 대답 ( stackoverflow.com/questions/2139134/… )은 그때 잘못 되었습니까? 그는 Parcelable IS 가 그 목적을 위해 특별히 설계 되었다고 말한다 Serializable. 혼란 스러워요.
Slauma

41
Parcelable속도는 좋지만 구현하기가 복잡합니다. 활동 사이에 통과해야 할 8 개의 오브젝트가 있으면 Parcelable어떻게합니까? Serializable대신 사용 하는 것이 더 합리적 입니다. 구현할 때 Parcelable클래스에 많은 코드를 추가하고 매우 구체적인 방식으로 필드를 정렬해야합니다. Serializable당신은하지 않습니다. 궁극적으로, 나는 당신이 지나가는 물건의 수와 당신이하려는 일에 달려 있다고 생각합니다.
BlackHatSamurai

15
Serializable표준 Java 인터페이스입니다. 인터페이스를 임박하여 Serializable 클래스를 표시하면 Java는 특정 상황에서 자동으로 직렬화합니다. Parcelable직렬화를 직접 구현하는 Android 전용 인터페이스입니다. 그것은 직렬화가 훨씬 더 효율적으로, 기본 자바 직렬화 기법 몇 가지 문제를 해결하기 위해서는 생성
Gaurav 아 로라를

311

Serializable을 사용하여 클래스를 구현하십시오. 이것이 엔터티 클래스라고 가정 해 봅시다.

import java.io.Serializable;

@SuppressWarnings("serial") //With this annotation we are going to hide compiler warnings
public class Deneme implements Serializable {

    public Deneme(double id, String name) {
        this.id = id;
        this.name = name;
    }

    public double getId() {
        return id;
    }

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

    public String getName() {
        return this.name;
    }

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

    private double id;
    private String name;
}

deneX 액티비티에서 Y 액티비티로 호출 된 객체를 보냅니다 . X 활동의 어딘가;

Deneme dene = new Deneme(4,"Mustafa");
Intent i = new Intent(this, Y.class);
i.putExtra("sampleObject", dene);
startActivity(i);

Y 활동에서 우리는 객체를 얻고 있습니다.

Intent i = getIntent();
Deneme dene = (Deneme)i.getSerializableExtra("sampleObject");

그게 다야.


1
정말 도움이되었습니다. 감사합니다 ... 그러나 전달 된 객체를 수신 할 때 구문은 다음과 같아야합니다. [Deneme dene = (Deneme) i.getSerializableExtra ( "sampleObject"); ] ... 그것은 ??
JibW

1
@ MustafaGüven 그러나 나는 classCastException: java.lang.Long그렇게하고 있습니다. 이유를 설명해 주시겠습니까?
Shajeel Afzal 2016

내 대답과는 아무런 관련이 없습니다. 당신이 얻는 것은 매우 다릅니다. 코드를 공유 할 수 있습니까?
Mustafa Güven

1
큰 POJO에는 직렬화가 너무 느립니다. 버스를 사용하는 것이 훨씬 더 나은 패턴입니다.
Steven Mark Ford

1
(Serializable)객체 에 접두사 를 붙여야 합니까?
Alston

123
  • 전역 정적 변수를 사용하는 것은 좋은 소프트웨어 엔지니어링 관행 이 아닙니다 .
  • 객체의 필드를 원시 데이터 유형 으로 변환하는 것은 바쁜 작업이 될 수 있습니다 .
  • 직렬화 가능을 사용하는 것은 좋지만 Android 플랫폼 에서는 성능 비효율적 입니다.
  • Parcelable은 Android 용 으로 특별히 설계되었으며 사용해야합니다. 간단한 예제는 다음과 같습니다. Android 활동간에 사용자 정의 오브젝트 전달

사이트를 사용하여 클래스에 대한 Parcelable 코드를 생성 할 수 있습니다 .


4
객체에 중첩 된 Arraylist가 포함되어 있으면 어떻게됩니까?
Dr. aNdRO

10
아마도 그러나 한 사람은 실제로 소금 imo로``성능 ''을 취해야합니다. 그것이 구현 가격에 오면 ParcelablePOJO 클래스를 Android에 무관하게 유지하고 사용하고 싶습니다 Serializable.
VH-NZZ

Parcelable을 사용해야한다는 데 동의하지 않습니다. 간단한 BUS 패턴은 런타임시 훨씬 더 효율적이며 많은 개발 시간을 절약합니다.
Steven Mark Ford

15
이 벤치 마크에 따르면 bitbucket.org/afrishman/androidserializationtest Serializable은 Parcelable보다 훨씬 빠릅니다. Parcelable에 관한이 5 년 된 말도 안되는 이야기 나누기를 중단하십시오.
afish

7
전역 정적 변수는 어떻게 "좋은 소프트웨어 엔지니어링 관행"이 아닌가? 싱글 톤 캐시 및 / 또는 데이터 그리드와 같은 것을 만든 다음 ID 또는 이와 유사한 것을 전달할 수 있습니다. Java에서 참조를 전달하면 전역 정적 변수가 동일한 객체를 가리키는 의미로 사용됩니다.
breakline

112

gson 을 사용 하여 객체를 JSON으로 변환하고 의도를 전달하십시오. 새로운 활동에서 JSON을 객체로 변환하십시오.

에서 build.gradle의존성에 추가하십시오.

implementation 'com.google.code.gson:gson:2.8.4'

활동에서 객체를 json-string으로 변환하십시오.

Gson gson = new Gson();
String myJson = gson.toJson(vp);
intent.putExtra("myjson", myjson);

수신 활동에서 json-string을 원래 객체로 다시 변환하십시오.

Gson gson = new Gson();
YourObject ob = gson.fromJson(getIntent().getStringExtra("myjson"), YourObject.class);

들어 코 틀린 꽤 동일합니다

데이터를 전달

val gson = Gson()
val intent = Intent(this, YourActivity::class.java)
intent.putExtra("identifier", gson.toJson(your_object))
startActivity(intent)

데이터 수신

val gson = Gson()
val yourObject = gson.fromJson<YourObject>(intent.getStringExtra("identifier"), YourObject::class.java)

3
과잉 인 gson은 json에 대한 문자열 직렬화의 한 유형일 뿐이며 Serializable 또는 Paracable을 구현하는 것이 좋습니다.
James Roeiter

14
그것을 처리하는 라이브러리 (gson)를 사용할 수 있다면 모든 객체와 모든 프로젝트 (시간 낭비)에서 직렬화 가능을 구현할 필요가 없습니다. 그리고 과잉 기술에 대해 이중 및 쿼드 코어 전화가 있으며이 답변 아이디어에 따라 목록을 처리 할 수도 있습니다.
sagits

4
gson은 위의 것 외에도 배열 목록을 직렬화 할 수 있기 때문에 gson을 사용하는 것이 좋습니다.
nurgasemetey

4
대단해! 제 경우에는 객체가 직렬화 가능하거나 소포를 구현하지 않는 라이브러리를 사용하고 있습니다. 그래서 이것은 나의 유일한 선택 afaik입니다
Chad Bingham

2
이것이 "최상의"옵션입니다. 일부 클래스는 매우 단순하므로 직렬화 가능을 구현하여 구현을 복잡하게 할 필요가 없습니다.
Ojonugwa Jude Ochalifu

98

활동을 부르는 동안

Intent intent = new Intent(fromClass.this,toClass.class).putExtra("myCustomerObj",customerObj);

toClass.java에서 활동을 수신하십시오.

Customer customerObjInToClass = getIntent().getExtras().getParcelable("myCustomerObj");

고객 클래스가 소포를 구현하는지 확인하십시오

public class Customer implements Parcelable {

    private String firstName, lastName, address;
    int age;

    /* all your getter and setter methods */

    public Customer(Parcel in ) {
        readFromParcel( in );
    }

    public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
        public LeadData createFromParcel(Parcel in ) {
            return new Customer( in );
        }

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


    @Override
    public void writeToParcel(Parcel dest, int flags) {

        dest.writeString(firstName);
        dest.writeString(lastName);
        dest.writeString(address);
        dest.writeInt(age);
    }

    private void readFromParcel(Parcel in ) {

        firstName = in .readString();
        lastName  = in .readString();
        address   = in .readString();
        age       = in .readInt();
    }

아다 반, 질문이 있어요 첫 번째 Intent 클래스를 만들면 fromClass.this를 첫 번째 인수로 전달합니다. 수신 활동 클래스에서이 오브젝트를 검색하는 방법이 있습니까?
newman

1
Miliu, fromClass fr = (fromClass) getParent (); 이것이 당신이 필요한 것입니까?
광고

Adhava, 나는 실제로 이것을했지만 fr은 null입니다. 왜 그런지 알아?
newman

miliu, 우리가 조사 할 수 있도록 예외 추적을 공유하십시오.
광고

Parcelable은 불필요하게 많은 보일러 플레이트 코드를 가지고 있으며 솔직히 시간 낭비입니다. 오히려 버스를 사용하십시오. 아래 내 게시물을 참조하십시오.
Steven Mark Ford

89

내 경험에는 각각 단점과 장점이있는 세 가지 주요 솔루션이 있습니다.

  1. 소포 가능 구현

  2. 직렬화 가능 구현

  3. 일종의 경량 이벤트 버스 라이브러리 사용 (예 : Greenrobot의 EventBus 또는 Square 's Otto)

소포 가능 -빠르며 안드로이드 표준이지만 보일러 플레이트 코드가 많으며 의도를 강하게 입력 할 때 참조하기 위해 하드 코딩 된 문자열이 필요합니다 (강하지 않은 유형).

직렬화 가능 -상용구가 0에 가깝지만 가장 느리게 접근하는 방식이며 값을 의도하지 않은 값으로 가져올 때 하드 코딩 된 문자열이 필요합니다 (비 유형).

이벤트 버스 -상용구 없음, 가장 빠른 접근 방식, 하드 코딩 된 문자열이 필요하지 않지만 추가 종속성이 필요함 (보통 약 40KB 임)

효율성 벤치 마크를 포함하여이 세 가지 접근 방식을 매우 상세하게 비교했습니다.


4
기사 링크가 죽었습니다. webarchive에서 여전히 사용 가능 : web.archive.org/web/20160917213123/http://…
OlivierH

링크가 다운 된 것은 부끄러운 일입니다 :(
Mauker

이벤트 버스 사용의 문제점은 예를 들어 회전으로 인해 대상 활동이 다시 작성 될 때입니다. 이 경우 대상 활동은 전달 된 오브젝트에 액세스 할 수 없습니다.이 오브젝트는 이전 호출에 의해 버스에서 소비 되었기 때문입니다.
JuliuszJ

1
Parcelable이 가장 빠르며이 발전기 ( parcelabler.com) )를 사용하면 클래스를 붙여넣고 코드를 생성 할 수 있습니다. 단순한.
ByWaleed

1
@ ByWaleed ... 나는 절대적으로 동의합니다, 나는 항상이 사이트를 사용하고, 번거 로움없이 물건을 만듭니다. 그러나 다른 객체로 구성된 POJO를 사용하려고 할 때 많은 시도가 실패했습니다. 어떤 이유로 든 출력이 실제로 작동하지 않습니다.
Yo Apps

42

간단하고 우아한 방법을 찾았습니다.

  • 소포 없음
  • 직렬화 불가능
  • 정적 필드 없음
  • 이벤트 버스 없음

방법 1

첫 번째 활동을위한 코드 :

    final Object objSent = new Object();
    final Bundle bundle = new Bundle();
    bundle.putBinder("object_value", new ObjectWrapperForBinder(objSent));
    startActivity(new Intent(this, SecondActivity.class).putExtras(bundle));        
    Log.d(TAG, "original object=" + objSent);

두 번째 활동을위한 코드 :

    final Object objReceived = ((ObjectWrapperForBinder)getIntent().getExtras().getBinder("object_value")).getData();
    Log.d(TAG, "received object=" + objReceived);

당신은 발견 할 것이다 objSent & objReceived동일이 hashCode가 동일하므로,.

그러나 왜 이런 식으로 Java 객체를 전달할 수 있습니까?

실제로 안드로이드 바인더는 자바 객체에 대한 글로벌 JNI 참조를 생성하고이 자바 객체에 대한 참조가 없을 때이 글로벌 JNI 참조를 해제합니다. 바인더는이 글로벌 JNI 참조를 바인더 오브젝트에 저장합니다.

*주의 :이 메소드는 두 활동이 동일한 프로세스에서 실행되지 않는 한 작동합니다. 그렇지 않으면 (ObjectWrapperForBinder) getIntent (). getExtras (). getBinder ( "object_value")에서 ClassCastException을 발생시킵니다.

ObjectWrapperForBinder 정의 클래스

public class ObjectWrapperForBinder extends Binder {

    private final Object mData;

    public ObjectWrapperForBinder(Object data) {
        mData = data;
    }

    public Object getData() {
        return mData;
    }
}

방법 2

  • 발신자에게
    1. 사용자 정의 원시 메소드를 사용하여 JNI 글로벌 참조 테이블에 Java 오브젝트를 추가하십시오 (JNIEnv :: NewGlobalRef를 통해)
    2. 반환 정수를 넣습니다 (실제로 JNIEnv :: NewGlobalRef 반환 jobject, 포인터입니다, 안전하게 int로 캐스트 할 수 있습니다) intent (Intent :: putExtra를 통해)
  • 수신기
    1. Intent에서 정수 가져 오기 (Intent :: getInt를 통해)
    2. JNI 글로벌 참조 테이블에서 JNIEnv :: NewLocalRef를 통해 Java 오브젝트를 복원하려면 사용자 정의 고유 메소드 사용
    3. JNI 글로벌 참조 테이블에서 항목 제거 (JNIEnv :: DeleteGlobalRef를 통해),

그러나 방법 2에는 수신자가 java 오브젝트를 복원하지 못하면 (예를 들어, java 오브젝트를 복원하기 전에 일부 예외가 발생하거나 수신자 활동이 전혀 존재하지 않는 경우) 약간의 심각한 문제가 있습니다. 그러면 java 오브젝트는 안드로이드 바인더 가이 예외를 처리하기 때문에 고아 또는 메모리 누수, 방법 1에는이 문제가 없습니다

방법 3

java 객체를 원격으로 호출하기 위해 java 객체를 설명하기위한 데이터 계약 / 인터페이스를 작성하고 aidl 파일을 사용합니다.

IDataContract.aidl

package com.example.objectwrapper;
interface IDataContract {
    int func1(String arg1);
    int func2(String arg1);
}

첫 번째 활동을위한 코드

    final IDataContract objSent = new IDataContract.Stub() {

        @Override
        public int func2(String arg1) throws RemoteException {
            // TODO Auto-generated method stub
            Log.d(TAG, "func2:: arg1=" + arg1);
            return 102;
        }

        @Override
        public int func1(String arg1) throws RemoteException {
            // TODO Auto-generated method stub
            Log.d(TAG, "func1:: arg1=" + arg1);
            return 101;
        }
    };
    final Bundle bundle = new Bundle();
    bundle.putBinder("object_value", objSent.asBinder());
    startActivity(new Intent(this, SecondActivity.class).putExtras(bundle));
    Log.d(TAG, "original object=" + objSent);

두 번째 활동을위한 코드 :

두 번째 활동이 다른 프로세스에서 실행되도록 AndroidManifest.xml의 android : process 속성을 비어 있지 않은 프로세스 이름으로 변경하십시오.

    final IDataContract objReceived = IDataContract.Stub.asInterface(getIntent().getExtras().getBinder("object_value"));
    try {
        Log.d(TAG, "received object=" + objReceived + ", func1()=" + objReceived.func1("test1") + ", func2()=" + objReceived.func2("test2"));
    } catch (RemoteException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

이러한 방식으로 두 프로세스가 서로 다른 프로세스에서 실행 되더라도 두 활동간에 인터페이스를 전달하고 원격으로 인터페이스 메소드를 호출 할 수 있습니다.

방법 4

방법 3은 보조 인터페이스를 구현해야하기 때문에 충분히 단순 해 보이지 않습니다. 간단한 작업을하고 메소드 반환 값이 필요하지 않은 경우 android.os.Messenger를 사용할 수 있습니다

첫 번째 활동 코드 (발신자) :

public class MainActivity extends Activity {
    private static final String TAG = "MainActivity";

    public static final int MSG_OP1 = 1;
    public static final int MSG_OP2 = 2;

    public static final String EXTRA_MESSENGER = "messenger";

    private final Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            Log.e(TAG, "handleMessage:: msg=" + msg);
            switch (msg.what) {
            case MSG_OP1:

                break;
            case MSG_OP2:
                break;

            default:

                break;
            }
            super.handleMessage(msg);
        }

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

        startActivity(new Intent(this, SecondActivity.class).putExtra(EXTRA_MESSENGER, new Messenger(mHandler)));
    }
}

두 번째 활동에 대한 코드 (수신자) :

public class SecondActivity extends Activity {

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

        final Messenger messenger = getIntent().getParcelableExtra(MainActivity.EXTRA_MESSENGER);
        try {
            messenger.send(Message.obtain(null, MainActivity.MSG_OP1, 101, 1001, "10001"));
            messenger.send(Message.obtain(null, MainActivity.MSG_OP2, 102, 1002, "10002"));
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

모든 Messenger.send는 Handler에서 비동기 적으로 순차적으로 실행됩니다.

실제로 android.os.Messenger는 보조 인터페이스입니다 .Android 소스 코드가 있으면 IMessenger.aidl이라는 파일을 찾을 수 있습니다.

package android.os;

import android.os.Message;

/** @hide */
oneway interface IMessenger {
    void send(in Message msg);
}

죄송합니다. 귀하의 답변에 구속력이 있음을 보지 못 했으므로 귀하의 답변도 매우 우아하다고 생각합니다.
SkidRunner

와우 ....이 남자의 첫 번째 방법은 엄청납니다 ..... 당신이 잘 작동하는 매우 크거나 큰 크기의 물건을 가지고있을 때
karan

사용자 방법 1이므로 시간을 절약 할 수 있습니다. 감사;
ShweLiam

ObjectWrapperForBinder 메서드에 대해 대단히 감사합니다.
Vladimir Tolstikov

40

객체의 데이터를 임시 문자열과 int에 기록하여 액티비티에 전달할 수도 있습니다. 물론 그런 식으로 데이터를 전송하지만 객체 자체는 얻지 못합니다.

그러나 당신이 그것들을 보여주고 싶거나 다른 방법이나 그와 비슷한 것에 객체를 사용하지 않는다면 충분해야합니다. 다른 활동에서 한 객체의 데이터를 표시하는 것과 동일한 방식으로 수행했습니다.

String fName_temp   = yourObject.getFname();
String lName_temp   = yourObject.getLname();
String age_temp     = yourObject.getAge();
String address_temp = yourObject.getAddress();

Intent i = new Intent(this, ToClass.class);
i.putExtra("fname", fName_temp);
i.putExtra("lname", lName_temp);
i.putExtra("age", age_temp);
i.putExtra("address", address_temp);

startActivity(i);

당신은 또한 임시 ivar 대신에 직접 전달할 수 있지만, 이런 식으로 내 의견으로는 더 명확합니다. 또한 임시 ivar을 null로 설정하여 GarbageCollector에서 더 빨리 청소할 수 있습니다.

행운을 빕니다!

참고로 자신의 인쇄 메소드를 작성하는 대신 toString ()을 대체하십시오.

아래 의견에서 언급했듯이 다른 활동에서 데이터를 다시 얻는 방법입니다.

String fName = getIntent().getExtras().getInt("fname");

9
다음을 사용하여 데이터를 다시 가져옵니다. String fName = getIntent (). getExtras (). getInt ( "fname");
Alister

2
데이터를 다시 얻으려면 : Bundle extras = getIntent().getExtras(); String val = extras.getString("fname");
Eric Leschinski

1
이는 큰 POJO에게는 신속하게 실현 불가능할 수 있습니다. 오히려 버스를 사용하십시오. 아래 내 게시물을 참조하십시오.
Steven Mark Ford

내 대답에서 언급했듯이 이것은 객체 자체가 필요하지 않고 단순한 값이있는 간단한 유스 케이스입니다. 복잡한 사용 사례에 대한 해결책은 아닙니다.
MJB

1
단일 객체를 전달하는 것이 좋지만 객체의 알 수없는 크기의 배열을 전달하려고합니다. 아마도 귀하의 솔루션은 객체 배열을 전달하기위한 것이 아닙니다.
Muhammad Saqib

25

임시 객체를 보유하는 단일 도우미 클래스를 만들었습니다.

public class IntentHelper {

    private static IntentHelper _instance;
    private Hashtable<String, Object> _hash;

    private IntentHelper() {
        _hash = new Hashtable<String, Object>();
    }

    private static IntentHelper getInstance() {
        if(_instance==null) {
            _instance = new IntentHelper();
        }
        return _instance;
    }

    public static void addObjectForKey(Object object, String key) {
        getInstance()._hash.put(key, object);
    }

    public static Object getObjectForKey(String key) {
        IntentHelper helper = getInstance();
        Object data = helper._hash.get(key);
        helper._hash.remove(key);
        helper = null;
        return data;
    }
}

Intent 내에 객체를 넣는 대신 IntentHelper를 사용하십시오.

IntentHelper.addObjectForKey(obj, "key");

새 활동 내에서 객체를 얻을 수 있습니다.

Object obj = (Object) IntentHelper.getObjectForKey("key");

일단로드 된 객체는 불필요한 참조를 피하기 위해 제거됩니다.


1
좋은 생각! 또한 추가 클래스를 만들 수 있습니다. ObjectContainer {Object, obj; 부울 영구; ....} 아이디어는 객체를 지속적으로 유지해야하고 get을 호출 할 때 제거하지 않으면 add 메소드에서 부울을 전달할 수 있다는 것입니다. 전역 객체를 유지하는 데 도움이됩니다. 열린 블루투스 연결 등이 될 수 있습니다.
Umair

1
귀엽지 만 바퀴를 다시 발명하지 마십시오. 버스 패턴은 우아하고 강력합니다. 아래 내 게시물을 참조하십시오.
Steven Mark Ford

@StevenMarkFord 지금까지 버스 패턴이 여전히 유효합니까? 내가 활동 사이의 액세스하는 데이터와 같은 코드로 코드베이스를 개선하기 위해 노력하고 있어요 : BookActivity.getInstance().recommendationResponseRoomsActivity
Woppi

수신 활동이 다시 생성되면 (예 : 화면 회전) obj이됩니다 null. 이를 피하려면 obj다시 가져 오려면 어딘가에 보관해야합니다. 실제로 Json 솔루션은 객체 데이터를 Intent에 저장합니다.
살바도르

25

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

A. 데이터베이스

B. 공유 환경 설정.

C. 객체 직렬화.

D. 공통 데이터를 보유 할 수있는 클래스는 공통 유틸리티로 명명 될 수 있습니다. 이것은 너에게 달려있어.

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

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

A. 데이터베이스

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

튜토리얼

B. 공유 환경 설정

사용자 이름을 저장한다고 가정하십시오. 이제 핵심 사용자 이름, 값의 두 가지가 있습니다 .

보관 방법

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

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

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

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

이 튜토리얼을 원하면 다음을 참조하십시오.

D. 공통 유틸리티

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

견본

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

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

이 데이터 전달 옵션에 대해서는 Parcelable 클래스사용하여 활동간에 전달할 Android – Parcel 데이터 학습서를 참조하십시오 .


22

Customer다음과 같이 자신의 클래스 를 작성하십시오 .

import import java.io.Serializable;
public class Customer implements Serializable
{
    private String name;
    private String city;

    public Customer()
    {

    }
    public Customer(String name, String city)
    {
        this.name= name;
        this.city=city;
    }
    public String getName() 
    {
        return name;
    }
    public void setName(String name) 
    {
        this.name = name;
    }
    public String getCity() 
    {
        return city;
    }
    public void setCity(String city) 
    {
        this.city= city;
    }

}

당신의 onCreate()방법으로

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

    Customer cust=new Customer();
    cust.setName("abc");
    cust.setCity("xyz");

    Intent intent=new Intent(abc.this,xyz.class);
    intent.putExtra("bundle",cust);
    startActivity(intent); 
}

에서 xyz activity클래스 다음 코드를 사용합니다 :

Intent intent=getIntent();
Customer cust=(Customer)intent.getSerializableExtra("bundle");
textViewName.setText(cust.getName());
textViewCity.setText(cust.getCity());

당신이 넣어의 핵심으로 "번들"을 전달하는 코드를 ..Check CUST OBJ 및 "클래스"..pls 중 하나 "클래스"또는 "번들".. 하나의 키 사용에서 점점
AK 조시

오류가 발생했습니다 : Parcelable에서 IOException이 직렬화 가능한 개체를 쓰는 중
Arul Mani

15

가장 좋은 방법은 응용 프로그램에 클래스 '고객'유형의 정적 변수를 보유하는 클래스 (Control)라고하는 것입니다 (귀하의 경우). 활동 A에서 변수를 초기화하십시오.

예를 들면 다음과 같습니다.

Control.Customer = CustomerClass;

그런 다음 Activity B로 이동하여 Control 클래스에서 가져옵니다. 변수를 사용한 후 null을 할당하는 것을 잊지 마십시오. 그렇지 않으면 메모리가 낭비됩니다.


4
@aez 디자인 관점에서 느슨하고 의도가 다른 프로세스에있는 경우 끔찍하게 깨지기 때문입니다.

7
앱을 활동 B로 다시 시작할 때 문제가 발생합니다. Android에서 활동을 종료 할 수 있고 오브젝트가 저장되지 않기 때문에.
Ryan R

15
public class MyClass implements Serializable{
    Here is your instance variable
}

이제 startActivity에서이 클래스의 객체를 전달하려고합니다. 간단히 이것을 사용하십시오 :

Bundle b = new Bundle();
b.putSerializable("name", myClassObject);
intent.putExtras(b);

MyClass가 구현하기 때문에 여기에서 작동합니다 Serializable.


더 자세히 설명하거나 더 자세히 설명해 주시겠습니까
Amitsharma

숙제 데이터 숙제 데이터 = homeWorksList.get (position); 의도 의도 = 새로운 의도 (c, HomeWorkActivitydetail.class); 번들 b = 새 번들 (); b.putSerializable ( "CompleteData", homeworkData); intent.putExtras (b); c.startActivity (의도); 객체를 추가 할 때 객체 요소를 추가 할 때 약간의 오류가 발생합니다. 이것으로 완전한 객체를 전달할 수 없습니다
Amitsharma

나는 데이터를 추가 할 가치가있다
Amitsharma

12

Samuh가 설명하는 방식을 사용하기로 선택한 경우 기본 값만 보낼 수 있음을 기억하십시오. 즉, 구문 분석 가능한 값입니다. 따라서 객체에 복잡한 객체가 포함되어 있으면 따르지 않습니다. 예를 들어 Bitmap, HashMap 등과 같은 변수는 의도를 전달하기가 까다 롭습니다.

일반적으로 나는 사건이 될 것에서는 문자열, INT, 부울 등과 같이 엑스트라로만 원시 데이터 유형을 보내 조언을 것입니다 : String fname, String lname, int age,와 String address.

내 의견 : ContentProvider , SDCard 등 을 구현하면 더 복잡한 객체를 더 잘 공유 할 수 있습니다. 정적 변수 를 사용할 수도 있지만 오류가 발생하기 쉬운 코드로 빠르게 이어질 수 있습니다 ...

그러나 다시, 그것은 단지 내 주관적인 의견 일뿐입니다.


8

한 활동에서 다른 활동으로 데이터를 보내기 위해 소포 가능을 사용하고 있습니다. 내 프로젝트에서 잘 작동하는 코드는 다음과 같습니다.

public class Channel implements Serializable, Parcelable {

    /**  */
    private static final long serialVersionUID = 4861597073026532544L;

    private String cid;
    private String uniqueID;
    private String name;
    private String logo;
    private String thumb;


    /**
     * @return The cid
     */
    public String getCid() {
        return cid;
    }

    /**
     * @param cid
     *     The cid to set
     */
    public void setCid(String cid) {
        this.cid = cid;
    }

    /**
     * @return The uniqueID
     */
    public String getUniqueID() {
        return uniqueID;
    }

    /**
     * @param uniqueID
     *     The uniqueID to set
     */
    public void setUniqueID(String uniqueID) {
        this.uniqueID = uniqueID;
    }

    /**
     * @return The name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name
     *            The name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the logo
     */
    public String getLogo() {
        return logo;
    }

    /**
     * @param logo
     *     The logo to set
     */
    public void setLogo(String logo) {
        this.logo = logo;
    }

    /**
     * @return the thumb
     */
    public String getThumb() {
        return thumb;
    }

    /**
     * @param thumb
     *     The thumb to set
     */
    public void setThumb(String thumb) {
        this.thumb = thumb;
    }


    public Channel(Parcel in) {
        super();
        readFromParcel(in);
    }

    public static final Parcelable.Creator<Channel> CREATOR = new Parcelable.Creator<Channel>() {
        public Channel createFromParcel(Parcel in) {
            return new Channel(in);
        }

        public Channel[] newArray(int size) {

            return new Channel[size];
        }
    };

    public void readFromParcel(Parcel in) {
        String[] result = new String[5];
        in.readStringArray(result);

        this.cid = result[0];
        this.uniqueID = result[1];
        this.name = result[2];
        this.logo = result[3];
        this.thumb = result[4];
    }

    public int describeContents() {
        return 0;
    }

    public void writeToParcel(Parcel dest, int flags) {

        dest.writeStringArray(new String[] { this.cid, this.uniqueID,
                this.name, this.logo, this.thumb});
    }
}

activityA에서 다음과 같이 사용하십시오 :

Bundle bundle = new Bundle();
bundle.putParcelableArrayList("channel",(ArrayList<Channel>) channels);
Intent intent = new Intent(ActivityA.this,ActivityB.class);
intent.putExtras(bundle);
startActivity(intent);

ActivityB에서 다음과 같이 사용하여 데이터를 가져옵니다.

Bundle getBundle = this.getIntent().getExtras();
List<Channel> channelsList = getBundle.getParcelableArrayList("channel");

7

해당 클래스를 사용해보십시오. 한 프로세스 외부에서는 사용할 수 없다는 제한이 있습니다.

하나의 활동 :

 final Object obj1 = new Object();
 final Intent in = new Intent();
 in.putExtra(EXTRA_TEST, new Sharable(obj1));

다른 활동 :

final Sharable s = in.getExtras().getParcelable(EXTRA_TEST);
final Object obj2 = s.obj();

public final class Sharable implements Parcelable {

    private Object mObject;

    public static final Parcelable.Creator < Sharable > CREATOR = new Parcelable.Creator < Sharable > () {
        public Sharable createFromParcel(Parcel in ) {
            return new Sharable( in );
        }


        @Override
        public Sharable[] newArray(int size) {
            return new Sharable[size];
        }
    };

    public Sharable(final Object obj) {
        mObject = obj;
    }

    public Sharable(Parcel in ) {
        readFromParcel( in );
    }

    Object obj() {
        return mObject;
    }


    @Override
    public int describeContents() {
        return 0;
    }


    @Override
    public void writeToParcel(final Parcel out, int flags) {
        final long val = SystemClock.elapsedRealtime();
        out.writeLong(val);
        put(val, mObject);
    }

    private void readFromParcel(final Parcel in ) {
        final long val = in .readLong();
        mObject = get(val);
    }

    /////

    private static final HashMap < Long, Object > sSharableMap = new HashMap < Long, Object > (3);

    synchronized private static void put(long key, final Object obj) {
        sSharableMap.put(key, obj);
    }

    synchronized private static Object get(long key) {
        return sSharableMap.remove(key);
    }
}

6

이 활동에서 다른 활동을 시작하고 번들 오브젝트를 통해 매개 변수를 전달하십시오.

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

다른 활동 (YourActivity)에 대한 데이터 검색

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

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

여기 직원 모델이 있습니다

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

TypeToken <>은 더 이상 사용되지 않습니다. 대체물은 무엇입니까?
Ragavendra M

6

이 질문은 다른 스택 오버플로 질문에서도 논의됩니다. Serializable 사용하여 의도를 통해 데이터 전달대한 솔루션을 살펴보십시오 . 요점은 Bundle필요한 데이터를 내부에 저장하는 객체를 사용 하는 것 Intent입니다.

 Bundle bundle = new Bundle();

 bundle.putSerializable(key1, value1);
 bundle.putSerializable(key2, value2);
 bundle.putSerializable(key3, value3);

 intent.putExtras(bundle);

값을 추출하려면 다음을 수행하십시오.

 Bundle bundle = new Bundle();

 for (String key : bundle.keySet()) {
 value = bundle.getSerializable(key));
 }

장점은 Serializable단순성입니다. 그러나 Android 용으로 특별히 설계되었으며보다 효율적 Parcelable이기 때문에 많은 데이터를 전송해야하는 경우 분석법 사용을 고려해야 합니다. 다음을 사용하여 수업을 만들 수 있습니다 .ParcelableSerializableParcelable

  1. 온라인 도구- 소포
  2. Android Studio 용 플러그인 -Android Parcelable Code Generator

5

Bean 클래스와 같은 클래스를 작성하고 Serializable인터페이스를 구현하십시오 . 그런 다음 intent메소드를 통해 전달할 수 있습니다 . 예를 들면 다음과 같습니다.

intent.putExtra("class", BeanClass);

그런 다음 다른 활동에서 가져옵니다.

BeanClass cb = intent.getSerializableExtra("class");

5

이와 같이 커스텀 클래스에 두 개의 메소드를 작성하십시오.

public class Qabir {

    private int age;
    private String name;

    Qabir(){
    }

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

    // method for sending object
    public String toJSON(){
        return "{age:" + age + ",name:\"" +name +"\"}";
    }

    // method for get back original object
    public void initilizeWithJSONString(String jsonString){

        JSONObject json;        
        try {
            json =new JSONObject(jsonString );
            age=json.getInt("age");
            name=json.getString("name");
        } catch (JSONException e) {
            e.printStackTrace();
        } 
    }
}

이제 발신자 활동에서 다음과 같이하십시오.

Qabir q= new Qabir(22,"KQ");    
Intent in=new Intent(this,SubActivity.class);
in.putExtra("obj", q.toJSON());
startActivity( in);

그리고 수신자 활동에서

Qabir q =new Qabir();
q.initilizeWithJSONString(getIntent().getStringExtra("obj"));

3

예, 정적 개체를 사용하는 것이 사용자 지정 비 직렬화 가능 개체에서 가장 쉬운 방법입니다.


그래, 난 당신에 동의하는 것 같아 전달하려는 모든 속성에 대해 static계속 호출하는 것이 실용적이지 않은 경우 이러한 개체를 만드는 것이 더 나은 해결 방법 putExtra()입니다. 예를 들어 지금 당장 ArrayList은 객체가 포함 된 객체 를 전달하고 싶습니다 . static대신 ArrayList 를 만들 수도 있습니다 .
Matthew Quiros

3

Android 활동 오브젝트는 파기 및 재구성 될 수 있습니다. 따라서 다른 접근 방식을 사용 하여 또는 자신이 생성 한 객체를 확인해야합니다. !!! -위로. 즉, 정적 클래스 참조로 전달할 수 있지만 객체 기능 (Java는 SmallTalk와 마찬가지로 이러한 "참조"를 호출하지만 C 또는 어셈블리의 의미에서는 참조가 아님)은 나중에 "기능"으로 인해 유효하지 않을 수 있습니다. Android OE는 모든 활동이 나중에 소멸되고 재구성 될 수 있습니다.

원래 질문은 "Android에서 한 활동에서 다른 활동으로 오브젝트를 전달하는 방법"을 물었고 아무도 대답하지 않았습니다. 확실히, 직렬화 (Serializable, Parcelable, JSON으로 /로부터) 할 수 있으며 오브젝트의 데이터 사본을 전달하면 동일한 데이터를 가진 새 오브젝트를 작성할 수 있습니다. 그러나 동일한 참조 / 핸들을 갖지 않습니다. 또한 많은 사람들이 참조를 정적 저장소에 저장할 수 있다고 언급했습니다. 안드로이드가 onDestroy Activity를 결정하지 않는 한 작동합니다.

따라서 원래 질문을 실제로 해결하려면 정적 조회가 필요하며 각 객체는 다시 생성 될 때 / 다시 생성 될 때마다 해당 참조를 업데이트합니다. 예를 들어 onCreate가 호출되면 각 Android 활동이 다시 나열됩니다. 또한 일부 사람들이 작업 목록을 사용하여 이름별로 활동을 검색하는 방법을 볼 수 있습니다. (시스템은 공간을 절약하기 위해 활동의이 인스턴스를 일시적으로 파괴합니다. .getRunningTasks, 작업 목록은 사실상 각 활동의 최신 오브젝트 인스턴스의 특수화 된 목록입니다).

참고로 :

중지됨 : "활동이 다른 활동에 의해 완전히 가려져 있습니다 (활동이"백그라운드 "에 있음). 중지 된 활동도 여전히 유효합니다 ( 활동 오브젝트는 메모리에 유지되며 모든 상태 및 멤버 정보를 유지하지만 그렇지는 않습니다) 그러나이 파일은 더 이상 사용자에게 표시되지 않으며 다른 곳에서 메모리가 필요할 때 시스템에 의해 종료 될 수 있습니다. "

onDestroy "시스템이 공간을 절약하기 위해 활동 의이 인스턴스 를 일시적으로 파괴 하고 있습니다."

따라서 메시지 버스는 실행 가능한 솔루션입니다. 기본적으로 "펀트"입니다. 객체에 대한 참조를 갖기보다는; 그런 다음 SequentialCode 대신 MessagePassing을 사용하도록 디자인을 다시 설계하십시오. 기하 급수적으로 디버그하기가 어렵습니다. 그러나 이러한 종류의 운영 환경 이해를 무시할 수 있습니다. 효과적으로, 각 객체 메소드 액세스가 반전되어 호출자가 메시지를 게시하고 객체 자체가 해당 메시지의 핸들러를 정의합니다. 더 많은 코드가 있지만 Android OE 제한으로 강력해질 수 있습니다.

원하는 모든 것이 최상위 활동 (모든 곳에서 "컨텍스트"가 필요하기 때문에 Android 앱의 일반적인 것) 인 경우 onResume이 호출 될 때마다 각 전역 활동을 정적 전역 공간에서 "정상"으로 표시 할 수 있습니다. 그런 다음 AlertDialog 또는 컨텍스트가 필요한 것은 무엇이든 얻을 수 있습니다. 또한 전역을 사용하는 것은 다소 좋지 않지만 어디서나 컨텍스트를 위아래로 전달하는 것을 단순화 할 수 있으며, 확실히 MessageBus를 사용하면 IT는 전역입니다.


Otto는 평범한 오래된 Java 앱에서 외부에서 실행할 수 있다는 장점이 있습니다. 따라서 안드로이드를 망칠 필요없이 개발자와 테스트에 좋습니다. 오토는 큰 학습 곡선을 가지고 있으며 해결해야 할 대부분은 이미 안드로이드 방식 (로컬 브로드 캐스트 등) 또는 일반적인 앱 개발 접근 방식으로 해결되었습니다 (오토의 글로벌 조회보다 훨씬 간단한 글로벌 조회를 작성할 수 있습니다. 코드를 통한 벡터화 / F3 및 디버깅을 통한 스테핑에 더 접근 가능).
TimJowers2

2
  1. 나는 정적이 나쁘다는 것을 알고 있지만 여기서 사용해야 할 것 같습니다. Parceables / Seriazables의 문제점은 두 활동에 동일한 오브젝트의 중복 인스턴스 (메모리 낭비 및 CPU)가 있다는 것입니다.

    public class IntentMailBox {
        static Queue<Object> content = new LinkedList<Object>();
    }

전화 활동

IntentMailBox.content.add(level);
Intent intent = new Intent(LevelsActivity.this, LevelActivity.class);
startActivity(intent);

호출 된 활동 (참고 시스템이 활동을 파괴하고 재 작성할 때 onCreate ()onResume () 이 여러 번 호출 될 수 있음에 )

if (IntentMailBox.content.size()>0)
    level = (Level) IntentMailBox.content.poll();
else
    // Here you reload what you have saved in onPause()
  1. 또 다른 방법은 해당 클래스에 전달하려는 클래스의 정적 필드를 선언하는 것입니다. 이 목적을 위해서만 제공됩니다. 시스템에서 앱 패키지를 메모리에서 언로드하고 나중에 다시로드하기 때문에 onCreate에서 null 일 수 있습니다.

  2. 여전히 활동 라이프 사이클을 처리해야한다는 점을 염두에두고, 복잡한 데이터 구조로 인해 고통스러운 모든 데이터를 공유 환경 설정에 바로 기록 할 수 있습니다.


1

위의 답변은 거의 모두 맞지만 그 답변을 이해하지 못하는 사람들을 위해 안드로이드는 강력한 클래스 의도를 가지고 있습니다. 액티비티뿐만 아니라 Android의 다른 구성 요소 (브로드 캐서 수신기, 콘텐츠를 제공하여 ContetnResolver 클래스를 사용하지 않습니다) ). 당신의 활동에서 당신은 의도를 구축

Intent intent = new Intent(context,SomeActivity.class);
intent.putExtra("key",value);
startActivity(intent);

당신의받는 활동에서 당신은

public class SomeActivity extends AppCompactActivity {

    public void onCreate(...){
    ...
          SomeObject someObject = getIntent().getExtras().getParceable("key");
    }

}

활동간에 공유하려면 오브젝트에 Parceable 또는 Serializable 인터페이스를 구현해야합니다. 안드로이드가 특히 이것을 위해 플러그인을 가지고있는 이유 때문에 객체에 직렬화 가능 인터페이스가 아닌 Parcealbe 를 구현하기가 어렵 습니다.


0

나는 왜 이것이 다른 활동의 메소드를 호출하는 것만 큼 간단하지 않은지 궁금했습니다. 최근에는 유틸리티 라이브러리를 작성하여 거의 간단하게 만들었습니다. 여기서 확인할 수 있습니다 ( https://github.com/noxiouswinter/gnlib_android/wiki/gnlauncher ).

GNLauncher를 사용하면 필요한 데이터를 매개 변수로 사용하여 Activity의 함수를 호출하는 것처럼 다른 Activity 등에서 Activity로 객체 / 데이터를 보낼 수 있습니다. 형식 안전을 도입하고 직렬화해야하는 모든 번거 로움을 없애고 문자열 키를 사용하여 의도를 첨부하고 다른 쪽 끝을 취소합니다.

용법

시작하기 위해 활동에서 호출하려는 메소드로 인터페이스를 정의하십시오.

public interface IPayload {
    public void sayHello(String name, int age);
}

시작할 Activity에서 위의 인터페이스를 구현하십시오. 활동이 준비되면 GNLauncher에 알리십시오.

public class Activity_1 extends Activity implements IPayload {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //Notify GNLauncher when the Activity is ready. 
        GNLauncher.get().ping(this);
    }

    @Override
    public void sayHello(String name, int age) {
        Log.d("gnlib_test", "Hello " + name + "! \nYour age is: " + age);
    }
}

다른 활동에서 위 활동에 대한 프록시를 얻고 원하는 매개 변수로 메소드를 호출하십시오.

public class Activity_2 extends Activity {
    public void onClick(View v) {
        ((IPayload)GNLauncher.get().getProxy(this, IPayload.class, Activity_1.class)).sayHello(name, age);
    }
}

첫 번째 활동이 시작되고 메소드가 필수 매개 변수와 함께 호출됩니다.

전제 조건

종속성을 추가하는 방법에 대한 정보는 https://github.com/noxiouswinter/gnlib_android/wiki#prerequisites 를 참조하십시오 .


0

한 활동에서 다른 활동으로 오브젝트를 전달하십시오.

(1) 소스 활동

Intent ii = new Intent(examreport_select.this,
                    BarChartActivity.class);

            ii.putExtra("IntentExamResultDetail",
                    (Serializable) your List<ArraList<String>> object here);
            startActivity(ii);

(2) 목적지 행동

List<ArrayList<String>> aa = (List<ArrayList<String>>) getIntent()
            .getSerializableExtra("IntentExamResultDetail");

0

Pacelable 또는 Serializable로 객체를 전송하도록 설정했지만 객체 (모델)에 다른 변수를 추가 할 때마다 모두 등록해야합니다. 너무 불편합니다.

액티비티 또는 프래그먼트간에 객체를 전송하는 것이 매우 쉽습니다.

안드로이드 데이터 캐시


0

한 활동에서 다른 활동으로 객체를 전달할 수 있습니다.

SupplierDetails poSuppliersDetails = new SupplierDetails();

내부 poSuppliersDetails에는 몇 가지 가치가 있습니다. 이제이 객체를 대상 활동으로 보냅니다.

Intent iPODetails = new Intent(ActivityOne.this, ActivityTwo.class);
iPODetails.putExtra("poSuppliersDetails", poSuppliersDetails);

ACtivityTwo에서 이것을 얻는 방법 :

private SupplierDetails supplierDetails;
    supplierDetails =(SupplierDetails) getIntent().getSerializableExtra("poSuppliersDetails");

0

한 활동을 다른 활동으로 전달하십시오.

startActivity(new Intent(getBaseContext(),GetActivity.class).putExtra("passingkey","passingvalue"));

가치를 얻으십시오 :

String myvalue= getIntent().getExtras("passingkey");

-1

안녕하세요. 좋은 옵션이 많이 있지만 바인딩이 사용되지 않은 이유가 궁금합니다.

객체에 대한 참조를 전달하는 것은 객체를 직렬화하고 살균하는 것보다 나에게 더 효율적인 것처럼 보이지만 그 장면이 뒤에서 진행되고 있는지 확인하기 위해 심층적 인 다이빙을하지 않았습니다.

바인더를 만드는 것은 간단합니다 ...

public class MyBinder extends Binder {

    private Object myObject;

    public MyBinder(Object object) {
        myObject = object;
    }

    public Object getObject() {
        return myObject;
    }

}

그리고 그것을 사용하기 위해 소포를 만드는 것은 그렇게 나쁜 것이 아닙니다.

public class MyParcelable implements Parcelable {

    private Object myObject;

    public MyParcelable() {
    }

    public MyParcelable(Parcel parcel) {
        myObject = ((MyBinder)parcel.readStrongBinder()).getObject();
    }

    public void setObject(Object object) {
        myObject = object;
    }

    public Object getObject() {
        return myObject;
    }

    public void writeToParcel(Parcel parcel, int flags) {
        parcel.writeStrongBinder(new MyBinder(myObject));
    }

    public int describeContents() {
        return myObject == null ? 0 : 1;
    }

    public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {

        public MyParcelable createFromParcel(Parcel parcel) {
            return new MyParcelable(parcel);
        }

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

    };
}

이 논리는 실제로 참조를 활동에서 활동으로 전달하기 때문에 정말 멋집니다.

null을 확인하고 Binder의 인스턴스가 MyBinder인지 확인하는 것이 좋습니다.

그리고 이것을 구현하려면 ...

보내

Object myObject = "some object";
MyParcelable myParcelable = new MyParcelable();
myParcelable.setObject(myObject);

intent.putExtra("MyParcelable", myParcelable);

돌려 받다

myParcelable = (MyParcelable) getIntent().getExtras().getParcelable("MyParcelable");
myObject = myParcelable.getObject();

누군가가 미쳐 버릴 수도 있고이 속임수를 진정한 제네릭으로 만들 수도 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.