Skip to content

Commit

Permalink
Add information about AppLoader to AndroidManifest's meta-data and co…
Browse files Browse the repository at this point in the history
…nsume it in AppLoaderProvider.
  • Loading branch information
mczernek committed May 22, 2020
1 parent 0d6412f commit 4156f32
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 43 deletions.
5 changes: 5 additions & 0 deletions android/expoview/src/main/AndroidManifest.xml
Expand Up @@ -106,6 +106,11 @@
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>

<meta-data
tools:replace="android:value"
android:name="org.unimodules.core.AppLoader#react-native-headless"
android:value="host.exp.exponent.taskManager.ExpoHeadlessAppLoader"/>
</application>

</manifest>
Expand Up @@ -53,16 +53,14 @@ public void onCreate() {
if (!Constants.isStandaloneApp()) {
KernelConstants.MAIN_ACTIVITY_CLASS = LauncherActivity.class;
}

AppLoaderProvider.registerLoader(this, "react-native-headless", ExpoHeadlessAppLoader.class);
KernelProvider.setFactory(new KernelProvider.KernelFactory() {
@Override
public KernelInterface create() {
return new Kernel();
}
});

ExponentKernelModuleProvider.setFactory(reactContext -> new ExponentKernelModule(reactContext));
ExponentKernelModuleProvider.setFactory(ExponentKernelModule::new);

Exponent.initialize(this, this);
NativeModuleDepsProvider.getInstance().add(Kernel.class, KernelProvider.getInstance());
Expand Down
Expand Up @@ -26,7 +26,6 @@ public class ReactAdapterPackage extends BasePackage {

@Override
public List<InternalModule> createInternalModules(Context context) {
AppLoaderProvider.registerLoader(context, "react-native-headless", RNHeadlessAppLoader.class);
// We can force-cast here, because this package will only be used in React Native context.
ReactContext reactContext = (ReactContext) context;
return Arrays.asList(
Expand Down
@@ -1,5 +1,11 @@
<manifest package="org.unimodules.adapters.react"
xmlns:android="http://schemas.android.com/apk/res/android">

<manifest package="org.unimodules.adapters.react">
<application>
<meta-data
android:name="org.unimodules.core.AppLoader#react-native-headless"
android:value="org.unimodules.adapters.react.apploader.RNHeadlessAppLoader"/>
</application>

</manifest>

Expand Up @@ -26,7 +26,6 @@ public class ReactAdapterPackage extends BasePackage {

@Override
public List<InternalModule> createInternalModules(Context context) {
AppLoaderProvider.registerLoader(context, "react-native-headless", RNHeadlessAppLoader.class);
// We can force-cast here, because this package will only be used in React Native context.
ReactContext reactContext = (ReactContext) context;
return Arrays.asList(
Expand Down
@@ -1,31 +1,16 @@
package org.unimodules.apploader;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.util.Log;

import java.util.HashMap;
import java.util.Map;

public class AppLoaderProvider {

private static Map<String, Class> loaderClasses = new HashMap<>();
private static Map<String, HeadlessAppLoader> loaders = new HashMap<>();

public static void registerLoader(Context context, String name, Class loaderClass) {
registerLoader(context, name, loaderClass, false);
}

public static void registerLoader(Context context, String name, Class loaderClass, boolean overload) {
if (!overload) {
if (appLoaderRegisteredForName(context, name, loaderClass)) return;
}
getSharedPreferences(context).edit()
.putString(appLoaderKey(name), loaderClass.getName())
.apply();
loaderClasses.put(name, loaderClass);
}

public static HeadlessAppLoader getLoader(String name, Context context) {
if (!loaders.containsKey(name)) {
try {
Expand All @@ -39,32 +24,21 @@ public static HeadlessAppLoader getLoader(String name, Context context) {
return loaders.get(name);
}

private static boolean appLoaderRegisteredForName(Context context, String name, Class loaderClass) {
String cachedClassName = getSharedPreferences(context).getString(appLoaderKey(name), null);
return loaderClasses.containsKey(name) && loaderClass.getName().equals(cachedClassName);
}

@SuppressWarnings("unchecked")
private static void createLoader(String name, Context context) throws ClassNotFoundException, IllegalAccessException, InstantiationException, java.lang.reflect.InvocationTargetException, NoSuchMethodException {
Class loaderClass = loaderClasses.get(name);
if (loaderClass == null) {
String loaderClassName = getSharedPreferences(context)
.getString(appLoaderKey(name), null);
Class<? extends HeadlessAppLoader> loaderClass;
try {
String loaderClassName = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA).metaData.getString("org.unimodules.core.AppLoader#" + name);
if (loaderClassName != null) {
loaderClass = Class.forName(loaderClassName);
loaderClass = (Class<? extends HeadlessAppLoader>)Class.forName(loaderClassName);
loaders.put(name, (HeadlessAppLoader) loaderClass.getDeclaredConstructor(Context.class).newInstance(context));
} else {
throw new IllegalStateException("Unable to instantiate AppLoader!");
}
} catch (PackageManager.NameNotFoundException e) {
throw new IllegalStateException("Unable to instantiate AppLoader!", e);
}
loaders.put(name, (HeadlessAppLoader) loaderClass.getDeclaredConstructor(Context.class).newInstance(context));
}

private static final String APP_LOADER_PREFERENCES_NAME = "appLoader_config";
private static final String KEY_LOADER_PREFIX = "appLoader_";

private static String appLoaderKey(String appLoaderName) {
return KEY_LOADER_PREFIX + appLoaderName;
}

private static SharedPreferences getSharedPreferences(Context context) {
return context.getSharedPreferences(APP_LOADER_PREFERENCES_NAME, Context.MODE_PRIVATE);
}

public static abstract class Callback {
Expand Down

0 comments on commit 4156f32

Please sign in to comment.