인텐트의 복잡한 데이터 전달
이 섹션 소개:
이전 섹션에서 우리는 Intent의 몇 가지 기본 사용법을 배웠고 Intent의 7가지 속성, 명시적 Intent 및 Intent에 대해 배웠습니다. 암시적 인텐트, 암시적 인텐트를 사용자 정의하는 방법, 그리고 마지막으로 일반적으로 사용되는 시스템 인텐트를 제공합니다! 이번 섹션에서는 인텐트 전달 데이터의 문제에 대해 설명하겠습니다~좋아, 이번 섹션부터 시작하겠습니다~
1. 인텐트는 간단한 데이터를 전달합니다
Activity A 방식에서 두 가지 활동을 통해 서로 통신하는 방법을 배웠다는 것을 기억하세요. 간단한 데이터를 전달하려면?
Intent의 putExtra() 메소드를 호출하여 데이터를 직접 저장할 수 있으며, Intent를 가져온 후 getXxxExtra를 호출할 수 있습니다. 해당 유형의 데이터, 여러 개가 전달되면 Bundle 객체를 컨테이너로 사용하고 먼저 Bundle의 putXxx를 호출하여 데이터를 전송할 수 있습니다. Bundle에 저장한 후 Intent의 putExtras() 메소드를 호출하여 Bundle을 Intent에 저장하고 Intent를 얻은 후, 번들 컨테이너를 얻으려면 getExtras()를 호출하고 해당 데이터를 얻으려면 getXXX를 호출하세요! 게다가 데이터 저장은 Map의 <키, 값>과 다소 유사합니다!
2. 인텐트가 배열을 통과함
헤헤 일반형도 문제없지만 배열이면 어떨까요? 해결책은 다음과 같습니다:
Write into the array:
//StringArray는 다음으로 대체될 수 있습니다. int, float 등과 같은 다른 데이터 유형...
배열 읽기:
3 인텐트는 컬렉션을 전달합니다
음, 배열 아주 간단하니 다시 컬렉션을 전달해 볼까요~ 이건 좀 더 복잡하고 상황에 따라 처리됩니다:
1) List<기본 데이터 유형 또는 문자열>
Write the 컬렉션:
intent.putIntegerArrayListExtra(이름, 값)
컬렉션 읽기:
intent.getIntegerArrayListExtra(이름 )
2) List< Object> ;
목록을 직렬화 가능한 유형으로 만든 다음 전달합니다(번들은 매체로 사용할 수 있음)
컬렉션 작성:
컬렉션 읽기:
PS: Object 클래스는 직렬화 가능 인터페이스를 구현해야 합니다.
3) Map 또는 더 복잡한
해결책은 다음과 같습니다. 외부 레이어에 목록 넣기
Map
map1.put("key1", "value1");
List
list.add(map1);
Intent 의도 = new Intent(); MainActivity.this ,ComplexActivity.class);
Bundle Bundle = new Bundle();
//Burnle에서 전달해야 하는 ArrayList<Object>를 전달하려면 목록을 정의해야 합니다.
ArrayList Bundlelist = new ArrayList () ;
bundlelist.add(list);
bundle.putParcelableArrayList("list",bundlelist);
intent.putExtras(bundle); 객체를 전달하는 방법에는 객체를 Json 문자열로 변환하거나 직렬화하는 두 가지 유형이 있습니다. 직렬화 가능 및 Parcelable을 통해 Android에 내장된 Json 파서를 사용하지 않는 것이 좋습니다. fastjson 또는 Gson 타사 라이브러리를 사용할 수 있습니다!
1) 객체를 Json 문자열로 변환
Gson 구문 분석 예: Model:
public class Author{ private int id private String name; /...
}public class Author{ private int id;
private String name;쓰기 데이터:
Book book=new Book();
book.setTitle ("Java 프로그래밍 생각");
저자 작성자=new Author();
book.setAuthor(저자);Intent 의도=새 의도(this,SecondActivity) .class);intent.putExtra("book",new Gson().toJson(book));
startActivity(intent);读取数据:
Book book=new Gson().fromJson(bookJson,Book.class);
Log.d(TAG," 책 제목->"+book.getTitle());
Log.d(TAG,"책 저자 이름->"+book.getAuthor().getName());
2) Serialized, Parcelable을 사용하여 객체 직렬화
1. 직렬화 가능 구현:
① 비즈니스 Bean 구현: 직렬화 가능 인터페이스, getter 및 setter 메소드 작성
②Intent 호출 putExtra(문자열 이름, 직렬화 가능 값) 전달 객체 인스턴스 물론, 여러 객체가 있는 경우 먼저 Bundle.putSerialized(x,x);
③새 Activity가 getSerializedExtra() 메서드를 호출하여 객체 인스턴스를 얻을 수도 있습니다. 예:Product pd = (Product) getIntent().getSerializedExtra("Product");
4해당 매개변수를 얻기 위해 객체 get 메소드를 호출합니다
2. Parcelable 구현:
일반 프로세스:
① 비즈니스 Bean은 Parcelable 인터페이스를 상속하고 writeToParcel 메소드를 재정의하며 객체를 Parcel 객체로 직렬화합니다.
② explainContents 메소드, 컨텐츠 인터페이스 설명을 다시 작성하고 기본적으로 0을 반환합니다.
③ 정적 내부 객체 CREATOR를 인스턴스화합니다. Parcelable 인터페이스를 구현하세요
4같은 방식으로 Intent의 putExtra() 메소드를 통해 객체 인스턴스가 전달됩니다. 물론 객체가 여러 개인 경우 먼저 할 수 있습니다. Bundle.putParcelable(x,x)에 넣은 다음 Intent.putExtras()
몇 가지 설명:
writeToParcel을 통해 개체를 Parcel 개체에 매핑한 다음 createFromParcel을 통해 Parcel 개체를 매핑합니다. 당신의 대상이 되십시오. Parcel을 스트림으로 생각하고 writeToParcel을 통해 스트림에 개체를 쓸 수도 있습니다. createFromParcel을 통해 스트림에서 객체를 읽지만 이 프로세스에서는 이를 구현해야 하므로 작성하세요. 순서와 읽는 순서가 일관되어야 합니다.
Parcelable 인터페이스 구현을 위한 코드 예:
}
@Override
public void writeToParcel(Parcel parcel, int flags){
parcel.writeString(bookName);
parcel.writeString(작성자);
parcel.writeInt(publishTime);
}
public static final Parcelable.Creator<Book> CREATOR = 새 Creator<Book>() {
@Override
public Book[] newArray(int size) {
새 책[크기] 반환;
}
@Override
public Book createFromParcel(Parcel source) {
Book mBook = new Book();
mBook.bookName = source.readString();
mBook.author = source.readString();
mBook.publishTime = source.readInt();
mBook 반환;
}
};
Android Studio에서는 Parcleable 플러그인을 생성합니다.
Intellij/Andriod Studio 플러그인 android-parcelable-intellij-plugin ALT+Insert를 누르면 Parcleable 인터페이스 코드를 직접 생성할 수 있습니다.
또한, Parcelable 객체는 Android에서 널리 사용되며 Parcable 인터페이스를 구현하는 것은 매우 번거로울 수 있습니다. 타사 오픈 소스 프레임워크: Parceler, Maven 문제 때문에 아직 시도하지 않았습니다.
참조 주소:[안드로이드의 Parcelable 자동 생성]
3. 두 가지 직렬화 방법 비교:
두 가지 방법 비교:
- 1) 메모리를 사용할 경우 Parcelable이 Serialized High보다 성능이 좋으므로 Parcelable을 사용하는 것이 좋습니다.
- 2) 직렬화 가능은 직렬화 중에 많은 수의 임시 변수를 생성하므로 GC가 자주 발생합니다.
- 3) Parcelable은 데이터의 무결성을 보장할 수 없기 때문에 데이터를 디스크에 저장할 때 Parcelable을 사용할 수 없습니다. 외부 세계의 변화에도 불구하고 지속성. 직렬화 가능은 덜 효율적이지만 현재로서는 여전히 직렬화 가능을 사용하는 것이 좋습니다.
5. Intent는 Bitmap을 전달합니다.
bitmap은 기본적으로 Parcelable 인터페이스를 구현하므로 직접 전달할 수 있습니다.
구현 코드:
Intentintent = new Intent();
Bundle Bundle = new Bundle();
bundle.putParcelable("bitmap", bitmap);
intent.putExtra("bundle", Bundle);
6. 전역 데이터를 직접 정의하는 것이 불편합니다.
간단한 데이터를 전달하는 경우 Activity1 -> Activity2 -> Activity의 특정 데이터를 Activity4로 전달하고 싶습니다. 어떻게 페이지에서 페이지로 전달하시겠습니까?
물론 비과학적이겠죠? 특정 데이터를 어디서나 사용할 수 있게 하려면 Application 전역 객체 사용을 고려해 보세요!
안드로이드 시스템은 각 프로그램이 실행될 때 Application 개체를 생성하며 하나만 생성되므로 Application 싱글톤 패턴의 클래스로, 전체 프로그램 중 Application 객체의 수명이 가장 길다. 기간은 본 프로그램의 수명주기와 동일합니다. 더 많은 정적 값(고정 및 변경 불가능, 변경 가능)을 저장하려는 경우 애플리케이션에는 Application 클래스를 구현하고 인스턴스화되는 사용자 정의 애플리케이션임을 시스템에 알리기 위해 사용자 정의 클래스가 필요합니다. 시스템 기본값 대신 이 단계에서는 AndroidManifest.xml의 애플리케이션 태그에 name 속성 을 추가합니다.
코드의 주요 부분:
1) 사용자 정의 애플리케이션 클래스:
private String myState;
public String getState(){
return myState;
}
public void setState(문자열 s){
myState = s;
}
}
2) AndroidManifest.xml의 명령문:
android:label="@string/app_name">
3) 필요한 곳에 전화하세요:
@Override
public void onCreate(Bundle b){
.. .
MyApp appState = ((MyApp)getApplicationContext());
문자열 상태 = appState.getState();
...
}
}
고화질 쓰기 방법
: 애플리케이션 전역 개체는 어느 위치에서나 얻을 수 있습니다.Applicaiton은 시스템의 구성 요소이며 자체 수명 주기도 있습니다. onCraete에서 이를 얻을 수 있습니다. 응용 프로그램 개체입니다. 수정된 코드를 게시하세요! YClass MyApp 확장 애플리케이션 {
Private String Mystate;onCreate();
인스턴스 = this;
그런 다음 어디에서나 MyApp.getInstance()를 직접 호출하여 애플리케이션의 전역 개체를 가져올 수 있습니다!
참고:
Application 개체는 메모리에 존재하며 다음 시나리오와 같이 시스템에 의해 종료될 수 있습니다.
사용자 계정을 Activity1의 애플리케이션에 저장한 다음 사용자 계정을 Activity2를 표시해 보세요!
홈 버튼을 클릭한 후 N을 오래 기다린 후 시스템은 메모리를 회수하기 위해 앱을 종료합니다. 이때 우리는 다시 이 앱을 열면 이때는 마법처럼 보입니다. Activity2 페이지로 돌아가지만 이때 애플리케이션을 다시 받으면 프로그램 내 사용자 계정에서 NullPointerException이 발생하고 Crash가 발생합니다~
위의 Crash가 발생하는 이유는 Application 객체가 새로 생성되었기 때문이라고 생각하시면 됩니다. 실제로는 그렇지 않습니다. 새 애플리케이션을 만든 다음 사용자가 마지막으로 떠날 때 활동을 시작하여 앱을 만듭니다. 죽는다는 환상은 없습니다! 따라서 더 중요한 데이터라면 현지화하여 활용하는 것이 좋습니다. 변수 값이 null이 아닌지 확인해야 합니다! 또 다른 요점은 이것이 애플리케이션 변수뿐만 아니라 싱글톤 개체 및 공용 정적 변수에도 적용된다는 것입니다. 이렇게 됩니다~
7. 싱글톤 모드 매개변수 전달
위 애플리케이션은 싱글톤을 기반으로 하며 시스템에 클래스의 인스턴스가 하나만 있음을 보장할 수 있다는 것입니다. A에서 매개변수를 설정하고 B에서 직접 액세스하면 매우 쉽게 달성할 수 있습니다. 이는 여러 가지 방법 중 가장 효율적입니다.
예제 코드: (코드는 인터넷에서 제공됩니다~)
① 단일 케이스 클래스 정의:
Instance = New XClsingleton ()
}
Return Instance;
mmap = 새로운 해시맵 & LT; 문자열, 개체 및 GT()
}
}
public void put(문자열 키, 개체 값){
{
}
}
②매개변수 설정: