[Android] TransactionTooLargeException
A액티비티에서 어떤 데이터를 B액티비티에 전달하고자 할 때,
A액티비티에서 Intent.putExtra()를 이용해 인텐트에 데이터를 넣고,
startActivity()를 이용해 B액티비티에 데이터를 전달함과 동시에 B액티비티를 실행한다.
그러나, intent.putExtra()에 들어갈 수 있는 데이터의 크기는 무한정하지 않다.
공식 문서를 살펴보면, 이러한 방식으로 매우 큰 데이터가 입력될 경우 TransactionTooLargeException이 발생함을 명시하고 있다.
(한 프로세스가 공유하는 트랜젝션 버퍼에 1MB 넘게 입력할 때 이런 문제가 발생한다고 한다. 보통 Bitmap이나 길이가 긴 배열을 입력하려 할 때 발생한다)
If the arguments or the return value are too large to fit in the transaction buffer, then the call will fail and TransactionTooLargeException will be thrown.
The Binder transaction buffer has a limited fixed size, currently 1Mb, which is shared by all transactions in progress for the process.
그렇다면 매우 큰 데이터를 액티비티간 전달하고 싶을 때, 어떻게 해야 할까?
1. 큰 데이터를 작은 리퀘스트 단위로 쪼개서 처리하거나 압축 등을 통하여 데이터의 사이즈를 줄이기
이 방법은 설명하지 않을 것이다.
압축 알고리즘 등은 이 포스트에서 설명하지 않을 것이므로...
2. static변수에 쓰고 읽어오기
별도의 Dataholder클래스를 만들고 내부에 static변수를 만들어서 해당 인스턴스를 통해 get/set하는 방법이다.
가령 다음과 같은 모습이 될 수 있다.
public class DataHolder{
private static String str;
public static void setStr(String str){
DataHolder.str= str;
}
public static void getStr(){
return str;
}
}
그러나 이와 같은 패턴을 사용할 때는 백그라운드에서 앱이 Kill된 이후, 복구되었을 때의 상황을 반드시 고려해야 한다.
참고: https://satisfactoryplace.tistory.com/101
3. 파일로 저장하고 읽어오기
공유하려는 데이터를 A액티비티에서 File에 직렬화하여 저장하고, B액티비티에서 다시 파일을 역직렬화하여 읽어와서 사용하는 방법이다.
그러나 이 방법은 사용자로부터 File Read/Write권한을 위임받아야 하고,
저장장치의 속도가 느린 디바이스의 경우 오랜 시간이 걸려 사용자 경험을 해칠 수 있다.