TransactionTooLargeException पर क्या करें


239

मुझे ए TransactionTooLargeException। प्रतिलिपि प्रस्तुत करने योग्य नहीं। डॉक्स में यह कहता है

बाइंडर लेनदेन विफल हो गया क्योंकि यह बहुत बड़ा था।

एक दूरस्थ प्रक्रिया कॉल के दौरान, तर्क और कॉल के वापसी मूल्य को बाइंडर लेनदेन बफर में संग्रहीत पार्सल ऑब्जेक्ट के रूप में स्थानांतरित किया जाता है। यदि लेन-देन बफर में फिट होने के लिए तर्क या रिटर्न वैल्यू बहुत बड़ी है, तो कॉल विफल हो जाएगी और TransactionTooLargeException को फेंक दिया जाएगा।

...

दो संभावित परिणाम होते हैं जब एक दूरस्थ प्रक्रिया कॉल फेंकता है TransactionTooLargeException। या तो ग्राहक सेवा के लिए अपना अनुरोध भेजने में असमर्थ था (सबसे अधिक संभावना है कि यदि लेन-देन बफर में फिट होने के लिए तर्क बहुत बड़े थे), या सेवा ग्राहक को अपनी प्रतिक्रिया वापस भेजने में असमर्थ थी (सबसे अधिक संभावना है कि यदि वापसी मूल्य था) लेन-देन बफर में फिट करने के लिए बहुत बड़ा)।

...

इसलिए कहीं न कहीं मैं तर्क दे रहा हूँ या प्राप्त कर रहा हूँ जो कुछ अज्ञात सीमा से अधिक है। कहाँ पे?

स्टैकट्रेस उपयोगी कुछ भी नहीं दिखाता है:

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)

यह विचारों से संबंधित प्रतीत होता है? यह दूरस्थ प्रक्रिया कॉल से संबंधित कैसे है?

शायद महत्वपूर्ण: Android संस्करण: 4.0.3, डिवाइस: एचटीसी वन एक्स


नहीं, लेकिन मैं इसे फिर से नहीं मिला। लाइव ऐप में त्रुटि ट्रैकर है और इसे लगभग 3 सप्ताह में केवल एक बार मिला है। कम से कम ऐसा अक्सर नहीं होता है। शायद Android पर एक मुद्दा खोलने के लायक है ...
Ixx

मेरे पास कोई जवाब नहीं है, लेकिन यह मज़बूती से मेरे गैलेक्सी एस 2 को हार्ड रीसेट करने का कारण बनता है।
टिम्मम

मैंने आज ही अपने एक आवेदन में यह पाया है। यह भी केवल एक बार और गैलेक्सी एस 3 के साथ हुआ है। यह दिलचस्प है कि यह केवल और अधिक शक्तिशाली उपकरणों के साथ गिरफ्तार किया जा रहा है।
डेनवम्स

यह अपवाद API 15 में जोड़ा गया था, developer.android.com/reference/android/os/… और मैंने मैप के चारों ओर स्क्रॉल करते हुए इसे MapView में पुन: पेश किया है। जब तक जीसी ने लिखा कि मेरे पास कोई स्मृति नहीं बची है। (इसमें मुझे कुछ मिनट लगे)
meh

लेन-देन बफ़र सभी डिवाइसों पर 1MB तक सीमित है, और यह बफ़र प्रत्येक लेन-देन को हटा देता है। तो जितना अधिक शक्तिशाली उपकरण उतना ही अधिक लेनदेन एक साथ करेगा, सभी एक ही 1 एमबी बफर का उपभोग करते हैं। उस ने कहा, आपका उत्तर एक उत्तर नहीं बल्कि एक टिप्पणी है।
सी 71

जवाबों:


158

मुझे इस मुद्दे का सामना करना पड़ा, और मैंने पाया कि जब किसी सेवा और एप्लिकेशन के बीच भारी मात्रा में डेटा का आदान-प्रदान हो रहा होता है, (इसमें बहुत सारे थंबनेल स्थानांतरित करना शामिल है)। वास्तव में डेटा का आकार 500kb के आसपास था, और IPC लेनदेन बफर आकार 1024KB पर सेट है। मुझे यकीन नहीं है कि यह लेनदेन बफर से अधिक क्यों था।

यह तब भी हो सकता है, जब आप इरादे एक्स्ट्रा के माध्यम से बहुत सारे डेटा पास करते हैं

जब आप अपने आवेदन में यह अपवाद प्राप्त करते हैं, तो कृपया अपने कोड का विश्लेषण करें।

  1. क्या आप अपनी सेवाओं और एप्लिकेशन के बीच बहुत अधिक डेटा का आदान-प्रदान कर रहे हैं?
  2. विशाल डेटा साझा करने के लिए इंटेंट्स का उपयोग करना, (उदाहरण के लिए, उपयोगकर्ता गैलरी शेयर प्रेस शेयर से बड़ी संख्या में फ़ाइलों का चयन करता है, चयनित फ़ाइलों के यूआरआई को इंटेंट्स का उपयोग करके स्थानांतरित किया जाएगा)
  3. सेवा से बिटमैप फ़ाइलें प्राप्त करना
  4. भारी डेटा के साथ वापस जवाब देने के लिए Android की प्रतीक्षा कर रहा है (उदाहरण के लिए, getInstalledApplications () जब उपयोगकर्ता बहुत सारे एप्लिकेशन इंस्टॉल करता है)
  5. बहुत सारे ऑपरेशन लंबित होने के साथ applyBatch () का उपयोग करना

