English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
이 기사는 Android intent 간 복잡한 매개변수 전달 방법을 자세히 설명합니다. 여러분과 공유하고자 합니다:
Intent는 Activity와 Activity 간, Activity와 Service 간에 매개변수를 전달하는 매개체이며, 이 두 가지는 일반적으로 Java 기본 객체 타입과 String의 전달을 구현합니다.
실제 프로젝트에서 페이지 간 값을 전달할 때, 위에 설명한 것 외에도 Object 객체, List 타입, List<Object> 타입, 전역 변수 등을 전달하는 필요성이 종종 있습니다. 이 기사는 이러한 유형의 매개변수를 전달하는 방법을 설명합니다.
1. List<String>와 List<Integer>를 전달
다음은 List<String>를 전달하는 예제로, List<String>를 보내는 문법은 다음과 같습니다:
intent.putStringArrayListExtra(key, list);
List<String>를 받는 문법은 다음과 같습니다:
list = (ArrayList<String>)getIntent().getStringArrayListExtra(key);
다음은 응용 예제입니다:
// =============List<String>를 보내기============= ArrayList<String> stringList = new ArrayList<String>(); stringList.add("string1"); stringList.add("string2"); stringList.add("string3"); Intent intent = new Intent(); intent.setClass(ListDemoActivity.this, StringListActivity.class); intent.putStringArrayListExtra("ListString", stringList); startActivity(intent); // ====================List<String>를 받기====================== ArrayList<String> stringList = (ArrayList<String>) getIntent().getStringArrayListExtra("ListString");
List<Integer>와 유사한 작업을 호출하여 아래의 메서드를 사용하여 전송 및 수신도 가능합니다:
intent.putIntegerArrayListExtra(key, list); list = (ArrayList<Integer>) getIntent().getIntegerArrayListExtra(key);
2. Serializable와 Parcelable 두 가지 방식으로 Object 전달
Android의 Intent 간 객체 전달은 두 가지 방법이 있습니다. 하나는 Bundle.putSerializable(Key, Object); 다른 하나는 Bundle.putParcelable(Key, Object);입니다. 메서드의 Object는 특정 조건을 만족해야 합니다. 전자는 Serializable 인터페이스를 구현해야 하며, 후자는 Parcelable 인터페이스를 구현해야 합니다.
以下是实现了Serializable接口的User类,命名为SerializableUser纯粹是从类名方便区分实现了Parcelable接口的User类,实际开发中不建议这么命名:
public class SerializableUser implements Serializable { private String userName; private String password; public SerializableUser() { } public SerializableUser(String userName, String password) { this.userName = userName; this.password = password; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
以下是实现了Parcelable接口的User类:
public class ParcelableUser implements Parcelable { private String userName; private String password; public ParcelableUser() { } public ParcelableUser(String userName, String password) { this.userName = userName; this.password = password; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public static final Parcelable.Creator<ParcelableUser> CREATOR = new Creator<ParcelableUser>() { @Override public ParcelableUser createFromParcel(Parcel source) { ParcelableUser parcelableUser = new ParcelableUser(); parcelableUser.userName = source.readString(); parcelableUser.password = source.readString(); return parcelableUser; } @Override public ParcelableUser[] newArray(int size) { return new ParcelableUser[size]; } }; @Override public int describeContents() { // TODO 자동-생성된 메서드 스탑 return 0; } @Override public void writeToParcel(Parcel dest, int flags) { // TODO 자동-생성된 메서드 스탑 dest.writeString(userName); dest.writeString(password); } }
두 가지 방식으로 사용전달의 문법은 다음과 같습니다:
bundle.putSerializable(key,object); bundle.putParcelable(key,object);
두 가지 방식으로 사용수신의 문법은 다음과 같습니다:
object=(Object) getIntent().getSerializableExtra(key); object = (Object) getIntent().getParcelableExtra(key);
// ==========Serializable와 Parcelable를 사용하여 Object 전송=================== SerializableUser serializableUser = new SerializableUser("user"1", "123456"); ParcelableUser parcelableUser = new ParcelableUser("user"2""654321"); Intent intent = new Intent(); Bundle bundle = new Bundle(); bundle.putSerializable("serializableUser", serializableUser); bundle.putParcelable("parcelableUser", parcelableUser); intent.setClass(ListDemoActivity.this, ObjectActivity.class); intent.putExtras(bundle); startActivity(intent); // ====================Object 수신====================== SerializableUser serializableUser = (SerializableUser) getIntent().getSerializableExtra("serializableUser"); ParcelableUser parcelableUser = (ParcelableUser) getIntent().getParcelableExtra("parcelableUser");
누군가가 Serializable 인터페이스를 구현하면 객체를 시리얼라이즈하고 전달하는 것을 알아챕니다. Java의 일반적인 프로그래밍과 명확한 차이가 없으며 User는 명확히 변경되지 않아 간단합니다. 저도 이 방식을 추천합니다.
그러나 Parcelable 인터페이스를 구현한 후자의 클래스는 더 복잡합니다. Parcelable는 무엇인가요?
Android는 데이터를 포장하는 컨테이너로 사용되는 새로운 타입: Parcel을 제공합니다. 포장된 데이터는 Intent나 IPC를 통해 전달될 수 있습니다. 기본 타입 외에 Parcelable 인터페이스를 구현한 클래스 만 Parcel에 넣을 수 있습니다.
实现Parcelable接口需要实现三个方法:
1)writeToParcel 方法。该方法将类的数据写入外部提供的Parcel中。
声明:writeToParcel (Parcel dest, int flags)。
2)describeContents方法。直接返回0就可以。
3)静态的Parcelable.Creator<T>接口,本接口有两个方法:
createFromParcel(Parcel in) 实现从in中创建出类的实例的功能。
newArray(int size) 创建一个类型为T,长度为size的数组, returnnew T[size];即可。本方法是供外部类反序列化本类数组使用。
通过log测试输出可知程序的运行情况,在bundle.putParcelable("parcelableUser", parcelableUser);时,调用了ParcelableUser类中的publicvoid writeToParcel(Parcel dest, int flags)方法,并向dest写数据,在 ParcelableUserparcelableUser= (ParcelableUser)getIntent().getParcelableExtra("parcelableUser");的时候,调用了ParcelableUser类中的public ParcelableUsercreateFromParcel(Parcel source) 方法,创建了一个ParcelableUser对象,并给这个对象的属性赋值,这里的Parcel source和Parcel dest是相同的,然后返回这个ParcelableUser对象。最后就可以打印出parcelableUser的属性信息了。
三、传递List<Object>
如果要传递由Object组成的List列表,即List<Object>,该怎么办呢?首先需要将Object对象实现Serializable接口,然后把list强制类型转换成Serializable类型,最后通过:
Intent.putExtra(key, (Serializable)objectList);
이와 같은 문법으로 전달되며, 수신 측에서도 List<Object>로 강제 변환해야 합니다. List<Object>를 사용하는 문법은 다음과 같습니다:
objectList= (List<Object>) getIntent().getSerializableExtra(key);
다음은 응용 프로그램 예제로, 이번에는SerializableUser 클래스는 이전 단계에서 제공되었으므로 다시 제공하지 않습니다.
// ============== List<Object> 전송 ============ SerializableUser user1 = new SerializableUser("user1", "123456"); SerializableUser user2 = new SerializableUser("user2", "654321"); List<SerializableUser> objectList = new ArrayList<SerializableUser>(); objectList.add(user1); objectList.add(user2); Intent intent = new Intent(); intent.setClass(ListDemoActivity.this, ObjectListActivity.class); intent.putExtra("ListObject", (Serializable) objectList); startActivity(intent); // ==================== List<Object> 수신 ===================== List<SerializableUser> objectList = (List<SerializableUser>) getIntent().getSerializableExtra("ListObject");
4. 전역 변수
특정 애플리케이션 등급의 파라미터가 intent를 통해 전달하기 불편할 때, 전역 변수나 정적 변수를 사용할 수 있을까 생각할까? Java의 정적 변수는 여기에 적합하지만, Activity가 System.exit(0)나 finish()를 호출하면 값이 사라진다.
그리고 android에서는 ApplicationContext를 사용하는 더 우아한 방법이 있다. 이 전역 변수 메서드는 정적 클래스보다 보다 안전하며, 모든 Activity가 destroy되기 전까지는 해제되지 않는다.
Android의 SDK에는 Application이 전역 변수를 저장하기 위한 것이며, package가 생성되는 순간부터 존재한다고 적혀 있다. 따라서 전역 변수를 생성할 때는 J와 같이 다시 생성할 필요가 없다.2SE와 같이 public 권한의 static 변수를 생성해야 하는 경우, application에서 직접 구현하면 됩니다. Context.getApplicationContext 또는 Activity.getApplication 메서드를 호출하여 Application 객체를 얻으면, 전역 변수의 값을 설정하거나 읽을 수 있습니다.
Application을 시작할 때, 시스템이 PID(프로세스 ID)를 생성하며, 모든 Activity는 이 프로세스에서 실행됩니다. 따라서 Application이 생성될 때 전역 변수를 초기화하면, 같은 애플리케이션의 모든 Activity가 이 전역 변수의 값을 가져올 수 있습니다. 다시 말해, 어떤 Activity에서 전역 변수의 값을 변경하면, 같은 애플리케이션의 다른 Activity에서도 값이 변경됩니다.
사용법:
1자신만의 android.app.Application의 서브 클래스를 생성하여, 공유하고자 하는 private 전역 변수에 setter와 getter 메서드를 추가합니다.
public class MyApp extends Application{ private String globalVariable; public String getGlobalVariable() { return globalVariable; } public void setGlobalVariable(String globalVariable) { this.globalVariable = globalVariable; } }
2manifest에서 이 클래스를 선언하면, Android가 이를 통해 전역으로 사용할 수 있는 인스턴스를 생성합니다.
실제로는 기존에 있는 단 하나의 application 태그에 application에 이름을 지정하는 것입니다.
<application android:name=".MyApp" android:icon="@drawable/icon" android:label="@string/app_name">
3Context.getApplicationContext() 메서드를 사용하여 이 인스턴스를 얻고, 그 안의 상태(변수)를 얻을 수 있습니다.
// ============全局变量传递参数============== MyApp myApp = ((MyApp) getApplicationContext());//우리의 애플리케이션 MyApp을 얻습니다. myApp.setGlobalVariable("전역 변수"); Intent intent = new Intent(); intent.setClass(ListDemoActivity.this, GlobalActivity.class); startActivity(intent); // ============ 전역 변수를 수신하는 파라미터 ============= MyApp myApp = ((MyApp) getApplicationContext()); String globalVariable = myApp.getGlobalVariable();
Android 관련 내용에 더 관심이 있는 독자는 다음 웹사이트의 특집을 확인할 수 있습니다.:《Android 개발 입문 및 고급 교본》、《Android 프로그래밍에서 activity 작업 기술 요약》、《Android 자원 작업 기술 요약》、《Android 파일 작업 기술 요약》、《Android SQLite 데이터베이스 작업 기술 요약》、《Android json 형식 데이터 작업 기술 요약》、《Android 데이터베이스 작업 기술 요약》、《Android 프로그래밍에서 SD 카드 작업 방법 요약》、《Android 뷰 View 기술 요약》 및 《Android 컨트롤러 사용 요약》
본 글의 내용이 여러분의 Android 프로그램 설계에 도움이 되길 바랍니다.
고지: 본 글의 내용은 인터넷에서 가져왔으며, 저작권은 원작자에게 있으며, 인터넷 사용자가 자발적으로 기여하고 업로드한 내용입니다. 본 웹사이트는 소유권을 가지지 않으며, 인공적으로 편집한 것이 아니며, 관련 법적 책임도 부담하지 않습니다. 저작권 침해가 의심되는 내용이 있다면, notice#w로 이메일을 보내 주세요.3codebox.com에 이메일을 보내서 신고해 주세요. (#을 @으로 변경해 주세요.) 관련 증거를 제공하면, 해당 콘텐츠가 저작권 침해로 확인되면 즉시 해당 콘텐츠를 삭제할 것입니다.