트랜잭션에서 수행할 작업너무 큼 예외
는 요.TransactionTooLargeException재현할 수 없습니다.에 류상으서라고 써 .
바인더 트랜잭션이 너무 커서 트랜잭션에 실패했습니다.
원격 프로시저 호출 중에 호출의 인수와 반환 값은 바인더 트랜잭션 버퍼에 저장된 구획 객체로 전송됩니다.인수 또는 반환 값이 너무 커서 트랜잭션 버퍼에 들어가지 않으면 호출이 실패하고 트랜잭션이 수행됩니다.TooLargeException이 느려집니다.
...
원격 프로시저 호출로 트랜잭션이 발생할 경우 두 가지 결과가 발생할 수 있습니다.예외가 너무 큽니다.클라이언트가 요청을 서비스로 전송할 수 없거나(인수가 너무 커서 트랜잭션 버퍼에 맞지 않는 경우가 대부분), 서비스가 응답을 클라이언트로 다시 전송할 수 없습니다(반환 값이 너무 커서 트랜잭션 버퍼에 맞지 않는 경우가 대부분).
...
그래서 저는 어딘가에서 알려지지 않은 한계를 초과하는 주장을 전달하거나 받고 있습니다.어디?
스택 추적은 유용한 내용을 보여주지 않습니다.
java.lang.RuntimeException: Adding window failed
at android.view.ViewRootImpl.setView(ViewRootImpl.java:548)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:406)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:320)
at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:152)
at android.view.Window$LocalWindowManager.addView(Window.java:557)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2897)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$600(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4977)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.os.TransactionTooLargeException
at android.os.BinderProxy.transact(Native Method)
at android.view.IWindowSession$Stub$Proxy.add(IWindowSession.java:569)
at android.view.ViewRootImpl.setView(ViewRootImpl.java:538)
... 16 more
android.os.TransactionTooLargeException
at android.os.BinderProxy.transact(Native Method)
at android.view.IWindowSession$Stub$Proxy.add(IWindowSession.java:569)
at android.view.ViewRootImpl.setView(ViewRootImpl.java:538)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:406)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:320)
at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:152)
at android.view.Window$LocalWindowManager.addView(Window.java:557)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2897)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2245)
at android.app.ActivityThread.access$600(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1262)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:4977)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
at dalvik.system.NativeStart.main(Native Method)
뷰와 관련이 있는 것 같습니까?원격 프로시저 호출과 어떤 관련이 있습니까?
중요할 수도 있습니다.안드로이드 버전: 4.0.3, 장치: HTC One X
이 문제가 발생하여 서비스와 애플리케이션 간에 대량의 데이터가 교환되는 경우(예: 미리 보기를 많이 전송해야 함)를 발견했습니다.실제로 데이터 크기는 약 500KB였으며 IPC 트랜잭션 버퍼 크기는 1024KB로 설정되어 있습니다.왜 그것이 트랜잭션 버퍼를 초과했는지 잘 모르겠습니다.
의도된 추가 정보를 통해 많은 데이터를 전달하는 경우에도 이 문제가 발생할 수 있습니다.
응용 프로그램에서 이 예외가 발생하면 코드를 분석하십시오.
- 서비스와 애플리케이션 간에 많은 데이터를 교환하고 있습니까?
- 대량의 데이터를 공유하기 위해 의도 사용(예: 사용자가 갤러리 공유 프레스 공유에서 엄청난 수의 파일을 선택하면 선택한 파일의 URI가 의도를 사용하여 전송됨)
- 서비스에서 비트맵 파일 수신
- Android가 대용량 데이터로 응답하기를 기다립니다(예: 사용자가 많은 애플리케이션을 설치할 때 설치된 애플리케이션()).
- 보류 중인 작업이 많은 applyBatch() 사용
이 예외가 발생할 때 처리 방법
가능하면 큰 작업을 작은 청크로 분할합니다. 예를 들어, 1000개의 작업으로 applyBatch()를 호출하는 대신 각각 100개씩 호출합니다.
서비스와 애플리케이션 간에 대용량 데이터(1MB 이상)를 교환하지 마십시오.
어떻게 하는지는 모르겠지만, 엄청난 데이터를 반환할 수 있는 안드로이드에 문의하지 마세요 :-)
충돌의 원인이 되는 구획을 조사해야 하는 경우에는 너무 큰 도구를 사용하는 것을 고려해야 합니다.
(승인된 답변 아래에 있는 @Max Spencer의 코멘트로 이것을 발견했고 제 경우에 도움이 되었습니다.)
이것은 확실한 답은 아니지만, 그것은 원인을 밝혀줄 수 있습니다.TransactionTooLargeException문제를 정확히 파악하는 데 도움이 됩니다.
대부분의 답변이 전송된 많은 양의 데이터를 참조하지만, 이 예외는 과도한 스크롤 및 확대/축소를 수행하고 ActionBar 스피너 메뉴를 반복적으로 연 후에 부수적으로 발생합니다.작업 표시줄을 누를 때 충돌이 발생합니다.(사용자 지정 매핑 앱입니다)
주변에 전달되는 데이터는 "입력 디스패처"에서 앱으로 터치하는 것뿐인 것 같습니다.저는 이것이 "트랜잭션 버퍼"에서 1MB에 가까운 것에 합리적으로 도달할 수 없다고 생각합니다.
내 앱은 쿼드코어 1.6GHz 장치에서 실행되고 있으며 무거운 들어올리기에 3개의 스레드를 사용하여 UI 스레드에 1개의 코어를 사용할 수 있습니다.게다가, 앱은 안드로이드를 사용합니다: largeHeap, 사용하지 않는 힙이 10mb 남아있고 힙을 키울 수 있는 공간이 100mb 남아있습니다.그래서 저는 그것이 자원 문제라고 말하지 않을 것입니다.
충돌 직전에는 항상 다음 행이 나옵니다.
W/InputDispatcher( 2271): channel ~ Consumer closed input channel or an error occurred. events=0x9
E/InputDispatcher( 2271): channel ~ Channel is unrecoverably broken and will be disposed!
E/JavaBinder(28182): !!! FAILED BINDER TRANSACTION !!!
반드시 그 순서대로 인쇄되는 것은 아니지만 (제가 확인한 바로는) 동일한 밀리초 단위로 인쇄됩니다.
스택 추적 자체는 명확하게 하기 위해 질문과 동일합니다.
E/AndroidRuntime(28182): java.lang.RuntimeException: Adding window failed
..
E/AndroidRuntime(28182): Caused by: android.os.TransactionTooLargeException
Android의 소스 코드를 자세히 조사하면 다음과 같은 줄을 찾을 수 있습니다.
frameworks/base/core/jni/android_util_Binder.cpp:
case FAILED_TRANSACTION:
ALOGE("!!! FAILED BINDER TRANSACTION !!!");
// TransactionTooLargeException is a checked exception, only throw from certain methods.
// FIXME: Transaction too large is the most common reason for FAILED_TRANSACTION
// but it is not the only one. The Binder driver can return BR_FAILED_REPLY
// for other reasons also, such as if the transaction is malformed or
// refers to an FD that has been closed. We should change the driver
// to enable us to distinguish these cases in the future.
jniThrowException(env, canThrowRemoteException
? "android/os/TransactionTooLargeException"
: "java/lang/RuntimeException", NULL);
트랜잭션이 너무 크다는 이유 이외의 다른 이유로 트랜잭션이 실패하는 문서화되지 않은 이 기능을 사용하는 것처럼 들립니다.을 름을지었했어요야라고 이름 .TransactionTooLargeOrAnotherReasonException.
이때는 문제를 해결하지 못했지만, 유용한 내용이 발견되면 이 답변을 업데이트하겠습니다.
업데이트: 내 코드가 일부 파일 설명자를 유출한 것으로 드러났으며, 그 수는 Linux에서 최대화됩니다(일반적으로 1024개). 이것이 예외를 트리거한 것으로 보입니다.결국 그것은 자원 문제였습니다.나는 열어서 이것을 통해 확인했습니다./dev/zero하여 UI 한 1024회의 .1024 UI에서조차 발생했습니다.파일/소켓을 열지 못하는 것은 Android 전체에서 매우 깨끗하게 처리/보고되는 것이 아닙니다.
그TransactionTooLargeException 동안 했습니다! 약 4개월동우괴고혔롭를리다우해그니마습결문했침제를리내는안개!▁has다니해습결했!▁issue문!
무슨 일이 일어났는지는 우리가 사용하고 있다는 것이었습니다.FragmentStatePagerAdapter순식간에ViewPager사용자는 페이지를 통해 100개 이상의 조각(읽기 응용프로그램)을 만듭니다.
비록 우리가 파편들을 적절하게 관리하지만,destroyItem()에서 Androids의 :FragmentStatePagerAdapter다음 목록에 대한 참조를 유지한 버그가 있습니다.
private ArrayList<Fragment.SavedState> mSavedState = new ArrayList<Fragment.SavedState>();
Android가 작동하지 않을 때FragmentStatePagerAdapter하려고 시도하며 를 상태를함호출수합다니를하면구하라고 .
@Override
public Parcelable saveState() {
Bundle state = null;
if (mSavedState.size() > 0) {
state = new Bundle();
Fragment.SavedState[] fss = new Fragment.SavedState[mSavedState.size()];
mSavedState.toArray(fss);
state.putParcelableArray("states", fss);
}
for (int i=0; i<mFragments.size(); i++) {
Fragment f = mFragments.get(i);
if (f != null && f.isAdded()) {
if (state == null) {
state = new Bundle();
}
String key = "f" + i;
mFragmentManager.putFragment(state, key, f);
}
}
return state;
}
보다시피, 당신이 의 단편들을 적절하게 관리하더라도.FragmentStatePagerAdapter 기본 해서 " " " ", " " " 를 합니다.Fragment.SavedState지금까지 만들어진 모든 조각들을 위해.TransactionTooLargeException해당 배열이 a로 덤프될 때 발생합니다.parcelableArrayOS는 100개 이상의 항목을 좋아하지 않을 것입니다.
그러므로 우리를 위한 해결책은 그것을 무시하는 것이었습니다.saveState()방법 및 저장하지 않음"states".
@Override
public Parcelable saveState() {
Bundle bundle = (Bundle) super.saveState();
bundle.putParcelableArray("states", null); // Never maintain any states from the base class, just null it out
return bundle;
}
거래 이유에 대한 답을 찾아 몹시 실망한 사람들을 위해.TooLargeException이 표시됩니다. 인스턴스 상태에서 저장하는 정보의 양을 확인해 보십시오.
컴파일/targetSdkVersion <= 23에서 저장된 상태의 큰 크기에 대한 내부 경고만 있을 뿐 충돌은 발생하지 않습니다.
E/ActivityThread: App sent too much data in instance state, so it was ignored
android.os.TransactionTooLargeException: data parcel size 713856 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:615)
at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:3604)
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3729)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6044)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
그러나 컴파일/targetSdkVersion >= 24에는 실제 런타임이 있습니다.이 경우 예외 충돌:
java.lang.RuntimeException: android.os.TransactionTooLargeException: data parcel size 713860 bytes
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3737)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6044)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
Caused by: android.os.TransactionTooLargeException: data parcel size 713860 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:615)
at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:3604)
at android.app.ActivityThread$StopInfo.run(ActivityThread.java:3729)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6044)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
무엇을 해야 하나?
로컬 데이터베이스에 데이터를 저장하고 이 데이터를 검색하는 데 사용할 수 있는 ID만 인스턴스 상태로 유지합니다.
이 예외는 일반적으로 앱을 백그라운드로 보낼 때 발생합니다.
그래서 저는 데이터 프래그먼트 패턴을 사용하여 데이터를 완전히 우회하기로 결정했습니다.onSavedInstanceState 솔루션은 빨리 확보합니다.또한 복잡한 인스턴스 상태를 처리하고 메모리를 최대한 빨리 확보할 수 있습니다.
먼저 데이터를 저장할 간단한 파지먼트를 만들었습니다.
package info.peakapps.peaksdk.logic;
import android.app.Fragment;
import android.app.FragmentManager;
import android.os.Bundle;
/**
* A neat trick to avoid TransactionTooLargeException while saving our instance state
*/
public class SavedInstanceFragment extends Fragment {
private static final String TAG = "SavedInstanceFragment";
private Bundle mInstanceBundle = null;
public SavedInstanceFragment() { // This will only be called once be cause of setRetainInstance()
super();
setRetainInstance( true );
}
public SavedInstanceFragment pushData( Bundle instanceState )
{
if ( this.mInstanceBundle == null ) {
this.mInstanceBundle = instanceState;
}
else
{
this.mInstanceBundle.putAll( instanceState );
}
return this;
}
public Bundle popData()
{
Bundle out = this.mInstanceBundle;
this.mInstanceBundle = null;
return out;
}
public static final SavedInstanceFragment getInstance(FragmentManager fragmentManager )
{
SavedInstanceFragment out = (SavedInstanceFragment) fragmentManager.findFragmentByTag( TAG );
if ( out == null )
{
out = new SavedInstanceFragment();
fragmentManager.beginTransaction().add( out, TAG ).commit();
}
return out;
}
}
그런 다음 주 활동에서 저장된 인스턴스 주기를 완전히 우회하고 데이터 조각에 대한 책임을 연기합니다.조각의 상태가 활동의 상태에 자동으로 추가되므로 조각 자체에 이 기능을 사용할 필요가 없습니다.)
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
SavedInstanceFragment.getInstance( getFragmentManager() ).pushData( (Bundle) outState.clone() );
outState.clear(); // We don't want a TransactionTooLargeException, so we handle things via the SavedInstanceFragment
}
남은 것은 저장된 인스턴스를 팝업하는 것입니다.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(SavedInstanceFragment.getInstance(getFragmentManager()).popData());
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState( SavedInstanceFragment.getInstance( getFragmentManager() ).popData() );
}
전체 세부 정보: http://www.devsbedevin.net/avoiding-transactiontoolargeexception-on-android-nougat-and-up/
이 문제의 구체적인 원인은 하나도 없습니다.저는 프래그먼트 수업에서 다음과 같이 했습니다.
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View rootView = inflater.inflate(R.layout.snacks_layout, container); //<-- notice the absence of the false argument
return rootView;
}
이 대신에:
View rootView = inflater.inflate(R.layout.softs_layout, container, false);
장치 기능이나 앱에 관계없이 트랜잭션 버퍼가 1MB로 제한된다는 것을 이해하는 것이 중요합니다.이 버퍼는 사용자가 호출하는 모든 API 호출에 사용되며 앱이 현재 실행 중인 모든 트랜잭션에서 공유됩니다.
합니다.(Parcel.obtain()) 그서항일는것중이다요니합키시치래상▁every▁match다니▁so중▁always를 일치시키는 것이 중요합니다.obtain()recycle().
반환된 데이터가 1MB 미만임에도 불구하고(다른 트랜잭션이 여전히 실행 중인 경우) 많은 데이터를 반환하는 API 호출에서 이 오류가 쉽게 발생할 수 있습니다.
를 들면, 를들어예,,PackageManager.getInstalledApplication()설치된 합니다.call은 설치된 앱의 목록입니다.특정 플래그를 추가하면 많은 추가 데이터를 검색할 수 있습니다.이렇게 하면 실패할 가능성이 있으므로 추가 데이터를 검색하지 말고 앱별로 검색하는 것이 좋습니다.
실패할 도 있기 에 통화를 합니다.catch필요한 경우 다시 시도할 수 있습니다.
제가 알기로는 이러한 문제에 대한 해결 방법은 가능한 한 적은 정보를 검색하는 것 외에는 없습니다.
저도 삼성 S3에서 이 예외를 받았습니다.두 가지 근본 원인이 의심됩니다
- 로드하고 메모리를 너무 많이 차지하는 비트맵이 있습니다. 다운사이징을 사용하십시오.
- drawable-_dpi 폴더에 드로잉 가능한 항목이 몇 개 누락되어 있고, Android가 드로잉 가능한 항목을 찾고 크기를 조정하여 컨텐츠 뷰 세트가 갑자기 점프하고 메모리를 많이 사용하게 합니다.
DDMS를 사용하고 앱을 재생할 때 힙을 보면 어떤 세트 콘텐츠 뷰가 문제를 만들고 있는지 알 수 있습니다.
문제 2를 제거하기 위해 모든 폴더에 걸쳐 모든 드로잉 가능한 것을 복사했습니다.
문제가 해결되었습니다.
활동에 추가
@Override
protected void onSaveInstanceState(Bundle oldInstanceState) {
super.onSaveInstanceState(oldInstanceState);
oldInstanceState.clear();
}
그것은 나에게 효과가 있고 또한 그것이 당신에게 도움이 되기를 바랍니다.
활동 "A"에 조각이 있을 수 있고 활동 "B"로 이동할 때 발생할 수 있습니다.
그러면 활동 "A"의 활동 수명 주기는 다음과 같습니다.
OnResume->OnPause()->OnSavedInstanceState()
여기 OnSavedInstanceState에서는 너무 많은 데이터로 상태를 저장할 수 없기 때문에 충돌이 발생할 수 있습니다. 따라서 다음 코드를 추가하여 활동 "A"의 saveInstance를 지우려고 합니다.
@Override
protected void onSaveInstanceState(Bundle oldInstanceState) {
super.onSaveInstanceState(oldInstanceState);
if (oldInstanceState != null) {
oldInstanceState.clear();
}
}
우리 앱에도 이런 문제가 있습니다.테스트 후 애플리케이션 메모리가 부족하고 활동이 재활용되면 시스템에서 onSaveInstanceState 메서드를 호출하여 대량의 번들 데이터를 저장하고 매번 데이터가 커지며 마지막으로 트랜잭션이 발생합니다.TooLargeException 오류가 보고될 것이므로 이 방법으로 이 문제를 해결할 수 있어야 한다고 생각합니다.
public final int MAX_BUNDLE_SIZE = 300;
@Override
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
long bundleSize = getBundleSize(outState);
if (bundleSize > MAX_BUNDLE_SIZE * 1024) {
outState.clear();
}
}
private long getBundleSize(Bundle bundle) {
long dataSize;
Parcel obtain = Parcel.obtain();
try {
obtain.writeBundle(bundle);
dataSize = obtain.dataSize();
} finally {
obtain.recycle();
}
return dataSize;
}
그래서 우리는 AIDL 인터페이스를 통해 원격 서비스로 너무 큰 물체를 보내려고 했습니다.트랜잭션 크기는 1MB를 초과할 수 없습니다.요청은 512KB의 별도 청크로 분할되어 한 번에 하나씩 인터페이스를 통해 전송됩니다.잔인한 해결책을 알고 있지만 이봐 - 안드로이드야 :(
인텐트를 통해 비트맵을 전송하려고 할 때와 애플리케이션을 접었을 때 동일한 문제가 발생했습니다.
이 문서에서 설명한 링크 설명을 여기에 입력합니다. 이는 활동이 중지되는 과정에서 발생합니다. 즉, 나중에 복원을 위해 안전하게 보관하기 위해 활동이 저장된 상태 번들을 시스템 OS로 보내려고 했지만(구성 변경 또는 프로세스 중단 후) 하나 이상의 번들이 너무 컸다는 것을 의미합니다.
작업에서 인스턴스 상태 저장을 재정의하여 해킹을 통해 문제를 해결했습니다.
@Override
protected void onSaveInstanceState(Bundle outState) {
// super.onSaveInstanceState(outState);
}
그리고 댓글 콜 슈퍼.그것은 더러운 해킹이지만 완벽하게 작동하고 있습니다.비트맵이 충돌 없이 전송되었습니다.이것이 누군가에게 도움이 되기를 바랍니다.
최근에 안드로이드의 연락처 공급자와 작업하는 동안 흥미로운 사례를 접하기도 했습니다.
내부 연락처 데이터베이스에서 연락처 사진을 로드해야 했고 시스템 아키텍처에 따라 이 모든 데이터는 문의를 통해 연락처 공급자에게 전달됩니다.
별도의 응용프로그램으로 작동하므로 모든 종류의 데이터 전송은 바인더 메커니즘을 사용하여 수행되므로 바인더 버퍼가 여기에 적용됩니다.
제 주된 실수는 제가 문을 닫지 않은 것입니다.Cursor 공급자로부터으로써 공급자에 는 제가 수많은 BLOB .!!!FAILED BINDER TRANSACTION!!!메시지가 나타납니다.
주요 아이디어는 외부 콘텐츠 공급자와 협력하여 다음과 같은 이점을 얻을 수 있다는 것입니다.Cursor과 함께. s 터로부그작, 당이과업마을치항면닫그상으오것십시을들신들그▁it▁s▁when오▁close.
onSaveInstanceState 메서드에서 이전 InstanceState를 지우면 잘 작동합니다.보기 페이지에 FragmentStatePagerAdapter를 사용하고 있기 때문에 인스턴스 상태를 지우기 위해 아래 Override 메서드를 부모 활동으로 유지합니다.
@Override
protected void onSaveInstanceState(Bundle InstanceState) {
super.onSaveInstanceState(InstanceState);
InstanceState.clear();
}
여기 안드로이드.os에서 이 솔루션을 찾았습니다.거래Nougat에 대한 너무 큰 예외
큰 크기의 Intent 개체 데이터에 넣지 마십시오.저의 경우 String 500k 사이즈를 추가한 후 다른 활동을 시작하고 있었습니다.이 예외로 인해 항상 실패했습니다.활동의 정적 변수를 사용하여 활동 간에 데이터를 공유하는 것을 피했습니다. 활동을 의도로 보낸 다음 삭제할 필요가 없습니다.
내가 가진 것:
String html = new String();//some string of 500K data.
Intent intent = new Intent(MainActivity.this, PageWebView.class);
//this is workaround - I just set static variable and then access it from another activity.
MainActivity.htmlBody = timelineDb.getHTMLBodyForTweet(tweet);
//This line was present and it actually failed with the same exception you had.
//intent.putExtra("com.gladimdim.offtie.webview", html);
내 경우에는 트랜잭션이 발생합니다.기본 라이브러리가 SIGSEGV와 충돌한 후 보조 충돌로 TooLargeException이 발생했습니다.기본 라이브러리 충돌이 보고되지 않아 트랜잭션만 수신됩니다.예외가 너무 큽니다.
대량 작업을 시도할 때 동기화 어댑터에 이 메시지가 표시되었습니다.큰 ContentValues[]를 삽입합니다.다음과 같이 수정하기로 결정했습니다.
try {
count = provider.bulkInsert(uri, contentValueses);
} catch (TransactionTooLarge e) {
int half = contentValueses.length/2;
count += provider.bulkInsert(uri, Arrays.copyOfRange(contentValueses, 0, half));
count += provider.bulkInsert(uri, Arrays.copyOfRange(contentValueses, half, contentValueses.length));
}
나에게 그것은 또한.FragmentStatePagerAdapter 우선시되는 것은.saveState()작동하지 않았습니다.다음과 같이 수정했습니다.
을 때FragmentStatePagerAdapter생성자, 클래스 내에 별도의 fragment 목록을 유지하고 fragment를 제거하는 방법을 추가합니다.
class PagerAdapter extends FragmentStatePagerAdapter {
ArrayList<Fragment> items;
PagerAdapter(ArrayList<Fragment> frags) {
super(getFragmentManager()); //or getChildFragmentManager() or getSupportFragmentManager()
this.items = new ArrayList<>();
this.items.addAll(frags);
}
public void removeFragments() {
Iterator<Fragment> iter = items.iterator();
while (iter.hasNext()) {
Fragment item = iter.next();
getFragmentManager().beginTransaction().remove(item).commit();
iter.remove();
}
notifyDataSetChanged();
}
}
//...getItem() and etc methods...
}
다음에그에서.Activity을 저장합니다.ViewPager 앤 콜 위와부름지.adapter.removeFragments()에서.onSaveInstanceState()방법:
private int pagerPosition;
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//save other view state here
pagerPosition = mViewPager.getCurrentItem();
adapter.removeFragments();
}
마지막으로, 오버라이드에서.onResume()메서드, 어댑터가 그렇지 않으면 다시 인증합니다.null(만약 그렇다면)null 다음에 그음에다.Activity처음으로 또는 안드로이드에 의해 앱이 제거된 후에 열립니다.onCreate어댑터 생성을 수행합니다.)
@Override
public void onResume() {
super.onResume();
if (adapter != null) {
adapter = new PagerAdapter(frags);
mViewPager.setAdapter(adapter);
mViewPager.setCurrentItem(currentTabPosition);
}
}
이것은 제가 단편의 인수에 있는 검색 결과 목록을 전달하는 중이었기 때문에 제 앱에서 발생했습니다. 그 목록을 단편의 인수가 가리키는 메모리의 동일한 위치에 대한 참조인 단편의 속성에 할당한 다음 새 항목을 목록에 추가하여 단편의 인수 크기도 변경했습니다.활동이 일시 중단되면 기본 조각 클래스가 조각의 인수를 onSaveInstanceState에 저장하려고 합니다. 이 경우 인수가 1MB보다 크면 충돌합니다. 예:
private ArrayList<SearchResult> mSearchResults;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (getArguments() != null && getArguments().getSerializable("SearchResults") != null) {
mSearchResults = (ArrayList) getArguments().getSerializable("SearchResults");
}
}
private void onSearchResultsObtained(ArrayList<SearchResult> pSearchResults) {
// Because mSearchResults points to the same location in memory as the fragment's arguments
// this will also increase the size of the arguments!
mSearchResults.addAll(pSearchResults);
}
이 경우 가장 쉬운 해결책은 참조를 할당하는 대신 목록의 복사본을 조각의 속성에 할당하는 것이었습니다.
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (getArguments() != null && getArguments().getSerializable("SearchResults") != null) {
// Copy value of array instead of reference
mSearchResults = new ArrayList((ArrayList) getArguments().getSerializable("SearchResults"));
}
}
더 나은 해결책은 인수에 너무 많은 데이터를 전달하지 않는 것입니다.
이 답변과 TooLargeTool의 도움이 없었다면 저는 이것을 결코 발견하지 못했을 것입니다.
나는 또한 거래를 살아왔습니다.예외가 너무 큽니다.우선, 저는 그것이 어디서 발생하는지 이해하기 위해 노력했습니다.저는 그것이 발생하는 이유를 알고 있습니다.우리 모두는 콘텐츠가 크기 때문에 알고 있습니다.저의 문제는 이렇고 저는 해결했습니다.이 솔루션은 누구에게나 유용할 수 있습니다.나는 api에서 콘텐츠를 얻는 앱이 있습니다.첫 화면에서 API 결과를 받아서 두 번째 화면으로 보내고 있습니다.이 내용을 성공적으로 두 번째 화면으로 보낼 수 있습니다.두 번째 화면 이후에 세 번째 화면으로 이동하려면 이 예외가 발생합니다.각 화면은 조각으로 만들어집니다.제가 두 번째 화면에서 나갈 때 저는 그것을 알아차렸습니다.번들 내용이 저장됩니다. 이 내용이 너무 크면 이 예외가 발생합니다.제 해결책은 번들에서 컨텐츠를 가져온 후에 삭제하는 것입니다.
class SecondFragment : BaseFragment() {
lateinit var myContent: MyContent
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
myContent = arguments?.getParcelable("mycontent")
arguments?.clear()
}
내가 처리할 때WebView제 앱에서 그런 일이 일어납니다.와 관련이 있는 것 같습니다.addView및 UI 리소스.에 서코추니다가합드앱에에 합니다.WebViewActivity아래와 같이 실행됩니다.
@Override
protected void onDestroy() {
if (mWebView != null) {
((ViewGroup) mWebView.getParent()).removeView(mWebView);
mWebView.removeAllViews();
mWebView.destroy();
}
super.onDestroy();
}
저는 이것의 근본 원인을 발견했습니다(mvds에서 말하는 "창 추가 실패"와 파일 설명자 유출 모두 발생했습니다).
에 버그가 있습니다.BitmapFactory.decodeFileDescriptor()Android 4.4 버전입니다.다음과 같은 경우에만 발생합니다.inPurgeable그리고.inInputShareableBitmapOptions으로 됩니다.true이로 인해 파일과 상호 작용하는 많은 장소에서 많은 문제가 발생합니다.
이 메서드는 다음에서 호출됩니다.MediaStore.Images.Thumbnails.getThumbnail().
범용 이미지 로더가 이 문제의 영향을 받습니다.피카소와 글라이드는 영향을 받지 않은 것 같습니다.https://github.com/nostra13/Android-Universal-Image-Loader/issues/1020
writeToParcel(parcelest, int flags) 메서드의 이 한 줄 코드는 트랜잭션을 제거하는 데 도움이 되었습니다.예외가 너무 큽니다.
dest=Parcel.obtain();
이 코드 이후에는 모든 데이터를 소포 객체(즉, eest)에 씁니다.writeInt() 등
사용해 보십시오.EventBus또는ContentProvider한 해결책 유사용액용액.
동일한 프로세스에 있는 경우(일반적으로 모든 활동이 동일함) 다음을 사용해 보십시오.EventBus프로세스 중인 데이터 교환에는 버퍼가 필요하지 않으므로 데이터가 너무 클 경우 걱정할 필요가 없습니다.(메소드 호출을 사용하여 실제로 데이터를 전달할 수 있으며, EventBus는 추악한 것들을 숨깁니다.자세한 내용은 다음과 같습니다.
// one side
startActivity(intentNotTooLarge);
EventBus.getDefault().post(new FooEvent(theHugeData));
// the other side
@Subscribe public void handleData(FooEvent event) { /* get and handle data */ }
의 양쪽이 , 정도의 인텐트를 시도해 보세요.ContentProvider.
바인더 트랜잭션이 너무 커서 트랜잭션에 실패했습니다.
원격 프로시저 호출 중에 호출의 인수와 반환 값은 바인더 트랜잭션 버퍼에 저장된 구획 객체로 전송됩니다.인수 또는 반환 값이 너무 커서 트랜잭션 버퍼에 들어가지 않으면 호출이 실패하고 트랜잭션이 수행됩니다.TooLargeException이 느려집니다.
트랜잭션을 받았습니다.Android 에스프레소 테스트에서 스택 오버플로 오류에서 TooLargeException이 발생했습니다.내 앱의 Logcat 필터를 제거했을 때 로그에서 스택 오버플로 오류 스택 추적을 발견했습니다.
에스프레소 때문에 거래가 성사된 것 같아요매우 큰 예외 스택 추적을 처리하려고 할 때 TooLargeException이 발생했습니다.
또한 저는 한 활동에서 다른 활동으로 전달되는 비트맵 데이터에 대해 이 문제에 직면했지만, 저는 제 데이터를 정적 데이터로 만들어 해결책을 만들고 이것은 저에게 완벽하게 작동합니다.
먼저 활동 중:
public static Bitmap bitmap_image;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
bitmap_image=mybitmap;
}
그리고 두 번째 활동:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Bitmap mybitmap=first.bitmap_image;
}
프로젝트에서 비트맵을 Base64로 변환한 후 아래 코드로 비트맵 크기를 조정해야 하는 구획 가능한 개체에 저장한 경우,
png을 jpeg로 대체하고 품질 100을 75 또는 60으로 대체합니다.
bitmap.compress(Bitmap.CompressFormat.JPEG, 75, byteArrayOutputStream)
이 솔루션은 저에게 적합합니다.
끔가끔Activity약간의 부를포를 합니다.Fragment 때에ActivityFragments가 Fragments일 콘텐츠를 .sportFragmentManager.fragments한 역사 .
val fragments = sportFragmentManager.fragments
val transaction = sportFragmentManager.beginTransaction()
for (frag in fragments){
transaction.remove(frag)
}
transaction.commitAllowingStateLoss()
시간 조각 다시 만들기Activity발생합니다(디버그가 너무 큰 도구를 사용함).
W/ActivityStopInfo: Bundle stats:
W/ActivityStopInfo: android:viewHierarchyState [size=2304]
W/ActivityStopInfo: android:views [size=2256]
W/ActivityStopInfo: android:support:fragments [size=519072]
W/ActivityStopInfo: PersistableBundle stats:
W/ActivityStopInfo: [null]
언급URL : https://stackoverflow.com/questions/11451393/what-to-do-on-transactiontoolargeexception
'programing' 카테고리의 다른 글
| Swift에서 동일한 키에 대한 여러 값을 포함하는 쿼리 매개 변수로 URL을 작성하려면 어떻게 해야 합니까? (0) | 2023.08.31 |
|---|---|
| MVC4 StyleBundle이 이미지를 확인하지 않음 (0) | 2023.08.31 |
| MariaDB 연결이 거부되었습니다(NGINX, MariaDB, php-fpm) SQLSTATE[HY000] [2002] 연결이 거부되었습니다. (0) | 2023.08.26 |
| Mac에서 Android SDK 찾기 및 PATH에 추가 (0) | 2023.08.26 |
| 마지막 알 수 없는 ID로 레코드 그룹 가져오기 (0) | 2023.08.26 |