লেনদেন টু লার্জএক্সেপশনটিতে কী করবেন


239

আমি পেয়েছি একটি 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)

দেখে মনে হচ্ছে এটি সম্পর্কিত? এটি কীভাবে দূরবর্তী প্রক্রিয়া কলের সাথে সম্পর্কিত?

সম্ভবত গুরুত্বপূর্ণ: অ্যান্ড্রয়েড সংস্করণ: 4.0.3, ডিভাইস: এইচটিসি ওয়ান এক্স


না। তবে আমি আর পেলাম না। লাইভ অ্যাপ্লিকেশনটিতে ত্রুটিযুক্ত ট্র্যাকার রয়েছে এবং এটি প্রায় 3 সপ্তাহের মধ্যে কেবল একবারে পেয়েছে। অন্তত এটি ঘন ঘন ঘটবে বলে মনে হয় না। অ্যান্ড্রয়েডে ইস্যুটি খোলার উপযুক্ত হতে পারে যদিও ...
আইএক্সএক্স

আমার কাছে কোনও উত্তর নেই তবে এটি নির্ভরযোগ্যতার সাথে আমার গ্যালাক্সি এস 2কে হার্ড রিসেট করে।
টিএমএমএম

আমি আজই আমার একটি অ্যাপ্লিকেশনটিতে এটি ঘটেছে। এটি কেবল একবার এবং একটি গ্যালাক্সি এস 3 এর সাথে ঘটেছিল। এটি আকর্ষণীয় যে এটি কেবলমাত্র আরও শক্তিশালী ডিভাইসগুলির সাথে ধরা পড়েছে।
danwms

সেই ব্যতিক্রমটি এপিআই 15 এ যুক্ত হয়েছিল, বিকাশকারী.অ্যান্ড্রয়েড .com/references/android/os/… এবং মানচিত্রের চারদিকে স্ক্রোল করার সময় আমি এটি ম্যাপভিউতে পুনরুত্পাদন করেছি। যতক্ষণ না জিসি লিখেছেন যে আমার কোনও স্মৃতি নেই। (কয়েক মিনিট সময় লাগল)
মে

লেনদেনের বাফারটি সমস্ত ডিভাইসে 1MB এর মধ্যে সীমাবদ্ধ এবং এই বাফার প্রতিটি লেনদেনকে পুরাতন করে। সুতরাং ডিভাইসটি যত বেশি শক্তিশালী একই সাথে এটি সম্পাদন করতে পারে তত বেশি লেনদেন করে, যার সবকটি একই 1 এমবি বাফার গ্রহণ করে। এটি বলেছিল, আপনার উত্তরটি উত্তর নয় বরং একটি মন্তব্য।
3c71

উত্তর:


158

আমি এই সমস্যার মুখোমুখি হয়েছি এবং আমি দেখতে পেয়েছি যে যখন কোনও পরিষেবা এবং অ্যাপ্লিকেশনগুলির মধ্যে প্রচুর পরিমাণে ডেটা আদান প্রদান করা হয়, (এতে প্রচুর থাম্বনেইল স্থানান্তর করা জড়িত)। প্রকৃতপক্ষে ডেটা আকার 500kb এর কাছাকাছি ছিল, এবং আইপিসি লেনদেনের বাফার আকারটি 1024KB তে সেট করা আছে। কেন এটি লেনদেন বাফারকে ছাড়িয়ে গেছে আমি নিশ্চিত নই।

যখন আপনি অভিপ্রায় অতিরিক্তগুলির মাধ্যমে প্রচুর ডেটা পাস করেন তখন এটিও ঘটতে পারে

আপনি যখন আপনার অ্যাপ্লিকেশনটিতে এই ব্যতিক্রম পান, দয়া করে আপনার কোডটি বিশ্লেষণ করুন।

  1. আপনি কি আপনার পরিষেবা এবং অ্যাপ্লিকেশন মধ্যে প্রচুর ডেটা এক্সচেঞ্জ করছেন?
  2. বিপুল তথ্য ভাগ করে নেওয়ার উদ্দেশ্যে, উদাহরণস্বরূপ, ব্যবহারকারী গ্যালারী শেয়ার প্রেস শেয়ার থেকে বিপুল সংখ্যক ফাইল নির্বাচন করে, নির্বাচিত ফাইলগুলির ইউআরআইগুলি ইন্টেন্ট ব্যবহার করে স্থানান্তরিত হবে)
  3. পরিষেবা থেকে বিটম্যাপ ফাইলগুলি গ্রহণ করা
  4. অ্যান্ড্রয়েডের জন্য বিশাল ডেটা দিয়ে প্রতিক্রিয়া জানার জন্য অপেক্ষা করা (উদাহরণস্বরূপ, ব্যবহারকারীরা প্রচুর অ্যাপ্লিকেশন ইনস্টল করার সময় getInstalled অ্যাপ্লিকেশনগুলি () পান)
  5. প্রয়োগ ব্যাচ () ব্যবহার করে প্রচুর অপারেশন মুলতুবি রয়েছে

আপনি যখন এই ব্যতিক্রমটি পাবেন তখন কীভাবে পরিচালনা করবেন

যদি সম্ভব হয় তবে বড় অপারেশনটিকে ছোট ছোট ভাগে বিভক্ত করুন, উদাহরণস্বরূপ, 1000 অপারেশন দিয়ে অ্যাপলব্যাচ () কল করার পরিবর্তে, একে একে 100 দিয়ে কল করুন।

পরিষেবা এবং অ্যাপ্লিকেশন মধ্যে বিশাল ডেটা (> 1MB) বিনিময় করবেন না

আমি এটি কীভাবে করব তা জানি না, তবে, অ্যান্ড্রয়েডের জিজ্ঞাসা করবেন না, যা বিশাল ডেটা ফিরে আসতে পারে :-)


1
ধরুন আমি আমার .apk ইনস্টল করছি কিনা তা পরীক্ষা করে দেখছি নাকি? ইনস্টলেশন করার সময় ... আমি আমার প্যাকেজ com.test.installedornot পরীক্ষা করার সময় একই ব্যতিক্রম পাচ্ছি y আমার .apk আকার 9MB এর চেয়ে বেশি তবে সে ক্ষেত্রে আমি এই ব্যতিক্রমটি কীভাবে পরিচালনা করব?
ডিজেন

15
আমি কল করার সময় ঠিক এই ব্যতিক্রম পাচ্ছি getInstalledApplications। এটি সমাধান করার জন্য কী করা যেতে পারে?
স্ট্যান

1
@ স্ট্যান এই এপিআই সাধারণ এবং অ্যান্ড্রয়েড অ্যাপের চারপাশে ব্যাপকভাবে ব্যবহৃত হয়। আমি যখন এই এপিআই ব্যবহার করি তখন এই ব্যতিক্রমটি সত্যিই আমাকে চিন্তিত করে।
শান্তিবোধ

7
500KB এর কাছাকাছি কোথাও সীমাবদ্ধতা সম্পর্কে আমি আপনার সিদ্ধান্তগুলি নিশ্চিত করতে পারি তবে এটি ডিভাইস নির্দিষ্ট, কিছু ডিভাইসে আপনি প্রায় পুরো 1 এমবি স্থানান্তর করতে পারেন। আমারও এই ব্যতিক্রম ছিল, তাই আমি কিছু তদন্ত করেছি এবং এমন একটি পোস্ট লিখেছি যা এই সমস্যাযুক্ত লোকদের জন্য আকর্ষণীয়ভাবে পড়তে পারে। nemanjakovacevic.net/blog/english/2015/03/24/…
নেমানজা কোভাসেভিচ

11
আপনি যদি ঠিক কোন রাজ্যটি আপনার ক্র্যাশ ঘটাচ্ছে তা খুঁজে বের করতে যদি আপনি অসুবিধাজনিত হয়ে থাকেন তবে আপনি সম্ভবত টুলারজটুলকে দরকারী বলে মনে করতে পারেন ।
সর্বোচ্চ স্পেনসার

48

কোন পার্সেল আপনার ক্র্যাশ ঘটাচ্ছে তা যদি আপনার তদন্তের দরকার হয় তবে আপনার টোলারজটুল চেষ্টা করার বিষয়টি বিবেচনা করা উচিত ।

(আমি এটি ম্যাক্সড স্পেন্সারের কাছ থেকে গৃহীত উত্তরের অধীনে একটি মন্তব্য হিসাবে পেয়েছি এবং এটি আমার ক্ষেত্রে সহায়ক ছিল))


9
সর্বাধিক আন্ডাররেটেড সমাধান। এই সরঞ্জামটি আপনাকে আপত্তিজনক ক্রিয়াকলাপ সঙ্কুচিত করতে সহায়তা করে
কেদার পরানজপে

এই সমস্যাটি আমার সমস্যা সমাধানে সহায়তা করেছে। ইনস্টল এবং ব্যবহার করা সহজ।
কার্লোস

এই সরঞ্জামটি কোটলিনের জন্য: / জাভার কোনও বিকল্প?
ম্যাক্সওয়েলওয়েজ

2
@ ম্যাক্সওয়েলওয়েজ: সর্বশেষতম সংস্করণ (০.২.১, ০.০.০) এর মতো মনে হচ্ছে বর্তমানে জাভা-কেবল-অ্যাপ্লিকেশনগুলিতে কাজ করছে না। আমাকে 0.1.6 সংস্করণটি ব্যবহার করতে হয়েছিল এবং এটি তখন ভাল কাজ করেছে
হেইসেনবার্গ

