programing

Android에서 한 활동에서 다른 활동으로 개체를 전달하는 방법

goodcopy 2022. 8. 11. 23:50
반응형

Android에서 한 활동에서 다른 활동으로 개체를 전달하는 방법

하나에서 고객 클래스의 오브젝트를 전송하려고 합니다.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;
    }
}

는 그 싶다.ActivityActivity.

어떻게 하면 좋을까요?

클래스에 「」를도 입니다.Serializable extra를 를 전달할 수 .putExtra(Serializable..)Intent#putExtra()★★★★★★ 。

실제 코드:

커스텀 모델/오브젝트 클래스:

public class YourClass implements Serializable {

커스텀 모델/클래스를 사용하는 다른 클래스:

//To pass:
intent.putExtra("KEY_NAME", myObject);

myObject는 "YourClass" 유형입니다.그런 다음 다른 활동에서 검색하려면 getSerializable을 사용합니다.기타 동일한 키 이름을 사용하여 개체를 가져옵니다.또한 YourClass에 타이프캐스트가 필요합니다.

// To retrieve object in second Activity
myObject = (YourClass) getIntent().getSerializableExtra("KEY_NAME");

주의: 시리얼화 예외를 피하기 위해 메인 커스텀클래스의 네스트된 각 클래스에 Serializable 인터페이스가 실장되어 있는지 확인합니다.예를 들어 다음과 같습니다.

class MainClass implements Serializable {
    
    public MainClass() {}

    public static class ChildClass implements Serializable {
         
        public ChildClass() {}
    }
}

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

라고 하는 오브젝트를 보냅니다.deneY자형.액티비티 내 에; 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");

바로 그겁니다.

gson을 사용하여 개체를 JSON으로 변환하고 인텐션을 통과시킵니다.새 활동에서 JSON을 개체로 변환합니다.

고객님의 고객명build.gradle 됩니다.

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

Activity에서 개체를 json-string으로 변환합니다.

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

수신 액티비티에서 json 문자열을 원래 개체로 변환합니다.

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)
  • 글로벌 스태틱 변수를 사용하는 것은 소프트웨어 엔지니어링의 좋은 방법이 아닙니다.
  • 개체의 필드를 원시 데이터 유형으로 변환하는 작업매우 바쁜 작업일 수 있습니다.
  • serializable을 사용하는 것은 괜찮지만, Android 플랫폼에서는 성능 효율이 높지 않습니다.
  • Parchable은 Android 전용으로 설계되어 있으므로 사용해야 합니다.다음은 간단한 예입니다. Android 작업 사용자 지정 개체 전달

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

액티비티를 호출하는 동안

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

제 경험상으로는 다음과 같은 3가지 주요 솔루션이 있습니다.각 솔루션에는 단점과 장점이 있습니다.

  1. 구획화 가능 구현

  2. 시리얼 대응 구현

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

패키지 가능 - 빠른 Android 규격이지만 보일러 플레이트 코드가 많아 의도(강하지 않은 유형)를 추출할 때 참조하기 위해 하드 코딩된 문자열이 필요합니다.

직렬화 가능 - 보일러 플레이트 0에 가깝지만 가장 느린 접근 방식이며, 의도(강하지 않은 유형)를 추출할 때 하드 코딩된 문자열이 필요합니다.

이벤트 버스 - 보일러 플레이트가 제로이고 가장 빠른 접근으로 하드 코딩된 문자열이 필요하지 않지만 추가 종속성이 필요합니다(보통 경량, 최대 40KB).

효율성 벤치마크를 포함한 이 세 가지 접근법에 대해 매우 상세한 비교를 게시했습니다.

심플하고 우아한 방법을 찾았습니다.

  • 포장 가능 없음
  • 시리얼 대응 없음
  • 정적 필드 없음
  • 이벤트 버스 없음

방법 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&objReceivedhashCode그래서 똑같습니다.

그런데 왜 자바 오브젝트를 이런 식으로 넘길 수 있을까요?

