Allow SDL to use ReLinker if present. This fixes issues for applications that have a large number of shared libraries For more information, see https://github.com/KeepSafe/ReLinker for ReLinker's repository.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
diff --git a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java
index bd9de19..0ab2269 100644
--- a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java
+++ b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceBLESteamController.java
@@ -577,7 +577,7 @@ class HIDDeviceBLESteamController extends BluetoothGattCallback implements HIDDe
}
// We need to skip the first byte, as that doesn't go over the air
- byte[] actual_report = Arrays.copyOfRange(report, 1, report.length - 1);
+ byte[] actual_report = Arrays.copyOfRange(report, 1, report.length - 1);
//Log.v(TAG, "sendFeatureReport " + HexDump.dumpHexString(actual_report));
writeCharacteristic(reportCharacteristic, actual_report);
return report.length;
diff --git a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java
index 33ddb71..ba30d0a 100644
--- a/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java
+++ b/android-project/app/src/main/java/org/libsdl/app/HIDDeviceManager.java
@@ -80,14 +80,14 @@ public class HIDDeviceManager {
public HIDDeviceManager(Context context) {
mContext = context;
- // Make sure we have the HIDAPI library loaded with the native functions
+ // Make sure we have the HIDAPI library loaded with the native functions
try {
- System.loadLibrary("hidapi");
+ SDL.loadLibrary("hidapi");
} catch (Exception e) {
Log.w(TAG, "Couldn't load hidapi: " + e.toString());
return;
}
-
+
HIDDeviceRegisterCallback(this);
mSharedPreferences = mContext.getSharedPreferences("hidapi", Context.MODE_PRIVATE);
diff --git a/android-project/app/src/main/java/org/libsdl/app/SDL.java b/android-project/app/src/main/java/org/libsdl/app/SDL.java
index cfe4830..58597c6 100644
--- a/android-project/app/src/main/java/org/libsdl/app/SDL.java
+++ b/android-project/app/src/main/java/org/libsdl/app/SDL.java
@@ -2,6 +2,8 @@ package org.libsdl.app;
import android.content.Context;
+import java.lang.reflect.*;
+
/**
SDL library initialization
*/
@@ -33,5 +35,50 @@ public class SDL {
return mContext;
}
+ public static void loadLibrary(String libraryName) throws UnsatisfiedLinkError, SecurityException, NullPointerException {
+
+ if (libraryName == null) {
+ throw new NullPointerException("No library name provided.");
+ }
+
+ try {
+ // Let's see if we have ReLinker available in the project. This is necessary for
+ // some projects that have huge numbers of local libraries bundled, and thus may
+ // trip a bug in Android's native library loader which ReLinker works around. (If
+ // loadLibrary works properly, ReLinker will simply use the normal Android method
+ // internally.)
+ //
+ // To use ReLinker, just add it as a dependency. For more information, see
+ // https://github.com/KeepSafe/ReLinker for ReLinker's repository.
+ //
+ Class relinkClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker");
+ Class relinkListenerClass = mContext.getClassLoader().loadClass("com.getkeepsafe.relinker.ReLinker$LoadListener");
+ Class contextClass = mContext.getClassLoader().loadClass("android.content.Context");
+ Class stringClass = mContext.getClassLoader().loadClass("java.lang.String");
+
+ // Get a 'force' instance of the ReLinker, so we can ensure libraries are reinstalled if
+ // they've changed during updates.
+ Method forceMethod = relinkClass.getDeclaredMethod("force");
+ Object relinkInstance = forceMethod.invoke(null);
+ Class relinkInstanceClass = relinkInstance.getClass();
+
+ // Actually load the library!
+ Method loadMethod = relinkInstanceClass.getDeclaredMethod("loadLibrary", contextClass, stringClass, stringClass, relinkListenerClass);
+ loadMethod.invoke(relinkInstance, mContext, libraryName, null, null);
+ }
+ catch (final Exception e) {
+ // Fall back
+ try {
+ System.loadLibrary(libraryName);
+ }
+ catch (final UnsatisfiedLinkError ule) {
+ throw ule;
+ }
+ catch (final SecurityException se) {
+ throw se;
+ }
+ }
+ }
+
protected static Context mContext;
}
diff --git a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
index c53970f..67cb3a3 100644
--- a/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
+++ b/android-project/app/src/main/java/org/libsdl/app/SDLActivity.java
@@ -154,7 +154,7 @@ public class SDLActivity extends Activity implements View.OnSystemUiVisibilityCh
// Load the .so
public void loadLibraries() {
for (String lib : getLibraries()) {
- System.loadLibrary(lib);
+ SDL.loadLibrary(lib);
}
}