Codeegg’s 668th tweet

Author: Cheng Xiang Moying

Original: https://mp.weixin.qq.com/s/v57mDRnSEZ6hl7-bc3ugwA


A, sequence

For Android development, the most frequent operation of daily Coding should be the operation of a series of activities in the App. To pass data between activities, you need an Intent.

Many sources write that intEnts pass base-type data or serializable object data between activities. But Intent to there is a limit to the size of the data, when over the limit, it triggers TransactionTooLargeException anomalies.

Today we’ll talk about why intents throw exceptions when they deliver big data, and how to fix them.

Two, why the occurrence of abnormalities?

2.1 Abnormal Causes

Intent to deliver big data, there will be a TransactionTooLargeException scenario, this itself is a interview questions, often asked in an interview.

In fact, this problem, if encountered, check the documentation to know.

In TransactionTooLargeException (https://developer.android.com/reference/android/os/TransactionTooLargeException.html) In fact, the trigger cause has been specified in the documentation.

In short, IntEnts use binders as a mechanism for transferring data. The data in the Intent is transmitted as objects stored in the Binder transaction buffer for the Parcel.

The Binder transaction buffer has a finite fixed size, currently 1MB. Don’t assume that passing less than 1MB of data is safe; the 1MB space is not reserved for the current operation, but is shared by the current process. In other words, intEnts transfer data between activities and are not suitable for transferring too much data by themselves.

2.2 The Bundle’s pot?

Intents use bundles to store data. Are they passed by value (deep copy) or by reference?

The data transmitted by the Intent is stored in an mExtras object of type Bundle, and the Bundle requires that all stored data be serializable.

In Android, serializing data requires either Serializable or Parcelable implementation. The wrapper class for the underlying data type itself implements Serializable, while our custom object implements either of the two serialization interfaces on demand.

Is there a serialization problem whenever data is passed through the Bundle?

No, cross-process communication is a primary concern between activities, and Binder mechanisms handle cross-process communication in Android. When it comes to cross-processes, serialization and deserialization are involved for complex data, which is bound to be a value transfer (deep copy) process.

This problem using reduction to absurdity can also explain, if is the reference, the transfer of the past only object reference, points to the object store address, only equivalent to the size of an Int, also won’t appear abnormal TransactionTooLargeException.

Transferring data serialization has nothing to do with Bundle, only with cross-process communication with Binder.

Why emphasize this?

In Android, the use of bundles to transfer data is not unique to intEnts. For example, with popovers, you can also pass a Bundle object to the dialog box in DialogFragment using setArguments(Bundle).

The Fragment itself is cross-process free. The Bundle is used to transfer data, but not through Binder, meaning there is no serialization or deserialization. The Bundle associated with Fragment data passing is actually passing a reference to the original object.

If you’re interested, try passing an object when a Dialog pops up. After modifying data in the Dialog, check whether the data has been modified in the Activity.

How to resolve this exception?

3.1 Solution

If we know the cause of the anomaly, we can solve it.

Since Binder transmission limits the size of data, we can communicate without Binder.

You can think about it in terms of data sources.

Bitmap, for example, already implements Parcelable to support serialization. With Intent to transmit, a little bit big figure will appear TransactionTooLargeException. Of course, in a business scenario, there is no Bitmap transfer.

So let’s look at the data source for this image. Drawable? Local file? Online pictures? No matter where the data source is, we just need to pass a Drawable_ID, path, URL, and restore the image without passing the Bitmap object. Big data always has a data source, and restoring data from a data source is just calling a method for us.

Alibaba’s Android Developer’s Manual offers advice on how to solve this problem.


Ali’s solution is to pass the data through EventBus.

3.2 Sticky events of EventBus

Many commercial projects actually use EventBus, so here’s a quick look at how to use EventBus’s sticky events to transfer data between activities.

EventBus is an Android-optimized Publish/ Subscribe message bus that simplifies communication between components within an application and between components and background threads.

Using EventBus in an Activity calls the register() and unregister() methods in pairs, depending on the Activity lifecycle. Normal events will only occur after register(), and events that occur before register will not be received.

Sticky Events are implemented using EventBus, which maintains a Map object stickyEvents to cache Sticky events.

StickyEvents are sent using the postSticky() method, which cashes the event into stickyEvents, a Map object, for the next registration, which is then taken out and thrown to the registered component. In order to achieve a viscous lag event sent and received.

Let’s look at the details of how sticky events are used in EventBus.

(1) The difference between annotations

Annotations for sticky events are slightly different from annotations for normal events, requiring threadMode and sticky parameters.

@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)public void onStickyEvent(MyStickyEvent event){ //... }Copy the code

Note that these two additional parameters are required.

(2) The difference between calling methods

Replace the post() method with postSticky() when sending messages.

Note that sticky events are cached using the Map structure and are cached using the event object type as Key, so for data of the same type, it only caches the last data sent.

(3) Pay attention to cleaning events

As mentioned earlier, sticky events are stored in a Map object, which does not actively clean up the stored objects, requiring the developer to do so manually.

EventBus provides two classes of methods, removeStickyEvent() and removeAllStickyEvents(), to clean up fixed data and all data, respectively.

We need to manually call both types of methods when appropriate to clean up sticky events. If you do not clean up sticky events, you will receive sticky events every time you register().

(4) Sticky events in EventBus

Sticky events themselves are separate from Android’s Intent data delivery mechanism, as activities can be destroyed and rebuilt in special cases. In this case, the data passed through an Intent can be retrieved from the previous page.

Sticky events through EventBus can result in data loss during destruction and reconstruction.

If you want to use EventBus’s sticky events to transfer big data from page to page, there are a number of details that need to be tailored to your business.

Four, summary

Today we talk about the Activity rooms, large data shall be transmitted by Intent will trigger TransactionTooLargeException abnormal reason, and how to solve it, and then simple to summarize.

  1. Intents fail to deliver big data because of their internal use of the Binder communication mechanism, which limits the size of the data that can be delivered.

  2. Binder transaction buffers are limited to 1MB in size, but this size is shared, meaning that passing data below 1MB is not always safe, depending on the current environment.

  3. Do not push the limits of how big an Intent can be. For big data, such as long strings, bitmaps, etc., do not consider delivering data in an Intent.

  4. To solve the problem of big data transmission, we can start from the data source and restore the data according to the identification of the data, or persist and then restore the data. You can also use Sticky events from EventBus.

https://www.wanandroid.com/blogimgs/a2609aed-1000-4039-93c3-7541aaa2013b.pdf

Recent Articles:

  • I’m bloated! Continue to take your handwriting QQ bottom (3)

  • In times of peace, the interview questions can be seen more

  • It’s the weekend. You guys know the picture

Question of the day:

Is there an experience when a small point can be expanded to understand a lot?

Come to the community to unlock new poses! Community upgrade: Max your learning efficiency