जब आपको यह अपवाद मिलता है तो कैसे संभालना है

यदि संभव हो, तो बड़े ऑपरेशन को छोटे चंक्स में विभाजित करें, उदाहरण के लिए, कॉलबैक () के बजाय 1000 ऑपरेशन के साथ, प्रत्येक 100 पर कॉल करें।

सेवाओं और एप्लिकेशन के बीच भारी डेटा (> 1 एमबी) का आदान-प्रदान न करें

मुझे नहीं पता कि यह कैसे करना है, लेकिन, एंड्रॉइड को क्वेरी न करें, जो बहुत बड़ा डेटा वापस कर सकता है :-)


1
मान लीजिए मैं जाँच कर रहा हूँ मेरे .apk स्थापित है या नहीं? स्थापना के समय ... मुझे अपने पैकेज com.test.installedornot.My की जाँच करते समय एक ही अपवाद मिल रहा है। मेरा आकार 9 एमबी से अधिक है तो उस स्थिति में मैं इस अपवाद को कैसे प्रबंधित करूंगा?
13

15
मुझे यह अपवाद कॉल करने के दौरान बिल्कुल मिल रहा है getInstalledApplications। इसे हल करने के लिए क्या किया जा सकता है?
स्टेन

1
@Stan यह एप आम है और मोटे तौर पर एंड्रॉइड ऐप के आसपास उपयोग किया जाता है। जब मैं इस एपीआई का उपयोग करता हूं तो यह अपवाद वास्तव में मुझे किसी तरह चिंतित करता है।
शांति काल

7
मैं आपके निष्कर्ष के बारे में 500KB के आसपास कहीं होने की पुष्टि कर सकता हूं, लेकिन यह विशिष्ट डिवाइस है, कुछ उपकरणों पर आप लगभग पूरे 1MB स्थानांतरित कर सकते हैं। मेरे पास यह अपवाद भी था, इसलिए मैंने कुछ जांच की, और एक पोस्ट लिखी जो इस समस्या वाले लोगों के लिए दिलचस्प हो सकती है। nemanjakovacevic.net/blog/english/2015/03/24/…
Nemanja Kovacevic

11
यदि आपको यह पता लगाने में मुश्किल हो रही है कि आपकी दुर्घटना का कारण कौन सा राज्य है, तो आप बहुत उपयोगी पाया जा सकता है।
मैक्स स्पेंसर

48

यदि आपको यह जांचने की आवश्यकता है कि पार्सल आपके दुर्घटना का कारण बन रहा है, तो आपको भी टूएलर्जटूल की कोशिश करने पर विचार करना चाहिए ।

(मुझे यह स्वीकार किए गए उत्तर के तहत @Max स्पेंसर की टिप्पणी के रूप में मिला और यह मेरे मामले में मददगार था।)


9
सबसे कम समाधान। यह उपकरण आपको अपमानजनक गतिविधियों को कम करने में मदद करता है
केदार परांजपे

इस उपकरण ने मेरी समस्या को हल करने में मदद की। इंस्टॉल करने और उपयोग करने में आसान।
कार्लोस

यह उपकरण कोटलिन के लिए है: / जावा के लिए कोई विकल्प?
मैक्सवेलनवेज 16

2
@maxwellnewage: लगता है कि नवीनतम संस्करण (0.2.1, 0.2.0 भी) वर्तमान में जावा-केवल-अनुप्रयोगों में काम नहीं कर रहा है। मुझे संस्करण ०.१.६ का उपयोग करना था और यह तब अच्छी तरह से काम करता था
५०

इस उपकरण के उपयोग से मुझे पता चलता है कि मैं अपने टुकड़ों में बंडलों के विशाल आकार का उपयोग कर रहा था। मैंने जो किया वह बंडल से तर्क निकालने के लिए किया और बंडल का उपयोग करके साफ़ कर दियाbundle.clear()
EJ चतुरंगा

41

यह एक निश्चित जवाब नहीं है, लेकिन यह एक के कारणों पर कुछ प्रकाश डाल सकता है TransactionTooLargeExceptionऔर समस्या को इंगित करने में मदद कर सकता है।

हालांकि अधिकांश उत्तर बड़ी मात्रा में स्थानांतरित किए गए डेटा का संदर्भ देते हैं, मैं देखता हूं कि यह अपवाद संयोगवश भारी स्क्रॉलिंग और जूमिंग के बाद और बार-बार एक्शनबार स्पिनर मेनू खोलने के बाद फेंका जा रहा है। क्रैश एक्शन बार को टैप करने पर होता है। (यह एक कस्टम मैपिंग ऐप है)