실제로 안드로이드 바인더는 Java 오브젝트에 대한 글로벌 JNI 참조를 작성하고 Java 오브젝트에 대한 참조가 없을 때 글로벌 JNI 참조를 릴리스합니다.바인더는 이 글로벌 JNI 참조를 바인더 오브젝트에 저장합니다.

*주의: 이 메서드는 두 액티비티가 동일한 프로세스에서 실행되지 않는 한 기능합니다.그렇지 않으면 ClassCastException을 (ObjectWrapperForBinder)에 던집니다.Intent().getExtras().getBinder("object_value")*

클래스 ObjectWrapperForBinder 디피니션

public class ObjectWrapperForBinder extends Binder {

    private final Object mData;

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

    public Object getData() {
        return mData;
    }
}

방법 2

  • ★★★★★★★★★★★★★★★★,
    1. 커스텀 네이티브메서드를 사용하여 Java 객체를 JNI 글로벌 참조 테이블에 추가합니다(JNIEnv 경유:: NewGlobalRef)
    2. 반환 정수(실제로는 JNIEnv:: NewGlobalRef return jobject는 포인터이므로 안전하게 Int에 캐스트할 수 있습니다(Intent::putExtra를 통해).
  • 수취인을 위해
    1. Intent에서 정수 가져오기(Intent: getInt 경유)
    2. 커스텀 네이티브메서드를 사용하여 JNI 글로벌레퍼런스 테이블에서 Java 오브젝트를 복원합니다(JNIEnv 경유::New Local Ref)
    3. JNI 글로벌 참조 테이블에서 항목 제거(JNIEnv 경유::DeleteGlobalRef)

그러나 방법 2에는 조금 심각한 문제가 있습니다.리시버가 Java 오브젝트를 복원하지 못한 경우(예를 들어 Java 오브젝트를 복원하기 전에 일부 예외가 발생하거나 리시버 액티비티가 전혀 존재하지 않는 경우), 방법 1은 이 예외를 처리하므로 Java 오브젝트가 고립되거나 메모리 누수가 발생하지 않습니다.

방법 3

Java 객체를 원격으로 호출하려면 Java 객체를 설명하는 데이터 계약/인터페이스를 만들고 aidl 파일을 사용합니다.

IData Contract.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은 aidl 인터페이스를 구현해야 하기 때문에 충분히 간단하지 않습니다.간단한 작업만 원하시면 메서드 반환값이 필요없으시다면 Android.os를 이용하실 수 있습니다.메신저

첫 번째 액티비티의 코드(송신자):

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

    }
}

모든 메신저.send는 처리기에서 비동기적이고 순차적으로 실행됩니다.

사실, 안드로이드.os.메신저도 보조 인터페이스입니다.안드로이드 소스 코드가 있으면 IMessenger.aidl이라는 파일을 찾을 수 있습니다.

package android.os;

import android.os.Message;

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

또한 객체의 데이터를 임시 문자열 및 ints에 작성하여 액티비티에 전달할 수도 있습니다.물론 이렇게 하면 데이터가 전송되지만 객체 자체는 전송되지 않습니다.

그러나 오브젝트를 다른 방법으로 사용하지 않고 표시만 하고 싶다면 그걸로 충분합니다.다른 액티비티에 있는 오브젝트의 데이터를 표시하기 위해서도 같은 방법으로 했습니다.

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를 null로 설정하여 GarbageCollector에 의해 더 빨리 정리할 수 있습니다.

행운을 빕니다.

덧붙여서: 독자적인 인쇄 방식을 쓰는 대신 String()으로 덮어씁니다.

아래 코멘트에서 설명한 바와 같이 데이터를 다른 액티비티로 되돌리는 방법은 다음과 같습니다.

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

저는 임시 물건을 담을 수 있는 싱글톤 도우미 클래스를 만들었습니다.

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

로드되면 불필요한 참조를 피하기 위해 오브젝트가 삭제된다는 점에 유의하십시오.

다른 클래스나 액티비티의 변수나 오브젝트에 액세스 하는 방법에는 몇 가지가 있습니다.

