번들을 통해 대부분의 처리를 수행하는 클래스에 대한 참조를 전달해야합니다.
문제는 의도 또는 컨텍스트와 관련이 없으며 많은 양의 비 원시 객체가 있다는 것입니다. 클래스를 parcelable / serializable로 패키징하고 어떻게 전달 startActivityForResult
합니까?
번들을 통해 대부분의 처리를 수행하는 클래스에 대한 참조를 전달해야합니다.
문제는 의도 또는 컨텍스트와 관련이 없으며 많은 양의 비 원시 객체가 있다는 것입니다. 클래스를 parcelable / serializable로 패키징하고 어떻게 전달 startActivityForResult
합니까?
답변:
어떤 길을 택해야하는지 알아 내기 위해서는 CommonsWare의 핵심 질문 인 "왜"뿐 아니라 "무엇을 위해?"라는 질문에 답해야합니다. 통과하고 있습니까?
현실은 번들을 통과 할 수있는 유일한 것은 일반 데이터라는 것입니다. 다른 모든 것은 해당 데이터가 의미하거나 가리키는 것에 대한 해석을 기반으로합니다. 문자 그대로 객체를 전달할 수는 없지만 다음 세 가지 중 하나를 수행 할 수 있습니다.
1) 개체를 구성 데이터로 분해 할 수 있으며 다른 쪽 끝에있는 개체가 동일한 종류의 개체에 대해 알고 있으면 직렬화 된 데이터에서 복제본을 조합 할 수 있습니다. 이것이 대부분의 일반적인 유형이 번들을 통과하는 방법입니다.
2) 불투명 핸들을 전달할 수 있습니다. 핸들이 될 동일한 컨텍스트 내에서 전달하는 경우 (귀찮은 이유를 물을 수도 있지만) 호출하거나 역 참조 할 수 있습니다. 그러나 Binder를 통해 다른 컨텍스트로 전달하면 리터럴 값은 임의의 숫자가됩니다 (사실 이러한 임의의 숫자는 시작부터 순차적으로 계산됩니다). Binder가 다시 원래 핸들로 변환하여 다시 유용하게 만들도록 원래 컨텍스트로 다시 전달할 때까지 아무것도 할 수 없지만 추적 할 수 있습니다.
3) 파일 설명자 또는 특정 OS / 플랫폼 개체에 대한 참조와 같은 매직 핸들을 전달할 수 있으며 올바른 플래그를 설정하면 Binder는 수신자에 대해 동일한 리소스를 가리키는 복제본을 생성하여 실제로 사용할 수 있습니다. 다른 쪽 끝. 그러나 이것은 매우 적은 유형의 객체에만 적용됩니다.
대부분의 경우 다른 쪽 끝이이를 추적하고 나중에 다시 제공 할 수 있도록 클래스를 전달하거나 직렬화 된 구성 데이터에서 복제본을 생성 할 수있는 컨텍스트로 전달합니다. 작동하지 않을 일을 시도하고 있으며 전체 접근 방식을 재고해야합니다.
Gson을 사용하여 객체를 JSONObject로 변환하고 번들로 전달할 수도 있습니다. 제게는 이것을 할 수있는 가장 우아한 방법이었습니다. 성능에 미치는 영향을 테스트하지 않았습니다.
초기 활동에서
Intent activity = new Intent(MyActivity.this,NextActivity.class);
activity.putExtra("myObject", new Gson().toJson(myobject));
startActivity(activity);
다음 활동에서
String jsonMyObject;
Bundle extras = getIntent().getExtras();
if (extras != null) {
jsonMyObject = extras.getString("myObject");
}
MyObject myObject = new Gson().fromJson(jsonMyObject, MyObject.class);
Parcelable 인터페이스는 의도를 가진 개체를 전달할 수있는 좋은 방법입니다.
사용자 지정 개체를 Parcelable로 만들려면 어떻게해야합니까? 사용 방법에 대한 꽤 좋은 대답입니다.Parcelable
공식 Google 문서 에는 예제도 포함되어 있습니다.
글로벌 애플리케이션을 사용할 수 있습니다. 상태를 .
최신 정보:
이를 사용자 정의한 다음 AndroidManifest.xml에 추가하십시오.
<application android:label="@string/app_name" android:debuggable="true" android:name=".CustomApplication"
그런 다음 프로젝트에 다음과 같은 클래스가 있습니다.
package com.example;
import android.app.Application;
public class CustomApplication extends Application {
public int someVariable = -1;
}
그리고 " 모든 활동 또는 서비스에서 getApplication ()을 통해 액세스 할 수 있기 때문에 다음과 같이 사용합니다.
CustomApplication application = (CustomApplication)getApplication();
application.someVariable = 123;
도움이되기를 바랍니다.
객체를 Serializable로 만들고 Bundle의 getSerializable 및 putSerializable 메소드를 사용할 수도 있습니다.
가능한 해결책:
Bundle bundle = new Bundle();
bundle.putSerializable("key", new CustomObject());
CustomObject 클래스 :
class CustomObject implements Serializable{
private SubCustomObject1 sc1;
private SubCustomObject2 sc2;
}
하위 사용자 지정 개체 :
class SubCustomObject1 implements Serializable{ }
class SubCustomObject2 implements Serializable{ }
번들을 통해 개체를 보내는 또 다른 방법은 bundle.putByteArray
샘플 코드를 사용하는 것입니다.
public class DataBean implements Serializable {
private Date currentTime;
public setDate() {
currentTime = Calendar.getInstance().getTime();
}
public Date getCurrentTime() {
return currentTime;
}
}
DataBean의 객체를 Bundle에 넣습니다.
class FirstClass{
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Your code...
//When you want to start new Activity...
Intent dataIntent =new Intent(FirstClass.this, SecondClass.class);
Bundle dataBundle=new Bundle();
DataBean dataObj=new DataBean();
dataObj.setDate();
try {
dataBundle.putByteArray("Obj_byte_array", object2Bytes(dataObj));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
dataIntent.putExtras(dataBundle);
startActivity(dataIntent);
}
객체를 바이트 배열로 변환
/**
* Converting objects to byte arrays
*/
static public byte[] object2Bytes( Object o ) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream( baos );
oos.writeObject( o );
return baos.toByteArray();
}
번들에서 개체 가져 오기 :
class SecondClass{
DataBean dataBean;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Your code...
//Get Info from Bundle...
Bundle infoBundle=getIntent().getExtras();
try {
dataBean = (DataBean)bytes2Object(infoBundle.getByteArray("Obj_byte_array"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
바이트 배열에서 객체를 가져 오는 방법 :
/**
* Converting byte arrays to objects
*/
static public Object bytes2Object( byte raw[] )
throws IOException, ClassNotFoundException {
ByteArrayInputStream bais = new ByteArrayInputStream( raw );
ObjectInputStream ois = new ObjectInputStream( bais );
Object o = ois.readObject();
return o;
}
이것이 다른 친구들에게 도움이되기를 바랍니다.
1. 매우 직접적이고 사용하기 쉬운 예제로 전달 될 객체가 Serializable을 구현하도록합니다.
class Object implements Serializable{
String firstName;
String lastName;
}
2. 번들 객체 전달
Bundle bundle = new Bundle();
Object Object = new Object();
bundle.putSerializable("object", object);
3. Serializable로 번들에서 객체를 전달한 다음 Object로 캐스트합니다.
Object object = (Object) getArguments().getSerializable("object");
이것은 내 질문에 대한 매우 뒤늦은 대답이지만 계속 관심을 끌기 때문에 해결해야한다고 생각합니다. 이 답변의 대부분은 정확하며 작업을 완벽하게 처리합니다. 그러나 응용 프로그램의 요구 사항에 따라 다릅니다. 이 답변은이 문제에 대한 두 가지 해결책을 설명하는 데 사용됩니다.
서비스는 다음에서 장기 실행 작업을 수행 할 수있는 응용 프로그램 구성 요소입니다. 배경이며 사용자 인터페이스를 제공하지 않습니다.서비스는보다 쉽게 제어 할 수있는보다 정의 된 수명주기를 가지고 있다는 점에서 깔끔합니다. 또한 필요한 경우 서비스를 응용 프로그램의 외부에서 실행할 수 있습니다 (예 : 부팅시). 이는 일부 앱 또는 깔끔한 기능에 필요할 수 있습니다.
이것은 둘 중 하나에 대한 완전한 설명은 아니지만 더 조사하고 싶은 사람들을 위해 문서 링크를 남겼습니다. 전반적으로 Service
SPP 장치에 ServerSocket을 실행하는 데 필요한 인스턴스가 더 좋습니다.
Date 객체를 전달하는 방법을 찾고있을 때이 질문을 보았습니다. 제 경우에는 답변 중 제안 된 것처럼 Bundle.putSerializable ()을 사용했지만 원래 게시물에서 설명한 DataManager처럼 복잡한 작업에는 작동하지 않습니다.
DataManager를 Application에 넣거나 Singleton으로 만드는 것과 매우 유사한 결과를 제공하는 내 제안은 Dependency Injection을 사용하고 DataManager를 Singleton 범위에 바인딩하고 필요한 곳에 DataManager를 삽입하는 것입니다. 증가 된 테스트 가능성의 이점을 얻을 수있을뿐만 아니라 "클래스와 활동간에 종속성을 전달"하는 모든 보일러 플레이트없이 더 깨끗한 코드를 얻을 수 있습니다. (Robo) Guice 는 작업하기가 매우 쉽고 새로운 Dagger 프레임 워크도 유망 해 보입니다.