
/* gradle.properties */ deployAarPath=../Assets/Plugins/Android /* build.gradle */ task clearLibraryAar(type: Delete) { delete fileTree("${deployAarPath}") { include 'my-plugin-**.aar' } } task deployLibraryAar(type: Copy, dependsOn: clearLibraryAar) { from('build/outputs/aar/') into("${deployAarPath}") include('my-plugin-release.aar') rename('my-plugin-release.aar', 'my-plugin-' + android.defaultConfig.versionName + '.aar') doLast { fileTree("${deployAarPath}"){ include { it.file.name ==~ "^my-plugin-([0-9.]+).aar.meta\$" }}.each { f -> f.renameTo(file("${deployAarPath}/my-plugin-" + android.defaultConfig.versionName + ".aar.meta")) } } } tasks.whenTaskAdded { task -> if (task.name == 'bundleRelease') { task.finalizedBy 'deployLibraryAar' } }  /* MessageHandler.cs */ using UnityEngine; public static class MessageHandler { //     Java Interface,    private class JavaMessageHandler : AndroidJavaProxy { private JavaMessageHandler() : base("com.myplugin.JavaMessageHandler") {} public void onMessage(string message, string data) { //      MessageRouter.RouteMessage(message, data); } } //        Unity Engine   [RuntimeInitializeOnLoadMethod] private static void Initialize() { #if !UNITY_EDITOR //   JavaMessageHandler    new AndroidJavaClass("com.myplugin.UnityBridge").CallStatic("registerMessageHandler", new JavaMessageHandler()); #endif } }  /* com.myplugin.JavaMessageHandler */ package com.myplugin; //  ,    public interface JavaMessageHandler { void onMessage(String message, String data); } /* com.myplugin.UnityBridge */ package com.myplugin; import android.os.Handler; public final class UnityBridge { //    C#   private static JavaMessageHandler javaMessageHandler; //    Unity  private static Handler unityMainThreadHandler; public static void registerMessageHandler(JavaMessageHandler handler) { javaMessageHandler = handler; if(unityMainThreadHandler == null) { //         Unity, //         , //    Handler unityMainThreadHandler = new Handler(); } } //     Unity ,    public static void runOnUnityThread(Runnable runnable) { if(unityMainThreadHandler != null && runnable != null) { unityMainThreadHandler.post(runnable); } } //  - ,      Unity public static void SendMessageToUnity(final String message, final String data) { runOnUnityThread(new Runnable() { @Override public void run() { if(javaMessageHandler != null) { javaMessageHandler.onMessage(message, data); } } }); } }  /* MonoJavaCallback.cs */ using System; using UnityEngine; public static class MonoJavaCallback { //  ,    Java //      Action private class AndroidCallbackHandler<T> : AndroidJavaProxy { private readonly Action<T> _resultHandler; public AndroidCallbackHandler(Action<T> resultHandler) : base("com.myplugin.CallbackJsonHandler") { _resultHandler = resultHandler; } //     JSONObject //       , //        public void onHandleResult(AndroidJavaObject result) { if(_resultHandler != null) { //  json    var resultJson = result == null ? null : result.Call<string>("toString"); //      C#  _resultHandler.Invoke(Newtonsoft.Json.JsonConvert.DeserializeObject<T>(resultJson)); } } } //         C#  public static AndroidJavaProxy ActionToJavaObject<T>(Action<T> action) { return new AndroidCallbackHandler<T>(action); } }  /* CallbackJsonHandler.java */ package com.myplugin; import org.json.JSONObject; public interface CallbackJsonHandler { void onHandleResult(JSONObject result); }  /* Example.cs */ public class Example { public class ResultData { public bool Success; public string ValueStr; public int ValueInt; } public static void GetSomeData(string key, Action<ResultData> completionHandler) { new AndroidJavaClass("com.myplugin.Example").CallStatic("getSomeDataWithCallback", key, MonoJavaCallback.ActionToJavaObject<ResultData>(completionHandler)); } } /* Example.java */ package com.myplugin; import org.json.JSONException; import org.json.JSONObject; public class Example { public static void getSomeDataWithCallback(String key, CallbackJsonHandler callback) { //     -   background  new Thread(new Runnable() { @Override public void run() { doSomeStuffWithKey(key); //     Unity  UnityBridge.runOnUnityThread(new Runnable() { @Override public void run() { try { callback.OnHandleResult(new JSONObject().put("Success", true).put("ValueStr", someResult).put( "ValueInt", 42)); } catch (JSONException e) { e.printStackTrace(); } } }); }); } }  public class InitProvider extends ContentProvider { @Override public boolean onCreate() { Context context = getContext(); if (context != null && context instanceof Application) { // ActivityLifecycleListener —    Application.ActivityLifecycleCallbacks ((Application) context).registerActivityLifecycleCallbacks(new ActivityLifecycleListener(context)); } return false; } //     }  <provider android:name=".InitProvider" android:authorities="${applicationId}.InitProvider" android:enabled="true" android:exported="false" android:initOrder="200" />  private boolean isLaunchActivity(Activity activity) { Intent launchIntent = activity.getPackageManager().getLaunchIntentForPackage(activity.getPackageName()); return launchIntent != null && launchIntent.getComponent() != null && activity.getClass().getName().equals(launchIntent.getComponent().getClassName()); }  <activity android:name=".ProxyActivity" android:excludeFromRecents="true" android:exported="false" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:theme="@android:style/Theme.Translucent.NoTitleBar" />  <dependencies> <iosPods> </iosPods> <androidPackages> <androidPackage spec="com.android.support:appcompat-v7:23+"> <androidSdkPackageIds> <androidSdkPackageId>extra-google-m2repository</androidSdkPackageId> <androidSdkPackageId>extra-android-m2repository</androidSdkPackageId> </androidSdkPackageIds> </androidPackage> <androidPackage spec="com.android.support:cardview-v7:23+"> <androidSdkPackageIds> <androidSdkPackageId>extra-google-m2repository</androidSdkPackageId> <androidSdkPackageId>extra-android-m2repository</androidSdkPackageId> </androidSdkPackageIds> </androidPackage> <androidPackage spec="com.android.support:design:23+"> <androidSdkPackageIds> <androidSdkPackageId>extra-google-m2repository</androidSdkPackageId> <androidSdkPackageId>extra-android-m2repository</androidSdkPackageId> </androidSdkPackageIds> </androidPackage> <androidPackage spec="com.android.support:recyclerview-v7:23+"> <androidSdkPackageIds> <androidSdkPackageId>extra-google-m2repository</androidSdkPackageId> <androidSdkPackageId>extra-android-m2repository</androidSdkPackageId> </androidSdkPackageIds> </androidPackage> </androidPackages> </dependencies> Source: https://habr.com/ru/post/353444/
All Articles