केवल पास किया जा रहा डेटा "इनपुट डिस्पैचर" से ऐप तक पहुंचता है। मुझे लगता है कि यह "लेन-देन बफर" में 1 एमबी के करीब कहीं भी नहीं हो सकता है।

मेरा ऐप क्वाड कोर 1.6 गीगाहर्ट्ज़ डिवाइस पर चल रहा है और यूआई थ्रेड के लिए एक कोर मुक्त रखते हुए, हेवीलाइडिंग के लिए 3 थ्रेड्स का उपयोग करता है। इसके अलावा, ऐप एंड्रॉइड का उपयोग करता है: bigHeap, में अप्रयुक्त ढेर के 10 mb बचे हैं और ढेर बढ़ने के लिए 100 mb का कमरा बचा है। इसलिए मैं यह नहीं कहूंगा कि यह एक संसाधन मुद्दा है।

दुर्घटना हमेशा इन पंक्तियों से पहले होती है:

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 !!!

जो उस क्रम में neccesately मुद्रित नहीं हैं, लेकिन (जहाँ तक मैंने जाँच की) एक ही मिलीसेकंड पर होते हैं।

और स्टैक खुद को स्पष्टता के लिए ट्रेस करता है, यह प्रश्न में जैसा है:

E/AndroidRuntime(28182): java.lang.RuntimeException: Adding window failed
..
E/AndroidRuntime(28182): Caused by: android.os.TransactionTooLargeException

एंड्रॉइड के सोर्स कोड में डिलीट करने पर ये लाइनें मिलती हैं:

चौखटे / आधार / कोर / 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

इस समय मैंने समस्या का समाधान नहीं किया, लेकिन अगर मुझे कुछ उपयोगी लगता है तो मैं इस उत्तर को अपडेट करूंगा।

अपडेट: यह पता चला कि मेरे कोड ने कुछ फ़ाइल डिस्क्रिप्टर को लीक कर दिया है, जिसकी संख्या लिनक्स (आमतौर पर 1024) में अधिकतम है, और ऐसा लगता है कि अपवाद को ट्रिगर किया गया है। तो यह सब के बाद एक संसाधन मुद्दा था। मैंने इसे /dev/zero1024 बार खोलकर सत्यापित किया , जिसके परिणामस्वरूप UI संबंधित कार्यों में सभी प्रकार के अजीब अपवाद थे, जिसमें उपरोक्त अपवाद और यहां तक ​​कि कुछ SIGSEGV भी शामिल थे। एक फ़ाइल / सॉकेट खोलने में स्पष्ट रूप से विफलता कुछ ऐसा नहीं है जो पूरे एंड्रॉइड में बहुत सफाई से संभाला / रिपोर्ट किया गया हो।


36

TransactionTooLargeExceptionअब 4 के बारे में महीनों के लिए हमें नाक में दम कर दिया गया है, और हम अंत में समस्या हल कर ली!

क्या हो रहा था कि हम एक प्रयोग कर रहे हैं FragmentStatePagerAdapterएक में ViewPager। उपयोगकर्ता 100 + टुकड़े (इसका एक पढ़ने वाला अनुप्रयोग) बनाएगा और बनाएगा।

हालाँकि, हम destroyItem()एंड्रॉइड के टुकड़ों को ठीक से प्रबंधित करते हैं , लेकिन कार्यान्वयन में FragmentStatePagerAdapterएक बग है, जहां यह निम्नलिखित सूची का संदर्भ रखता है:

private ArrayList<Fragment.SavedState> mSavedState = new ArrayList<Fragment.SavedState>();

और जब एंड्रॉइड 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तब होता है जब उस सरणी को डंप किया जाता है parcelableArrayऔर OS उसे 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;
}

मेरे लिए सबसे अच्छा जवाब। बहुत बहुत धन्यवाद
पावेल

इसके लिए सभी संभावनाओं में से, मेरे लिए यह केवल विकल्प लग रहा था। राज्य में क्या संग्रहीत किया जाता है जो इसे इस आकार में लाने की अनुमति देगा? यदि राज्य को इतनी बुरी तरह से जरूरत है कि इसे बचाने के लिए कोड है, तो यह अन्य समस्याओं का कारण कैसे नहीं बनता है? धन्यवाद
केनी

@ केनी के रूप में एक ही सवाल
श्री खरगोश

