-
Notifications
You must be signed in to change notification settings - Fork 24.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Petterh/support parcelable array args (#26379)
Summary: `ReactRootView.startReactApplication` takes a `Bundle` argument called `initialProperties`. This is translated to a `ReadableMap` via `Arguments.fromBundle`. If the bundle contains an array of bundles, this gets translated by `Arguments.fromArray`. If the bundle was passed from one activity to another via intent extras, however, there is a problem. After the bundle has been marshaled and unmarshaled, the array of `Bundle`s come out the other end as an arrap of `Parcelable`s, although each array element remains a `Bundle`. This results in an "Unknown array type" exception. This PR fixes this by adding support for `Parcelable` arrays – provided they contain only members of type `Bundle`. ## Changelog [Android] [Fixed] - Don't throw "Unknown array type" exception when passing serialized bundle arrays in ReactRootView.startReactApplication's initialProperties parameter Pull Request resolved: #26379 Test Plan: Added test class `ArgumentsTest`. The test method `testFromMarshaledBundle` fails when used on the old version of `Arguments`. Differential Revision: D17661203 Pulled By: cpojer fbshipit-source-id: 63612d78f49bdf9cc53f6f21ae883dba6cebce84
- Loading branch information
1 parent
e1d89fb
commit 4b93500
Showing
2 changed files
with
99 additions
and
0 deletions.
There are no files selected for viewing
89 changes: 89 additions & 0 deletions
89
ReactAndroid/src/androidTest/java/com/facebook/react/bridge/ArgumentsTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
package com.facebook.react.bridge; | ||
|
||
import android.content.Context; | ||
import android.content.Intent; | ||
import android.os.Bundle; | ||
import android.os.Parcel; | ||
import android.os.Parcelable; | ||
|
||
import androidx.annotation.NonNull; | ||
import androidx.test.platform.app.InstrumentationRegistry; | ||
import androidx.test.runner.AndroidJUnit4; | ||
|
||
import com.facebook.soloader.SoLoader; | ||
|
||
import org.junit.Before; | ||
import org.junit.Test; | ||
import org.junit.runner.RunWith; | ||
|
||
import static com.facebook.react.bridge.Arguments.fromBundle; | ||
import static org.junit.Assert.assertEquals; | ||
import static org.junit.Assert.assertNotNull; | ||
|
||
@RunWith(AndroidJUnit4.class) | ||
public class ArgumentsTest { | ||
|
||
@Before | ||
public void setUp() { | ||
Context context = InstrumentationRegistry.getInstrumentation().getTargetContext(); | ||
SoLoader.init(context, false); | ||
} | ||
|
||
@Test | ||
public void testFromBundle() { | ||
verifyBundle(createBundle()); | ||
} | ||
|
||
/** | ||
* When passing a bundle via {@link Intent} extras, it gets parceled and unparceled. | ||
* Any array of bundles will return as an array of {@link Parcelable} instead. This test | ||
* verifies that {@link Arguments#fromArray} handles this situation correctly. | ||
*/ | ||
@Test | ||
public void testFromMarshaledBundle() { | ||
verifyBundle(marshalAndUnmarshalBundle(createBundle())); | ||
} | ||
|
||
private void verifyBundle(@NonNull Bundle bundle) { | ||
WritableMap map = fromBundle(bundle); | ||
assertNotNull(map); | ||
|
||
assertEquals(ReadableType.Array, map.getType("children")); | ||
ReadableArray children = map.getArray("children"); | ||
assertNotNull(children); | ||
assertEquals(1, children.size()); | ||
|
||
assertEquals(ReadableType.Map, children.getType(0)); | ||
ReadableMap child = children.getMap(0); | ||
assertNotNull(child); | ||
assertEquals("exampleChild", child.getString("exampleChildKey")); | ||
} | ||
|
||
@NonNull | ||
private Bundle marshalAndUnmarshalBundle(@NonNull Bundle bundle) { | ||
Parcel parcel = null; | ||
try { | ||
parcel = Parcel.obtain(); | ||
bundle.writeToParcel(parcel, 0); | ||
|
||
byte[] bytes = parcel.marshall(); | ||
parcel.unmarshall(bytes, 0, bytes.length); | ||
parcel.setDataPosition(0); | ||
return Bundle.CREATOR.createFromParcel(parcel); | ||
} finally { | ||
if (parcel != null) { | ||
parcel.recycle(); | ||
} | ||
} | ||
} | ||
|
||
@NonNull | ||
private Bundle createBundle() { | ||
Bundle bundle = new Bundle(); | ||
Bundle[] children = new Bundle[1]; | ||
children[0] = new Bundle(); | ||
children[0].putString("exampleChildKey", "exampleChild"); | ||
bundle.putSerializable("children", children); | ||
return bundle; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters