From c741acf7ccef6d73a23efb92b8410fb930d936cd Mon Sep 17 00:00:00 2001 From: Krzysztof Magiera Date: Tue, 15 Jan 2019 16:29:46 +0100 Subject: [PATCH] Unwrap Context in order to retrieve Activity subclass (#59) This fixes crash on Expo client which is wrapping Activity prior to passing it as a context to the root view. After my recent change in the logic on how we access main activity we know extract the reference to it using `getContext` from the root view. Previously we were using `getTopLevelActivity` which wasn't working well in the cases where other non-react-native activities were transitioning in or out. The new approach however turned out not to be the best as for example expo client does not pass activity instance as a context directly to the root view. Instead the activity class is wrapped in ContextThemeWrapper ([see it here](https://github.com/expo/expo/blame/41458d1de91544c41097818db21e44e9aa84688c/android/expoview/src/main/java/versioned/host/exp/exponent/ReactUnthemedRootView.java#L13)). We now try to unwrap the context if it is not a fragment activity using `getBaseContext` This fixes https://github.com/expo/expo/issues/3191 --- .../main/java/com/swmansion/rnscreens/ScreenContainer.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.java b/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.java index e0a0fd5e..82701084 100644 --- a/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.java +++ b/android/src/main/java/com/swmansion/rnscreens/ScreenContainer.java @@ -2,6 +2,7 @@ package com.swmansion.rnscreens; import android.app.Activity; import android.content.Context; +import android.content.ContextWrapper; import android.support.annotation.Nullable; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; @@ -93,8 +94,12 @@ public class ScreenContainer extends ViewGroup { if (!(parent instanceof ReactRootView)) { throw new IllegalStateException("ScreenContainer is not attached under ReactRootView"); } - // ReactRootView is expected to be initialized with the main React Activity as a context + // ReactRootView is expected to be initialized with the main React Activity as a context but + // in case of Expo the activity is wrapped in ContextWrapper and we need to unwrap it Context context = ((ReactRootView) parent).getContext(); + while (!(context instanceof FragmentActivity) && context instanceof ContextWrapper) { + context = ((ContextWrapper) context).getBaseContext(); + } if (!(context instanceof FragmentActivity)) { throw new IllegalStateException( "In order to use RNScreens components your app's activity need to extend ReactFragmentActivity or ReactCompatActivity");