1
@Override public Parcelable saveState() { Bundle bundle = (Bundle) super.saveState(); if (bundle != null) { Parcelable[] states = bundle.getParcelableArray("states"); // Subset only last 3 states if (states != null) states = Arrays.copyOfRange(states, states.length > 3 ? states.length - 3 : 0, states.length - 1); bundle.putParcelableArray("states", states); } else bundle = new Bundle(); return bundle; }
रामी सब्री

मैंने अभी केवल अंतिम 3 राज्यों को, ऊपर दिए गए कोड की जाँच की।
रामी साबरी

20

जो लोग TransactionTooLargeException के माफी मांगने के जवाब की तलाश में निराश हैं, उनके लिए यह जाँचने की कोशिश करें कि आप उदाहरण के लिए राज्य में कितनी जानकारी सहेजते हैं।

संकलित / लक्ष्यविकास पर <= 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)

लेकिन संकलन / टारगेट पर SdkVersion> = 24 हमारे पास इस मामले में वास्तविक RuntimeException क्रैश है:

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) 

क्या करें?

स्थानीय डेटाबेस में डेटा सहेजें और केवल आईडी की स्थिति रखें जिसे आप इस डेटा को पुनः प्राप्त करने के लिए उपयोग कर सकते हैं।


क्या इसे वैश्विक पैरामीटर के रूप में रखना और बाद में इसका उपयोग करना संभव है?
जितेंद्र रामोलिया

@ जितेन्द्रमोलिया जी, आप कर सकते हैं। ठीक यही मेरा मतलब है।
Yazon2006

13

यह अपवाद आमतौर पर तब डाला जाता है जब ऐप को पृष्ठभूमि पर भेजा जा रहा हो।

इसलिए मैंने onSavedInstanceStaeजीवनचक्र को पूरी तरह से दरकिनार करने के लिए डेटा फ्रेगमेंट विधि का उपयोग करने का निर्णय लिया है । मेरा समाधान जटिल उदाहरण राज्यों को भी संभालता है और मेमोरी एएसएपी को मुक्त करता है।

पहले मैंने डेटा स्टोर करने के लिए एक सरल फ़ार्गेट बनाया है:

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/


1
यदि एप्लिकेशन पृष्ठभूमि में है और गतिविधि को नष्ट कर दिया जाता है, तो आप गतिविधि को नष्ट करने की कोशिश करते हैं तो क्या होता है?
मास्टर डिजास्टर

@MasterDisaster उस स्थिति में कोई भी राज्य सहेजा नहीं गया है क्योंकि आवृत्ति खंड रखने वाली प्रक्रिया मर गई है।
वैडन

अधिकार, इसलिए यह मामला केवल कॉन्फ़िगरेशन परिवर्तन के साथ काम करता है।
मास्टर डिजास्टर

जब भी OS ट्रिगर onSavedState()होता है तो यह काम करता है , जो कई मामलों में होता है। कॉन्फ़िगरेशन परिवर्तन एक है। ऐप्स को स्विच करना और बैकग्राउंड में जाना एक और बात है। और और भी हैं।
वैदिक

1
मुझे लगता है कि विभिन्न स्रोतों से डेटा को बचाने के लिए इस समाधान का विस्तार किया जाना चाहिए। संभवतः कुंजी के रूप में टैग और बंडलों के रूप में टैग के साथ एक
हैशपॉप

11

इस समस्या का कोई एक विशिष्ट कारण नहीं है। मेरे लिए, मेरी फ्रैगमेंट क्लास में मैं यह कर रहा था:

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);

9

यह समझना महत्वपूर्ण है कि लेनदेन बफर डिवाइस की क्षमता या ऐप की परवाह किए बिना 1 एमबी तक सीमित है। इस बफर का उपयोग आपके द्वारा की जाने वाली हर एपीआई कॉल के साथ किया जाता है और वर्तमान में चल रहे सभी लेनदेन के बीच साझा किया जाता है।

मेरा मानना ​​है कि यह पार्सल और जैसे कुछ विशिष्ट वस्तु भी रखता है (Parcel.obtain()), इसलिए यह हमेशा महत्वपूर्ण है कि प्रत्येक के obtain()साथ मेल खाना चाहिए recycle()

यह त्रुटि आसानी से बहुत सारे डेटा को लौटाने वाली एपीआई कॉल पर हो सकती है, भले ही लौटा डेटा 1 एमबी से कम हो (यदि अन्य लेनदेन अभी भी चल रहे हैं)।

उदाहरण के लिए, PackageManager.getInstalledApplication()कॉल स्थापित किए गए सभी ऐप्स की सूची देता है। विशिष्ट झंडे जोड़ने से कई अतिरिक्त डेटा प्राप्त करने की अनुमति मिलती है। ऐसा करने से असफल होने की संभावना है, इसलिए यह सिफारिश की जाती है कि किसी भी अतिरिक्त डेटा को वापस न लें और प्रति-ऐप के आधार पर उन लोगों को पुनः प्राप्त करें।

हालांकि कॉल अभी भी विफल हो सकती है, इसलिए catchयदि आवश्यक हो तो इसे चारों ओर से घेरना और पुन: प्रयास करने में सक्षम होना महत्वपूर्ण है।

जहाँ तक मुझे पता है, इस तरह के मुद्दे के पीछे कोई काम नहीं है सिवाय फिर से प्रयास करने और कम से कम जानकारी प्राप्त करने के लिए सुनिश्चित करने के लिए।


जानकारी के लिए धन्यवाद, कि बफर आवेदन के भीतर सभी लेनदेन के बीच साझा किया जाता है!
आर्टेम मोस्टेव

1
अगर ऐसा था तो ऐसा क्यों है कि मैं केवल एंड्रॉइड 4.4 फोन पर ही मिल रहा हूं और कहां नहीं। मुझे लगता है कि 4.4 में इसकी एक बग है कि मैं यह पता लगाने में असमर्थ हूं कि क्यों।
जेपीएम

9

मुझे भी सैमसंग एस 3 पर यह अपवाद मिला। मुझे 2 मूल कारणों पर संदेह है,

  1. आपके पास बिटमैप हैं जो लोड करते हैं और बहुत अधिक मेमोरी लेते हैं, डाउनसाइज़िंग का उपयोग करते हैं
  2. आपके पास drawable-_dpi फ़ोल्डरों से कुछ ड्रॉबल्स गायब हैं, android ड्रॉबल में उनके लिए दिखता है, और उनका आकार बदलता है, जिससे आपका setContentView अचानक कूदता है और बहुत सारी मेमोरी का उपयोग करता है।

डीडीएमएस का उपयोग करें और अपने ऐप को खेलते समय अपने ढेर को देखें, इससे आपको कुछ संकेत मिलेंगे, जिस पर सेट-कॉन्टेंटव्यू मुद्दा बना रहा है।

मैंने समस्या 2 से छुटकारा पाने के लिए सभी फ़ोल्डरों में सभी ड्रॉबल्स को कॉपी किया।

समस्या हल हो गई है।


मेमोरी / बिटमैप अपवाद आमतौर पर अलग दिखते हैं। मैंने पहले ही उनमें से कई को एंड्रॉइड 2.x - 4.x के साथ परीक्षण करते देखा है और अपवाद हमेशा अलग दिखते हैं। लेकिन, कौन जानता है, शायद यह भी संबंधित है लेकिन 4.x संस्करणों के लिए विशिष्ट है।
Ixx

10
यह जानकारी के संबंध में सिर्फ एक भयानक अपवाद है, क्योंकि यह इस बारे में कोई सुराग नहीं देता है कि समस्या कहां से आती है।
Ixx

मुझे लगता है कि कुछ दिन खत्म हो गए हैं, आपके निष्कर्ष क्या हैं?
डेनी

8

इसे अपनी गतिविधि में जोड़ें

@Override
protected void onSaveInstanceState(Bundle oldInstanceState) {
    super.onSaveInstanceState(oldInstanceState);
    oldInstanceState.clear();
}

यह मेरे लिए काम करता है आशा है कि यह भी आपकी मदद करेगा


7
मुझे लगता है, यह सबसे हानिकारक संकेत है। हमें वह डेटा क्यों साफ़ करना चाहिए जिसे हम पुनर्स्थापित करना चाहते हैं onCreate()?
कूलमाइंड

2
इस कोड का निहितार्थ यह है कि आप अंत में अपने इंस्टेंस राज्य को नहीं बचा रहे हैं ...
जस्टिन

4

इसलिए हमारे लिए यह था कि हम अपने एआईडीएल इंटरफ़ेस के माध्यम से किसी ऑब्जेक्ट की बहुत बड़ी संख्या को दूरस्थ सेवा में भेजने का प्रयास कर रहे थे। लेनदेन का आकार 1 एमबी से अधिक नहीं हो सकता। अनुरोध 512KB के अलग-अलग भाग में टूट गया है और इंटरफ़ेस के माध्यम से एक बार में भेजा गया है। एक क्रूर समाधान मुझे पता है लेकिन हे - इसके Android :(


4

आपने अपने पुराने InstanceState को onSaveInstanceState विधि से साफ़ कर दिया है, और यह अच्छी तरह से काम करेगा। मैं अपने viewpager के लिए FragmentStatePagerAdapter का उपयोग कर रहा हूं ताकि मैं स्पष्ट InstanceState के लिए अपने मूल गतिविधि में ओवरराइड विधि से नीचे रहूं।

@Override
protected void onSaveInstanceState(Bundle InstanceState) {
             super.onSaveInstanceState(InstanceState);
             InstanceState.clear();
}

मुझे यह समाधान यहाँ से प्राप्त हुआ। android.os.TransactionTooLargeException Nougat पर


बहुत बहुत धन्यवाद।
Andrain

शुक्रिया आपका जवाब मेरी मदद करें
जतिन पटेल

3

हाल ही में मुझे एंड्रॉइड के संपर्क प्रदाता के साथ काम करते समय एक दिलचस्प मामले का भी सामना करना पड़ा है ।

मुझे आंतरिक संपर्क डेटाबेस से संपर्कों की तस्वीरें लोड करने की आवश्यकता थी और सिस्टम आर्किटेक्चर के अनुसार यह सभी डेटा प्रश्नों द्वारा संपर्क प्रदाता को वितरित किए जाते हैं।

जैसा कि यह एक अलग अनुप्रयोग के रूप में काम करता है - सभी प्रकार के डेटा ट्रांसफरिंग बाइंडर तंत्र का उपयोग करके किए जाते हैं और इसलिए बाइंडर बफर यहां खेलने में आता है।

मेरी मुख्य गलती यह थी कि मैंनेCursor कॉन्टेक्ट प्रोवाइडर से प्राप्त ब्लॉब डेटा के साथ बंद नहीं किया था , ताकि प्रोवाइडर के लिए आवंटित मेमोरी बढ़े और इसने बिंडर बफर को तब तक फुलाया जब तक मुझे !!!FAILED BINDER TRANSACTION!!!मेरे लॉगकैट आउटपुट में संदेश नहीं मिल गए।

इसलिए मुख्य विचार यह है कि जब आप बाहरी सामग्री प्रदाताओं के साथ काम करते हैं और Cursorउनसे प्राप्त होते हैं, तो जब आप उनके साथ काम करना समाप्त करते हैं तो हमेशा इसे बंद कर दें।


3

मुझे उसी मुद्दे का सामना करना पड़ा जब मैंने इंटेंट के माध्यम से बिटमैप भेजने की कोशिश की और उसी समय जब ऐसा होता है कि मैंने एप्लिकेशन को तह किया।

इस लेख में इसका वर्णन कैसे किया गया है लिंक विवरण यहां दर्ज करें यह तब होता है जब कोई गतिविधि रुकने की प्रक्रिया में होती है, इसका मतलब है कि गतिविधि अपने सहेजे गए राज्य बंडलों को सिस्टम ओएस पर बाद में बहाली के लिए सुरक्षित रखने के लिए भेजने की कोशिश कर रही थी (एक कॉन्फ़िगरेशन परिवर्तन के बाद) या प्रक्रिया मृत्यु) लेकिन यह कि एक या अधिक बंडलों ने इसे भेजा था वे बहुत बड़े थे।

मैंने अपनी गतिविधि में onSaveInstanceState को ओवरराइड करके हैक के माध्यम से इसे हल किया:

@Override
protected void onSaveInstanceState(Bundle outState) {
    // super.onSaveInstanceState(outState);
}

और टिप्पणी कॉल सुपर। यह एक गंदा हैक है लेकिन यह पूरी तरह से काम कर रहा है। बिटमैप को क्रैश के बिना सफलतापूर्वक भेजा गया था। उम्मीद है कि यह किसी की मदद करेगा।


2

मेरे मामले में मैं SIGSEGV के साथ देशी पुस्तकालय के दुर्घटनाग्रस्त होने के बाद द्वितीयक दुर्घटना के रूप में TransactionTooLargeException प्राप्त करता हूं। मूल लाइब्रेरी क्रैश की सूचना नहीं है, इसलिए मुझे केवल TransactionTooLargeException प्राप्त हुई है।


2

जब एक बड़ी 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));
}

2
यदि दूसरा विफल हो जाए तो क्या होगा? लूप का उपयोग करके आपको अधिक विभाजन करने की आवश्यकता है। क्या लेनदेन का आकार प्राप्त करने और अधिकतम लेनदेन आकार प्राप्त करने का कोई तरीका है?
Android डेवलपर

2

मेरे लिए यह भी था FragmentStatePagerAdapter, हालांकि ओवरराइडिंग से saveState()काम नहीं चला। यहां बताया गया है कि मैंने इसे कैसे तय किया:

FragmentStatePagerAdapterनिर्माणकर्ता को बुलाते समय , कक्षा के भीतर टुकड़ों की एक अलग सूची रखें, और टुकड़ों को हटाने के लिए एक विधि जोड़ें:

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);
    }
}

1

सुनिश्चित करें कि आप बड़े आकार के इरादे वस्तु डेटा में नहीं डालते हैं। अपने मामले में मैं स्ट्रिंग 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);

यह बहुत बुरा विचार है। उस तरह से स्थिर चर का उपयोग करना एक कोड गंध है। इसके अलावा, इस कोड को "गतिविधियों को बनाए न रखें" ध्वज के साथ चलाने की कोशिश करें और PageWebView पर नेविगेट करने के बाद घर को दबाएं। आपके द्वारा अपनी गतिविधि को फिर से खोलने के बाद आपको संभवतः एक दुर्घटना मिल जाएगी क्योंकि MainActivity अपने सभी चर के साथ 100% मृत हो जाएगी।
Kyrylo Zapylaiev

1

जब मैं WebViewअपने ऐप के साथ काम कर रहा हूं तो ऐसा होता है। मुझे लगता है कि यह addViewऔर UI संसाधनों से संबंधित है । अपने ऐप में मैं WebViewActivityइस तरह से नीचे कुछ कोड जोड़ता हूं तो यह ठीक चलता है:

@Override
protected void onDestroy() {
    if (mWebView != null) {
        ((ViewGroup) mWebView.getParent()).removeView(mWebView);  
        mWebView.removeAllViews();  
        mWebView.destroy();
    }
    super.onDestroy();
}