এই সরঞ্জামটি ব্যবহার করে আমি সনাক্ত করেছি যে আমি আমার টুকরোগুলিতে বিশাল আকারের বান্ডিল ব্যবহার করছি। আমি যা করেছি তা হ'ল বান্ডিলটি থেকে যুক্তিটি বের করা এবং ব্যবহার করে বান্ডিলটি সাফ করাbundle.clear()
EJ Chathuranga

41

এটি একটি চূড়ান্ত উত্তর নয়, তবে এটি এর কারণগুলির উপর কিছুটা আলোকপাত করতে পারে TransactionTooLargeExceptionএবং সমস্যাটি চিহ্নিত করতে সহায়তা করতে পারে।

যদিও বেশিরভাগ উত্তরগুলি বিপুল পরিমাণে স্থানান্তরিত ডেটা বোঝায়, আমি দেখতে পাচ্ছি ভারী স্ক্রোলিং এবং জুমিং এবং বারবার অ্যাকশনবার স্পিনার মেনু খোলার পরে ঘটনাক্রমে এই ব্যতিক্রমটি ছুঁড়ে ফেলা হচ্ছে। ক্রিয়াটি অ্যাকশন বারে আলতো চাপলে ঘটে। (এটি একটি কাস্টম ম্যাপিং অ্যাপ্লিকেশন)

চারপাশে কেবলমাত্র পাস করা ডেটা মনে হচ্ছে "ইনপুট ডিসপ্যাচার" থেকে অ্যাপ্লিকেশনটিতে স্পর্শ করা। আমি মনে করি এটি "লেনদেন বাফার" এর 1 এমবি কাছাকাছি জায়গায় যুক্তিসঙ্গত পরিমাণে পরিমাণে আসতে পারে না।

আমার অ্যাপ্লিকেশনটি কোয়াড কোর ১.6 গিগাহার্টজ ডিভাইসে চলছে এবং ভারী উত্তোলনের জন্য তিনটি থ্রেড ব্যবহার করে, একটি কোর ইউআই থ্রেডের জন্য মুক্ত রাখে। তদ্ব্যতীত, অ্যাপটি অ্যান্ড্রয়েড ব্যবহার করে: লার্জহীপ, 10 এমবি অব্যবহৃত হিপ বাম রয়েছে এবং গাদাটি বাড়ানোর জন্য 100 এমবি ঘর রয়েছে। সুতরাং আমি বলব না এটি একটি সংস্থান সমস্যা।

ক্রাশটি সর্বদা এই লাইনের আগেই ঘটে:

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

যেগুলি ক্রমে এই ক্রমে মুদ্রিত হয় না, তবে (যতদূর আমি পরীক্ষা করেছি) একই মিলিসেকেন্ডে ঘটে happen

এবং স্ট্যাক নিজেই, স্পষ্টতার জন্য, প্রশ্নের মত একই:

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 সম্পর্কিত ক্রিয়াকলাপের সমস্ত ধরণের ব্যতিক্রম যেমন উপরের ব্যতিক্রম এবং এমনকি কিছু সিএসএসইজিভি'র ফলাফলও রয়েছে in দৃশ্যত কোনও ফাইল / সকেট খুলতে ব্যর্থতা এমন কিছু নয় যা অ্যান্ড্রয়েড জুড়ে খুব পরিষ্কারভাবে পরিচালনা / প্রতিবেদন করা হয়।


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এবং ওএস এটি 100+ আইটেম পছন্দ করে না The

অতএব আমাদের জন্য সমাধানটি 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

যারা ট্রানজেকশন টু লার্জএক্সেপশন কেন আসে তার উত্তরের জন্য যারা তিক্তভাবে হতাশ হয়েছেন, তাদের উদাহরণস্বরূপ আপনি কতটা তথ্য সংরক্ষণ করেন তা যাচাই করার চেষ্টা করুন।

সংকলন / টার্গেটএসডিভি ভার্সন <= 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)

তবে সংকলন / টার্গেটএসডিপি ভার্সন> = 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) 

কি করো?

স্থানীয় ডাটাবেসে ডেটা সংরক্ষণ করুন এবং কেবলমাত্র আইডি রাখুন যা আপনি এই ডেটা পুনরুদ্ধার করতে ব্যবহার করতে পারেন।


এটি কী বিশ্বব্যাপী প্যারামিটার হিসাবে রাখা এবং এটি পরে ব্যবহার করা সম্ভব?
জিতেন্দ্র রামোলিয়া

@ জিতেন্দ্রমোলিয়া হ্যাঁ, আপনি পারেন এটাই আমি বলতে চাইছি।
ইয়াজোন ২০০6

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/avoider-transactiontoolargeexception-on-android-nougat-and-up/


1
অ্যাপ্লিকেশন ব্যাকগ্রাউন্ডে থাকা অবস্থায় এবং ক্রিয়াকলাপটি ধ্বংস হয়ে যায় এবং আপনি অগ্রভাগের ক্রিয়াকলাপটি করার চেষ্টা করলে কী হবে?
মাস্টার বিপর্যয়

@ মাস্টারডিসাস্টার সেক্ষেত্রে কোনও রাজ্য সংরক্ষণ করা হয়নি কারণ উদাহরণটি খণ্ডিত প্রক্রিয়াটি মারা গেছে।
বৈদেন 9

অধিকার, সুতরাং এই কেসটি শুধুমাত্র কনফিগারেশন পরিবর্তনের সাথে কাজ করে।
মাস্টার দুর্যোগ

এটি যখনই ওএস ট্রিগার করে কাজ করে onSavedState(), যা অনেক ক্ষেত্রে ঘটে। কনফিগারেশন পরিবর্তন এক। অ্যাপ্লিকেশন স্যুইচ করা এবং ব্যাকগ্রাউন্ডে যাওয়া অন্য একটি another এবং আরও আছে।
বৌদিন

1
আমি মনে করি বিভিন্ন উত্স থেকে ডেটা সংরক্ষণ করতে এই সমাধানটি প্রসারিত করা উচিত। সম্ভবত একটি হ্যাশম্যাপ যা কী হিসাবে ট্যাগ এবং মান হিসাবে বান্ডিল রয়েছে ..
কুলমাইন্ড

11

এই সমস্যার কোনও নির্দিষ্ট কারণ নেই me আমার জন্য, আমার খণ্ড শ্রেণিতে আমি এটি করছিলাম:

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
যদি এটি হয় তবে কেন আমি কেবল অ্যান্ড্রয়েড ৪.৪ ফোনে পাচ্ছি এবং অন্য কোথাও নেই। আমি মনে করি এটি ৪.৪-তে আরও বেশি বাগ আছে যেটি কেন তা বুঝতে পেরেছি।
জেপিএম

9

আমিও একটি স্যামসাং এস 3 এ এই ব্যতিক্রম পেয়েছি। আমি 2 মূল কারণগুলি সন্দেহ করি,

  1. আপনার বিটম্যাপস রয়েছে যা লোড করে এবং খুব বেশি স্মৃতি গ্রহণ করে, ডাউনসাইজিং ব্যবহার করে
  2. আপনার আঁকা-_ডিপিআই ফোল্ডারগুলি থেকে কিছু আঁকিয়ে যায়, অ্যান্ড্রয়েডগুলি তাদের আঁকতে সক্ষম হয় এবং তাদের আকার পরিবর্তন করে আপনার সেটকন্টেন্টভিউ হঠাৎ করে লাফিয়ে উঠে এবং প্রচুর স্মৃতি ব্যবহার করে।

ডিডিএমএস ব্যবহার করুন এবং আপনার অ্যাপ্লিকেশনটি খেলতে থাকায় আপনার গাদাটি দেখুন, এটি আপনাকে কিছুটা ইঙ্গিত দেয় যা সেট কনটেন্টভিউ সমস্যাটি তৈরি করছে।

সমস্যা 2 থেকে মুক্তি পেতে আমি সমস্ত ফোল্ডারগুলিতে সমস্ত আঁকাগুলি অনুলিপি করেছি।

সমস্যা সমাধান করা হয়।


মেমরি / বিটম্যাপ ব্যতিক্রমগুলি সাধারণত আলাদা দেখায়। আমি ইতিমধ্যে তাদের মধ্যে অনেকগুলি অ্যান্ড্রয়েড 2.x - 4.x দিয়ে পরীক্ষা করে দেখেছি এবং ব্যতিক্রমগুলি সর্বদা আলাদা দেখায়। তবে, কে জানে, সম্ভবত এটি সম্পর্কিত তবে 4.x সংস্করণেও নির্দিষ্ট।
আইএক্সএক্স

10
তথ্য সম্পর্কিত এটি কেবল একটি ভয়াবহ ব্যতিক্রম, যেহেতু সমস্যাটি কোথা থেকে এসেছে সে সম্পর্কে কোনও ধারণা দেয় না।
আইএক্সএক্স

আমার মনে হয় কয়েকটা দিন শেষ হয়ে গেছে, আপনার সন্ধানগুলি কী?
ডেনি

8

এটি আপনার ক্রিয়াকলাপে যুক্ত করুন

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

এটি আমার পক্ষে কাজ করে আশা করি এটি আপনাকে সহায়তা করবে


7
আমি মনে করি, এটি সবচেয়ে ক্ষতিকারক ইঙ্গিত। আমরা যে ডেটা পুনরুদ্ধার করতে চাই তা কেন পরিষ্কার করব onCreate()?
শীতলমাইন্ড

2
এই কোডটির প্রভাবগুলি হ'ল আপনি নিজের উদাহরণের রাজ্যটি সংরক্ষণ না করে শেষ করেছেন ...
জাস্টিন

4

আমাদের জন্য এটি ছিল আমরা আমাদের এআইডিএল ইন্টারফেসের মাধ্যমে কোনও রিমোট সার্ভিসে কোনও বৃহত কোনও বস্তু প্রেরণের চেষ্টা করছি। লেনদেনের আকার 1MB ছাড়িয়ে যেতে পারে না। অনুরোধটি 512KB এর পৃথক অংশে বিভক্ত হয়ে ইন্টারফেসের মাধ্যমে একবারে একটি পাঠানো হয়েছে। আমি জানি কিন্তু একটি নির্মম সমাধান - এর অ্যান্ড্রয়েড :(


4

OnSaveInstanceState পদ্ধতি থেকে আপনি আপনার পুরানো ইনস্ট্যান্সস্টেটটি সাফ করেছেন এবং এটি ভালভাবে কাজ করবে। আমি আমার ভিউপ্যাজারের জন্য ফ্র্যাগমেন্টস্টেটপেজার অ্যাডাপ্টার ব্যবহার করছি তাই পরিষ্কার ইনস্ট্যান্সস্টেটের জন্য আমি আমার পিতামাতার ক্রিয়াকলাপে ওভাররাইড পদ্ধতিটি নীচে রাখি।

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

আমি এই সমাধানটি এখানে এন্ড্রয়েড.ওস থেকে পেয়েছি ou


তোমাকে অনেক ধন্যবাদ.
অ্যান্ড্রেন

ধন্যবাদ আপনার উত্তর আমাকে সাহায্য করুন
যতীন প্যাটেল

3

সম্প্রতি আমি অ্যান্ড্রয়েডের পরিচিতি সরবরাহকারীর সাথে কাজ করার সময় একটি আকর্ষণীয় ক্ষেত্রেও মুখোমুখি হয়েছি ।

আমার অভ্যন্তরীণ পরিচিতি ডাটাবেস থেকে পরিচিতিগুলির ফটো লোড করা দরকার এবং সিস্টেম আর্কিটেকচার অনুসারে এই সমস্ত ডেটা যোগাযোগ সরবরাহকারীকে কোয়েরি করে সরবরাহ করা হয়।

এটি যেমন একটি পৃথক অ্যাপ্লিকেশন হিসাবে কাজ করে - বাইন্ডার প্রক্রিয়া ব্যবহার করে সমস্ত ধরণের ডেটা ট্রান্সফার করা হয় এবং তাই বাইন্ডার বাফারটি এখানে কার্যকর হয় play

আমার মূল ভুলটি ছিল আমি বন্ধ করিনিCursor যোগাযোগ প্রোভাইডার থেকে অর্জিত ফোঁটা তথ্য দিয়ে, যাতে মেমরির সরবরাহকারীর জন্য বরাদ্দ বৃদ্ধি এবং এই দপ্তরী বাফার পর্যন্ত আমি টন পেয়েছিলাম স্ফীত !!!FAILED BINDER TRANSACTION!!!আমার Logcat আউটপুটে বার্তা।

সুতরাং মূল ধারণাটি হ'ল আপনি যখন বাহ্যিক সামগ্রী সরবরাহকারীদের সাথে কাজ করেন এবং Cursorসেগুলি থেকে সার্থক হন, আপনি যখন তাদের সাথে কাজ শেষ করেন সর্বদা এটি বন্ধ করুন।


3

আমি যখন ইন্টেন্টের মাধ্যমে বিটম্যাপ প্রেরণ করার চেষ্টা করেছি এবং একই সময়ে যখন আমি অ্যাপ্লিকেশনটি ভাঁজ করেছি তখন একই সমস্যার মুখোমুখি হয়েছি।

এটি কীভাবে এই নিবন্ধে বর্ণিত হয়েছে এখানে লিঙ্কের বর্ণনা লিখুন তা ঘটে যখন কোনও ক্রিয়াকলাপ বন্ধ হওয়ার প্রক্রিয়াধীন থাকে, তার অর্থ এই যে ক্রিয়াকলাপটি পুনরায় পুনরুদ্ধারের জন্য সুরক্ষিত সংরক্ষণের জন্য তার সংরক্ষিত রাজ্য বান্ডিলগুলি সিস্টেম ওএস-এ প্রেরণ করার চেষ্টা করছিল (কোনও কনফিগার পরিবর্তনের পরে) বা মৃত্যুর প্রক্রিয়া) তবে এটি প্রেরিত এক বা একাধিক বান্ডিলগুলি খুব বড়।

আমি আমার কার্যকলাপে সেভিআইনস্ট্যান্সস্টেটকে ওভাররাইড করে হ্যাকের মাধ্যমে সমাধান করেছি:

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

এবং মন্তব্য সুপার সুপার। এটি একটি নোংরা হ্যাক তবে এটি পুরোপুরি কাজ করছে। বিটম্যাপ ক্র্যাশ ছাড়াই সফলভাবে প্রেরণ করা হয়েছিল। আশা করি এটি কারও সাহায্য করবে।


2

আমার ক্ষেত্রে আমি সিএসএসইজিভিতে নেটিভ লাইব্রেরি ক্র্যাশ হওয়ার পরে গৌণ ক্রাশ হিসাবে লেনদেন টু লার্জএক্সেপশন পাই। নেটিভ লাইব্রেরির ক্র্যাশটির খবর পাওয়া যায় নি তাই আমি কেবল ট্রানজেকশন টু লার্জএক্সেপশন পাই।


2

একটি বড় কন্টেন্টভ্যালু [] বাল্ক ইনস্ট্রিট করার চেষ্টা করার সময় আমি আমার সিঙ্ক্যাডাপ্টারে এটি পেয়েছিলাম। আমি নিম্নলিখিত হিসাবে এটি ঠিক করার সিদ্ধান্ত নিয়েছে:

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
অন্য যদি ব্যর্থ হয়? একটি লুপ ব্যবহার করে আপনাকে আরও বিভাজন করতে হবে। লেনদেনের আকার এবং সর্বাধিক লেনদেনের আকার পাওয়ার কোনও উপায় কি আছে?
অ্যান্ড্রয়েড বিকাশকারী

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প্রথমবার জন্য খোলা হয় হচ্ছে অথবা পরে অ্যাপ্লিকেশনটি Android দ্বারা বন্ধ হত্যা করা হয়েছে, যা 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);

এটি খুব খারাপ ধারণা। স্ট্যাটিক ভেরিয়েবলগুলি সেভাবে ব্যবহার করা কোডের গন্ধ। এছাড়াও, "ক্রিয়াকলাপগুলি রাখবেন না" পতাকা সহ এই কোডটি চালানোর চেষ্টা করুন এবং আপনি পেজওয়েভিউতে নেভিগেট করার পরে হোম টিপুন। আপনি আবার আপনার ক্রিয়াকলাপটি খোলার পরে আপনি সম্ভবত ক্র্যাশ পাবেন কারণ মেইনএ্যাকটিভিটির সমস্ত ভেরিয়েবলের সাথে 100% মারা যাবে।
কিরিলো জাপিলিয়েভ

1

আমি যখন WebViewআমার অ্যাপ্লিকেশনটিতে কাজ করি তখন এটি ঘটে। আমি মনে করি এটি সম্পর্কিত addViewএবং ইউআই সংস্থার সাথে সম্পর্কিত । আমার অ্যাপে আমি WebViewActivityনীচের মত এর মতো কিছু কোড যুক্ত করেছি তবে এটি ঠিক আছে:

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

1

আমি এর মূল কারণটি খুঁজে পেয়েছি (এমভিডিএস যেমন বলেছে আমরা "অ্যাডিং উইন্ডো ব্যর্থ" এবং ফাইল বর্ণনাকারী ফাঁস উভয়ই পেয়েছি)।

অ্যান্ড্রয়েড ৪.৪-এর একটি বাগ রয়েছে BitmapFactory.decodeFileDescriptor()। এটা শুধুমাত্র ঘটে যখন inPurgeableএবং inInputShareableএর BitmapOptionsসেট করা হয়true । এটি অনেক জায়গায় ফাইলগুলির সাথে ইন্টারঅ্যাক্ট করার কারণে অনেক সমস্যার সৃষ্টি করে।

নোট করুন যে পদ্ধতিটি থেকেও আহ্বান করা হয়েছে MediaStore.Images.Thumbnails.getThumbnail()

ইউনিভার্সাল ইমেজ লোডার এই সমস্যা দ্বারা প্রভাবিত হয়। পিকাসো এবং গ্লাইড প্রভাবিত হয়নি বলে মনে হচ্ছে। https://github.com/nostra13/Android-Universal-Image-Loader/issues/1020


1

WritToParcel (পার্সেল ডেস্ট, ইন্ট ফ্ল্যাগ) পদ্ধতিতে কোডের এই এক লাইনটি আমাকে ট্রানজেকশন টু লার্জএক্সেপশন থেকে মুক্তি পেতে সহায়তা করেছিল।

dest=Parcel.obtain(); 

এই কোডের পরে কেবলমাত্র আমি সমস্ত তথ্য পার্সেল অবজেক্টে লিখছি অর্থাৎ ডেসটাইটারাইট ইন () ইত্যাদি


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


দেখা লেনদেনের টু লার্জএক্সপেশন

বাইন্ডার লেনদেন ব্যর্থ হয়েছে কারণ এটি অনেক বড়।

একটি রিমোট পদ্ধতি কলের সময়, আর্গুমেন্ট এবং কলটির রিটার্ন মান বাইন্ডার লেনদেন বাফারে সংরক্ষিত পার্সেল অবজেক্ট হিসাবে স্থানান্তরিত হয়। যদি আর্গুমেন্ট বা রিটার্ন মানটি লেনদেনের বাফারের সাথে মানানসই আকারে বড় হয় তবে কলটি ব্যর্থ হবে এবং লেনদেনের টু লার্জএক্সেপশন নিক্ষেপ করা হবে।


1

আমি একটি অ্যান্ড্রয়েড এসপ্রেসো পরীক্ষায় স্ট্যাকওভারফ্লো ত্রুটি থেকে একটি ট্রানজেকশন টু লার্জএক্সপেশন পেয়েছি। আমি যখন আমার অ্যাপ্লিকেশনটির জন্য লগক্যাট ফিল্টারটি বন্ধ করেছিলাম তখন আমি লগগুলিতে স্ট্যাকওভারফ্লো ত্রুটির স্ট্যাক ট্রেস পেয়েছি।

আমি অনুমান করছি যে সত্যিকারের বৃহত ব্যতিক্রম স্ট্যাকট্র্যাকগুলি হ্যান্ডেল করার চেষ্টা করার সময় এস্প্রেসো ট্রানজেকশন টু লার্জএক্সেপশন ঘটায়।


1

যে কেউ ব্যবহার করতে পারেন:

android:largeHeap="true"

অ্যাপ্লিকেশন ট্যাগের অধীনে অ্যান্ড্রয়েড ম্যানিফেস্টে।

এটি আমার ক্ষেত্রে সমস্যার সমাধান!


আমার ক্ষেত্রে ( onSaveInstantStateক্রিয়াকলাপ / টুকরোগুলি কল করার এবং বড় তালিকাগুলি সংরক্ষণ করার কারণে) এটি কোনও লাভ হয়নি।
শীতলমান্ড

1
এটিকে খারাপ অনুশীলন হিসাবে বিবেচনা করা হয় কারণ প্রচুর পরিমাণে ডেটা প্রথম স্থানে সংরক্ষিত হওয়ার কারণটি আপনি মোকাবেলা করছেন না। আরও নতুন ডিভাইসে এটি অ্যাপটিকে ক্র্যাশ করে এবং সীমাটি আরও ছোট (256 কেবি)। আপনি প্রথমে কেন প্রচুর পরিমাণে সংরক্ষণ করছেন এবং তদন্ত করুন।
টিম কিস্ট

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

এটি আমার অ্যাপ্লিকেশনটিতে ঘটছিল কারণ আমি কোনও খণ্ডের যুক্তিতে অনুসন্ধান ফলাফলের একটি তালিকা পাস করছিলাম, সেই তালিকাটি খণ্ডটির কোনও সম্পত্তিতে অর্পণ করছিলাম - যা প্রকৃতপক্ষে খণ্ডটির যুক্তিগুলির দ্বারা চিহ্নিত মেমরির একই অবস্থানের একটি রেফারেন্স - তারপরে যুক্ত করা হচ্ছে তালিকায় নতুন আইটেম, যা খণ্ডের যুক্তিগুলির আকারও পরিবর্তন করেছে। ক্রিয়াকলাপ স্থগিত করা হলে, বেস টুকরা ক্লাসটি সেভআইন্সট্যান্সস্টেটে টুকরোটির যুক্তিগুলি সংরক্ষণ করার চেষ্টা করে, যা আর্গুমেন্ট 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"));
    }
}

এর চেয়ে আরও ভাল সমাধান হ'ল আর্গুমেন্টগুলিতে এতগুলি ডেটা না দিয়ে।

আমি এই উত্তর এবং টোলারজটুলের সাহায্য ছাড়া সম্ভবত এটি কখনই পেতাম না ।


1

আমি ট্রানজেকশন টু লার্জএক্সসেপশনও বেঁচে আছি। প্রথম কোথায় আছে তা বুঝতে পেরে আমি কাজ করেছি। আমি জানি কেন এটি ঘটে যায়। আমরা প্রত্যেকে বড় কন্টেন্টের কারণে জানি। আমার সমস্যাটি এরকমই ছিল এবং আমি সমাধান করেছি। এই সমাধানটি কারও পক্ষে কার্যকর হতে পারে। আমার একটি অ্যাপ্লিকেশন রয়েছে যা এপিআই থেকে সামগ্রী পাওয়া যায়। আমি প্রথম স্ক্রিনে এপিআই থেকে ফলাফল পাচ্ছি এবং এটি দ্বিতীয় স্ক্রিনে প্রেরণ করছি। আমি এই বিষয়বস্তু সফলভাবে দ্বিতীয় স্ক্রিনে প্রেরণ করতে পারি। দ্বিতীয় স্ক্রিনের পরে যদি আমি তৃতীয় স্ক্রিনে যেতে চাই তবে এই ব্যতিক্রম ঘটে। আমার প্রতিটি স্ক্রিন ফ্র্যাগমেন্ট থেকে তৈরি করা হয়েছে। আমি লক্ষ্য করেছি যে আমি যখন দ্বিতীয় পর্দা থেকে ছাড়ি। এটি এর বান্ডিল সামগ্রী সংরক্ষণ করে। যদি এই বিষয়বস্তুটি খুব বেশি হয় তবে এই ব্যতিক্রম ঘটে। আমার সমাধানটি আমি বান্ডিল থেকে সামগ্রী পেয়েছি এটি পরিষ্কার করার পরে clear

class SecondFragment : BaseFragment() {

    lateinit var myContent: MyContent

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

যদিও এটি সঠিক (আমার কাছে লজ্জাজনক, আমি এক বছর পরেও একই বুঝেছিলাম), খণ্ডটি পুনরায় তৈরি করা হলে (স্ক্রিন রোটেশন) কীভাবে করবে?
কুলমাইন্ড

0

অ্যাপ্লিকেশনটির জন্য ফাইল সিস্টেমে অ্যারেলিস্ট (বা যে কোনও বিষয়ই সমস্যা সৃষ্টি করছে) লিখতে হবে তার সমাধান হ'ল ইনটেন্ট সার্ভিসে ইনটেন্টের মাধ্যমে সেই ফাইলটির (যেমন, ফাইলের নাম / পাথ) একটি রেফারেন্স দিন এবং তারপরে ইনটেন্ট সার্ভিসকে দিন ফাইলের সামগ্রীগুলি পুনরুদ্ধার করুন এবং এটিকে আবার অ্যারেলিস্টে রূপান্তর করুন।

ইন্টেন্ট সার্ভিস ফাইলটি সম্পন্ন করার পরে, এটি হয় এটি মুছে ফেলা উচিত বা এটি তৈরি করা ফাইলটি মুছে ফেলার জন্য স্থানীয় ব্রডকাস্টের মাধ্যমে অ্যাপ্লিকেশনটিতে নির্দেশটি ফেরত পাঠানো উচিত (এটি সরবরাহ করা একই ফাইলের রেফারেন্সটি ফিরিয়ে দিয়ে)।

আরও তথ্যের জন্য এই সম্পর্কিত সমস্যার আমার উত্তর দেখুন ।


0

ইন্টেন্টস, সামগ্রী সরবরাহকারী, ম্যাসেঞ্জার হিসাবে, টেলিফোন, ভাইব্রেটর ইত্যাদির মতো সমস্ত সিস্টেম পরিষেবাদি বাইন্ডার দ্বারা আইপিসি অবকাঠামো সরবরাহকারীর ব্যবহার করে oreএছাড়া ক্রিয়াকলাপের লাইফসাইকেল কলব্যাকগুলিও এই অবকাঠামো ব্যবহার করে।

1MB হ'ল নির্দিষ্ট মুহুর্তে সিস্টেমে কার্যকর সমস্ত বাইন্ডার লেনদেনের সামগ্রিক সীমা।

অভিপ্রায় পাঠানোর সময় প্রচুর লেনদেন ঘটতে থাকলে অতিরিক্ত ডেটা বড় না হলেও এটি ব্যর্থ হতে পারে। http://codetheory.in/an-overview-of-android-binder-framework/


0

ট্রানজেকশন টু লার্জএক্সেপশন ঘটতে পারে এমন অনেক জায়গার সাথে - এখানে অ্যান্ড্রয়েড 8-এ আরও একটি নতুন বিষয় রয়েছে - যখন বিষয়বস্তু খুব বড় হয় তবে কেউ কেবল সম্পাদনা-পাঠ্য টাইপ করতে শুরু করে।

এটা তোলে এর সাথে সম্পর্কিত হচ্ছে AutoFillManager (API এর 26 নতুন) এবং নিম্নলিখিত কোড StartSessionLocked():

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

যদি আমি সঠিকভাবে বুঝতে পারি তবে এটি স্বতঃপূরণ পরিষেবাটি কল করে - বাইন্ডারের মধ্যে অটোফিলম্যানেজারক্লিয়েন্টটি পাস করছে। এবং এডিটেক্সটটিতে যখন প্রচুর সামগ্রী থাকে, তখন মনে হয় এটি টিটিএলএল সৃষ্টি করে।

কয়েকটি জিনিস এটিকে প্রশমিত করতে পারে (বা আমি যেভাবেই পরীক্ষা করছিলাম সেভাবেই করেছে): android:importantForAutofill="noExcludeDescendants"এডিটেক্সট এর এক্সএমএল লেআউট ঘোষণায় যুক্ত করুন। অথবা কোডে:

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 য় ভয়ঙ্কর, ভয়ানক কাজটি একটি টেক্সটএডিট সাবক্লাসে নিজেই ত্রুটিটি ধরার পদ্ধতি performClick()এবং onWindowFocusChanged()পদ্ধতিগুলিকে ওভাররাইড করে। তবে আমি সত্যিই বুদ্ধিমান মনে করি না ...

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.