A. 데이터베이스

B. 공통 설정

C. 오브젝트 시리얼화

D. 공통 데이터를 저장할 수 있는 클래스는 공통 유틸리티로 명명할 수 있습니다.당신에 따라 달라요.

E. Intents 및 Parchable Interface를 통해 데이터 전달

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

A. 데이터베이스

SQLite는 Android에 내장된 오픈 소스 데이터베이스입니다.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. 오브젝트 시리얼화

오브젝트 serlization은 오브젝트 상태를 저장하여 네트워크를 통해 전송하려는 경우 또는 목적에도 사용할 수 있는 경우에 사용됩니다.

Java beans를 사용하여 그의 필드 중 하나로 저장하고 getter와 setter를 사용합니다.

JavaBeans는 속성을 가진 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);

그런 다음 오브젝트 serialization을 사용하여 이 오브젝트를 시리얼화하고 다른 클래스에서는 이 오브젝트의 시리얼화를 해제합니다.

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

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

이에 대한 튜토리얼을 보려면 다음을 참조하십시오.

D. 공통 유틸리티

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

샘플

public class CommonUtilities {

    public static String className = "CommonUtilities";

}

E. 데이터를 내부로 전달

Android – Parchable 데이터 튜토리얼을 참조하여 이 데이터 전달 옵션에 대해 Activities using Parchable 클래스전달하십시오.

인 클래스 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());
public class MyClass implements Serializable{
    Here is your instance variable
}

이제 startActivity에서 이 클래스의 개체를 전달합니다.간단히 이것을 사용하세요.

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

은 MyClass가 「MyClass」를 하고 있기 때문에 합니다.Serializable.

가장 좋은 방법은 응용 프로그램에 'Customer'(고객) 유형의 정적 변수를 보유하는 클래스(컨트롤이라고 함)를 갖는 것입니다.액티비티 A에서 변수를 초기화합니다.

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

Control.Customer = CustomerClass;

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

Samuh가 설명하는 방법을 사용할 경우 원시 값만 전송할 수 있습니다.즉, 비유할 수 있는 값입니다.따라서 객체에 복잡한 객체가 포함되어 있는 경우 이러한 객체는 이어지지 않습니다.예를 들어 비트맵, 해시맵 등의 변수...이것들은 의도로 넘어가기엔 까다롭다.

일반적으로 String, int, boolean 등과 같은 원시 데이터 유형만 추가로 보내는 것이 좋습니다.될 거예요.String fname,String lname,int age , , , , 입니다.String address.

제 의견:보다 복잡한 오브젝트는 Content Provider, SDCard 등을 실장함으로써 보다 효율적으로 공유할 수 있습니다.정적 변수를 사용할 수도 있지만, 이로 인해 오류가 발생하기 쉬운 코드가 빠르게 생성될 수 있습니다.

하지만 다시 말씀드리지만, 그건 제 주관적인 의견일 뿐입니다.

한 활동에서 다른 활동으로의 데이터 전송에 패키지 가능을 사용하고 있습니다.여기 제 프로젝트에서 잘 작동하는 코드가 있습니다.

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

액티비티에서는, 다음과 같이 사용합니다.

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

Activity B에서는 다음과 같이 데이터를 가져옵니다.

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

당신은 그 클래스를 이용해 보세요.한 공정 이외에는 사용할 수 없다는 것이 한계입니다.

1가지 액티비티:

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

이 액티비티에서 다른 액티비티를 시작하고 번들오브젝트를 통해 파라미터를 전달합니다.

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

구글에서 제공하는 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);

이 질문은 다른 스택오버플로우 질문에서도 설명됩니다.Serializable을 사용하여 의도를 통해 데이터를 전달하기 위한 솔루션을 살펴보시기 바랍니다.요점은 사용법입니다.BundleIntent.

 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경우에는 ',아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아,아.Parcelable해야 할 메서드는 과 같습니다.다음과 같습니다.Parcelable되었으며, 드드이이 is is is is is is is is is is is is is is is is is is is is is is is is is is is is is is is is is is 보다 효율적입니다.Serializable을 만들 수 .Parcelable다음 중 하나:

  1. 온라인 도구 - 소포 배달원
  2. Android Studio용 플러그인 - Android 패키지 코드 생성기