1

मुझे इसका मूल कारण मिला (हम दोनों को जोड़ते हुए "विंडो फेल हो गया" और फ़ाइल डिस्क्रिप्टर लीक जैसा कि mvds कहते हैं)।

एंड्रॉइड 4.4 में एक बग है BitmapFactory.decodeFileDescriptor()। यह केवल तब होता है जब inPurgeableऔर inInputShareableके BitmapOptionsकी तैयारी में हैं true। यह कई जगहों पर फ़ाइलों के साथ इंटरैक्ट करने में कई समस्या का कारण बनता है।

ध्यान दें कि विधि को भी कहा जाता है MediaStore.Images.Thumbnails.getThumbnail()

यूनिवर्सल इमेज लोडर इस मुद्दे से प्रभावित होता है। लगता है पिकासो और ग्लाइड प्रभावित नहीं हैं। https://github.com/nostra13/Android-Universal-Image-Loader/issues/1020


1

राइटऑपरपल (पार्सल डेस्ट, इंट फ्लैग) पद्धति में कोड की इस एक लाइन ने मुझे TransactionTooLargeException से छुटकारा पाने में मदद की।

dest=Parcel.obtain(); 

इस कोड के बाद केवल मैं पार्सल ऑब्जेक्ट यानी dest.writeInt () आदि के लिए सभी डेटा लिख ​​रहा हूं।


1

समाधान का उपयोग करने EventBusया ContentProviderपसंद करने की कोशिश करें ।

यदि आप एक ही प्रक्रिया में हैं (आम तौर पर आपकी सभी गतिविधियाँ होंगी), तो उपयोग करने का प्रयास करें 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


TransactionTooLargeException देखें

बाइंडर लेनदेन विफल हो गया क्योंकि यह बहुत बड़ा था।

एक दूरस्थ प्रक्रिया कॉल के दौरान, तर्क और कॉल के वापसी मूल्य को बाइंडर लेनदेन बफर में संग्रहीत पार्सल ऑब्जेक्ट के रूप में स्थानांतरित किया जाता है। यदि लेन-देन बफर में फिट होने के लिए तर्क या रिटर्न वैल्यू बहुत बड़ी है, तो कॉल विफल हो जाएगी और TransactionTooLargeException को फेंक दिया जाएगा।


1

मुझे एंड्रॉइड एस्प्रेसो परीक्षण में एक स्टैकओवरफ़्लो त्रुटि से एक TransactionTooLargeException मिली। जब मैंने अपने ऐप के लिए Logcat फ़िल्टर लिया, तो मुझे लॉग में स्टैकओवरफ़्लो त्रुटि स्टैक ट्रेस मिला।

मुझे लगता है कि एस्प्रेसो TransactionTooLargeException का कारण बना, जब एक बहुत बड़े अपवाद स्टैकट्रेस को संभालने की कोशिश कर रहा था।


1

एक का उपयोग कर सकते हैं:

android:largeHeap="true"

एप्लिकेशन टैग के तहत Android मैनिफ़ेस्ट में।

इससे मेरे मामले में समस्या हल हो गई!


मेरे मामले में ( onSaveInstantStateगतिविधियों / खंडों में कॉल करने और बड़ी सूचियों को सहेजने के कारण) इससे कोई मदद नहीं मिली।
कूलमाइंड

1
इसे बुरा व्यवहार माना जाता है क्योंकि आप इस कारण से नहीं निपट रहे हैं कि पहली बार में बहुत सारे डेटा को बचाया जा रहा है। नए उपकरणों पर, यह ऐप को क्रैश कर देता है और सीमा बहुत छोटी (256KB) होती है। जांच करें कि आप पहले बहुत भंडारण क्यों कर रहे हैं और इसे कम करें।
टिम किस्ट

1

इसके अलावा, मैं बिटमैप डेटा के लिए एक गतिविधि से दूसरी गतिविधि में जाने के लिए इस समस्या का सामना कर रहा था, लेकिन मैं अपने डेटा को स्टैटिक डेटा बनाकर समाधान करता हूं और यह मेरे लिए एकदम सही काम कर रहा है

पहले गतिविधि में:

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;
}

1

यह मेरे ऐप में हो रहा था क्योंकि मैं खंड के तर्कों में खोज परिणामों की एक सूची पारित कर रहा था, उस सूची को टुकड़े की संपत्ति को सौंप रहा था - जो वास्तव में खंड के तर्कों द्वारा इंगित स्मृति में उसी स्थान का संदर्भ है - जोड़ना सूची में नए आइटम, जिसने टुकड़े के तर्कों के आकार को भी बदल दिया। जब गतिविधि निलंबित हो जाती है, तो आधार खंड वर्ग 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 की मदद के बिना यह कभी नहीं मिला होगा ।


1

मैंने TransactionTooLargeException भी जी है। सबसे पहले मैंने यह समझने पर काम किया है कि यह कहां होता है। मुझे पता है कि ऐसा क्यों होता है। हममें से हर कोई बड़ी सामग्री के कारण जानता है। मेरी समस्या वैसी ही थी और मैंने हल कर दी। हो सकता है कि यह समाधान किसी के लिए भी उपयोगी हो। मेरे पास एक ऐप है जिसे आपी से सामग्री मिलती है। मैं पहली स्क्रीन में एपीआई से परिणाम प्राप्त कर रहा हूं और इसे दूसरी स्क्रीन पर भेज रहा हूं। मैं सफल होने के लिए इस सामग्री को दूसरी स्क्रीन पर भेज सकता हूं। दूसरी स्क्रीन के बाद अगर मैं तीसरी स्क्रीन पर जाना चाहता हूं तो यह अपवाद होता है। मेरी प्रत्येक स्क्रीन फ्रैगमेंट से बनाई गई है। मैंने देखा कि जब मैं दूसरी स्क्रीन से निकलता हूं। यह इसकी बंडल सामग्री को बचाता है। यदि यह सामग्री बहुत बड़ी है तो यह अपवाद होता है। मेरे द्वारा बंडल से सामग्री प्राप्त करने के बाद मेरा समाधान है मैं इसे साफ़ करता हूं।

class SecondFragment : BaseFragment() {

    lateinit var myContent: MyContent

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        myContent = arguments?.getParcelable("mycontent")
        arguments?.clear()
    }

जबकि यह सही है (मेरे लिए शर्म की बात है, मैं एक वर्ष के बाद ही समझ गया), अगर यह (स्क्रीन रोटेशन) घूमता है तो टुकड़ा कैसे करेगा?
CoolMind

0

फ़ाइल सिस्टम के लिए ArrayList (या जो भी वस्तु समस्या पैदा कर रही है) लिखने के लिए ऐप का एक समाधान होगा, फिर उस फ़ाइल का संदर्भ (जैसे, फ़ाइल नाम / पथ) इंटेंट के माध्यम से IntentService और फिर IntentService को दें। फ़ाइल सामग्री को पुनः प्राप्त करें और इसे एक ArrayList में बदलें।

जब IntentService फ़ाइल के साथ किया गया है, तो इसे या तो इसे हटा देना चाहिए या फ़ाइल को हटाने के लिए एक स्थानीय प्रसारण के माध्यम से एप्लिकेशन को निर्देश वापस पास करना चाहिए जो इसे बनाया (उसी फ़ाइल संदर्भ को वापस भेज दिया गया था जो इसे आपूर्ति की गई थी)।

अधिक जानकारी के लिए इस संबंधित समस्या के बारे में मेरा जवाब देखें ।


0

जैसा कि इंटेंट, कंटेंट प्रोवाइडर, मैसेंजर, सभी सिस्टम सेवाएं जैसे टेलीफोन, वाइब्रेटर आदि, बाइंडर द्वारा IPC इंफ्रास्ट्रक्चर प्रदाता का उपयोग करते हैं। गतिविधि के जीवनचक्र कॉलबैक भी इस बुनियादी ढांचे का उपयोग करते हैं।

1MB एक विशेष क्षण में सिस्टम में निष्पादित सभी बाइंडर लेनदेन पर समग्र सीमा है।

मामले में जब इरादे भेजे जाते हैं तो बहुत सारे लेनदेन होते हैं, यह तब भी विफल हो सकता है जब अतिरिक्त डेटा बड़ा नहीं होता है। http://codetheory.in/an-overview-of-android-binder-framework/


0

कई स्थानों के साथ जहां TransactionTooLargeException हो सकती है - यहां Android 8 में एक और नया है - एक दुर्घटना जब कोई व्यक्ति केवल एक EditText में लिखना शुरू करता है यदि सामग्री बहुत बड़ी है।

यह AutoFillManager (API 26 में नया) और निम्न कोड से संबंधित है StartSessionLocked():

    mSessionId = mService.startSession(mContext.getActivityToken(),
            mServiceClient.asBinder(), id, bounds, value, mContext.getUserId(),
            mCallback != null, flags, mContext.getOpPackageName());

अगर मैं सही ढंग से समझूं, तो यह ऑटोफिल सर्विस को कॉल करता है- बाइंडर के भीतर ऑटोफिलमैनगर्ल को पार करना। और जब EditText में बहुत सारी सामग्री होती है, तो यह TTLE का कारण बनता है।

कुछ चीजें इसे कम कर सकती हैं (या जैसा कि मैं वैसे भी परीक्षण कर रहा था): android:importantForAutofill="noExcludeDescendants"EditText के xml लेआउट घोषणा में जोड़ें । या कोड में:

EditText et = myView.findViewById(R.id.scriptEditTextView);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    et.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS);
}

एक 2 भयंकर, भयानक workaround भी हो सकता है performClick()और onWindowFocusChanged()एक TextEdit उपवर्ग में त्रुटि को पकड़ने के तरीकों को ओवरराइड कर सकता है। लेकिन मुझे नहीं लगता कि यह वास्तव में बुद्धिमान है ...

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.