는 콩 는 실행한다.Serializable인터페이스입니다. '우리'를 요.intent예를 들어 다음과 같습니다.

intent.putExtra("class", BeanClass);

그런 다음 다른 활동에서 가져옵니다. 예를 들어 다음과 같습니다.

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

이렇게 사용자 지정 클래스에 두 가지 메서드를 만듭니다.

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

Android Activity 객체를 파기하고 재구성할 수 있습니다.따라서 다른 접근 방식을 사용하여 해당 사용자 또는 사용자가 만드는 개체를 확인해야 합니다.즉, Static Class Reference로 전달될 수 있지만 오브젝트 핸들(Java는 SmallTalk와 마찬가지로 이러한 "References"라고 부르지만, 그것들은 C나 어셈블리의 의미에서는 참조가 아니다)은 나중에 무효가 될 가능성이 있습니다.안드로이드 OE의 "기능"은 나중에 삭제 및 재구성이 가능하기 때문입니다.

원래 질문에서 "안드로이드에서 한 활동에서 다른 활동으로 개체를 전달하는 방법"을 물었지만 아무도 이에 대답하지 않았습니다.확실히 시리얼화(시리얼화 가능, 구획화 가능, JSON에서/에서)하여 오브젝트의 데이터 복사본을 전달하고 동일한 데이터를 가진 새 오브젝트를 만들 수 있지만 동일한 참조/핸들 수는 없습니다.또한 다른 많은 사용자가 참조를 정적 저장소에 저장할 수 있다고 언급했습니다.Android가 당신의 활동을 파괴하기로 결정하지 않는 한 그것은 효과가 있습니다.

따라서 원래 문제를 해결하려면 정적 룩업이 필요하며 각 개체가 다시 작성될 때 참조가 업데이트됩니다.예를 들어, 각 Android Activity는 onCreate가 호출되면 다시 등록됩니다.또한 일부 사용자가 태스크 목록을 사용하여 이름으로 활동을 검색하는 방법도 볼 수 있습니다.(시스템은 공간을 절약하기 위해 이 액티비티 인스턴스를 일시적으로 파기하고 있습니다.getRunningTasks. 태스크목록은 사실상 각 액티비티의 최신 오브젝트인스턴스의 전문 목록입니다).

참조용:

정지: "다른 액티비티에 의해 액티비티가 완전히 가려집니다(액티비티는 "배경"에 있습니다).정지된 액티비티도 아직 활성화되어 있습니다(Activity 객체는 메모리에 유지되며 모든 상태 및 구성원 정보는 유지되지만 창 관리자에 연결되어 있지 않습니다).다만, 유저에게는 표시되지 않게 되어, 다른 장소에 메모리가 필요하게 되었을 때에 시스템에 의해서 정지될 가능성이 있습니다」라고 설명합니다.

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

따라서 메시지 버스는 실행 가능한 솔루션입니다.기본적으로 "펀치"입니다.오브젝트에 대한 참조를 시도하지 않고 Sequential Code 대신 MessagePassing을 사용하도록 설계를 재구성합니다.디버깅은 기하급수적으로 어렵지만, 이러한 운영 환경에 대한 이해를 무시할 수 있습니다.실제로 각 오브젝트 메서드접근은 반전되어 발신자가 메시지를 투고하고 오브젝트 자체가 그 메시지의 핸들러를 정의합니다.훨씬 더 많은 코드가 있지만 Android OE 제한으로 견고하게 만들 수 있습니다.

원하는 액티비티가 상위 액티비티('Context'가 어디에서나 필요하기 때문에 Android 앱에서는 일반적인 액티비티)인 경우, onResume가 호출될 때마다 정적 글로벌 공간에서 각 액티비티가 "최상위"로 표시되도록 할 수 있습니다.그런 다음 AlertDialog 또는 컨텍스트가 필요한 모든 항목을 여기에서 가져올 수 있습니다.또, 글로벌하게 사용하는 것은 조금 불쾌하지만, 콘텍스트의 상하 이동을 심플하게 할 수 있습니다.또, MessageBus 를 사용하면, IT는 글로벌하게 됩니다.

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

  1. 잡음이 나쁘다는 건 알지만, 여기서는 어쩔 수 없이 사용하는 것 같아요.parcesable/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. 액티비티 라이프 사이클을 처리할 필요가 있는 것을 염두에 두고, 모든 데이터를 공유 프리퍼런스에 직접 기입하는 것이 좋을지도 모릅니다.복잡한 데이터 구조에는 문제가 있습니다.

위의 답변은 거의 모두 맞지만, Android는 이러한 답변에 대해 강력한 클래스 의도를 가지고 있습니다. Android의 다른 컴포넌트(Broadcasr receiver, 컨텐츠용 서비스는 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 인터페이스를 구현해야 합니다.오브젝트에 Serializable Interface가 아닌 Parsealbe를 구현하기 어렵기 때문에 특히 Android에 플러그인이 있습니다.다운로드하여 사용하다

다음과 같이 사용자 지정 클래스를 만듭니다.

public class Test는 Parchable { String message를 구현합니다.

protected Test(Parcel in) {
    message = in.readString();
}

public static final Creator<Test> CREATOR = new Creator<Test>() {
    @Override
    public Test createFromParcel(Parcel in) {
        return new Test(in);
    }

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

public String getMessage() {
    return message;
}

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

@Override
public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(message);
}

다음과 같은 의도를 사용하여 데이터 전송:활동을 시작하기 전에 몇 가지 데이터를 설정해야 합니다.

Intent intent = new Intent(context, PostDetailsActivity.class);
                intent.putExtra("data", (Parcelable) test);
                ((context)).startActivity(intent);

다음과 같은 의도로부터 데이터를 가져옵니다.

Test test = (Test) getIntent().getParcelableExtra("data");

나는 왜 이것이 다른 활동의 방법을 부르는 것만큼 간단하지 않은지 항상 궁금했다.나는 최근에 그것을 거의 그것만큼 간단하게 하는 유틸리티 라이브러리를 썼다.여기(https://github.com/noxiouswinter/gnlib_android/wiki/gnlauncher))에서 확인하실 수 있습니다.

GNLauncher는 다른 액티비티 등에서 액티비티에 오브젝트/데이터를 송신하는 것을 필수 데이터를 파라미터로 하여 액티비티의 함수를 호출하는 것만큼이나 쉽게 합니다.타입의 안전성을 도입해, 시리얼화 할 필요가 없어져, 스트링 키를 사용해 의도에 접속해, 다른 한쪽 끝을 언로드 할 필요가 없어집니다.

사용.

기동하는 액티비티에 호출하는 메서드로 인터페이스를 정의합니다.

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

기동하는 액티비티에 상기의 인터페이스를 실장합니다.또한 액티비티가 준비되면 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 를 참조해 주세요.

한 활동에서 다른 활동으로 개체를 전달합니다.

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

이전에는 Pacelable이나 Serializable로 오브젝트를 설정하여 전송했는데 오브젝트(모델)에 다른 변수를 추가할 때마다 모두 등록해야 합니다.너무 불편해요.

액티비티나 fragment간의 오브젝트 전송은 매우 간단합니다.

Android 데이터 캐시

오브젝트를 액티비티 간에 전달할 수 있습니다.

SupplierDetails poSuppliersDetails = new SupplierDetails();

poSuppliersDetails우리에겐 몇 가지 가치가 있다.이제 대상 액티비티에 이 개체를 보냅니다.

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

ACtivity로 가져오는 방법2개:

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

하나의 액티비티를 다른 액티비티에 전달합니다.

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

값 가져오기:

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

언급URL : https://stackoverflow.com/questions/2736389/how-to-pass-an-object-from-one-activity-to-another-on-android

반응형