// ReSharper disable once CheckNamespace | |
namespace JsLab.JsApi | |
{ | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
public class JsApiBase : Java.Lang.Object | |
{ | |
private readonly string _jsBindName; | |
[AttributeUsage(AttributeTargets.Method)] | |
protected sealed class JsApiAttribute : Attribute | |
{ | |
} | |
// ReSharper disable UnusedAutoPropertyAccessor.Local | |
// ReSharper disable once ClassNeverInstantiated.Local | |
private sealed class InvokeRequestModel | |
{ | |
public string MethodName { get; set; } | |
public object[] Arguments { get; set; } | |
} | |
private sealed class InvokeResponseModel | |
{ | |
public bool Success { get; set; } | |
public Exception Exception { get; set; } | |
public object Result { get; set; } | |
} | |
// ReSharper restore UnusedAutoPropertyAccessor.Local | |
protected JsApiBase(string jsBindName) | |
{ | |
_jsBindName = jsBindName; | |
} | |
public string GenerateFunctionStub() | |
{ | |
var methods = GetType().GetMethods() | |
.Where(p => p.IsDefined(typeof(JsApiAttribute), true)) | |
.ToArray(); | |
var list = new List<string>(methods.Length); | |
// ReSharper disable once LoopCanBeConvertedToQuery | |
foreach (var method in methods) | |
{ | |
var argList = string.Join(",", method.GetParameters().Select((p, i) => "p" + i + "_" + p.Name)); | |
var line1 = | |
$"{method.Name}:function({argList})" + "{" + | |
"var arg={" + $"MethodName:'{method.Name}',Arguments:[{argList}]" + "};" + | |
"var argson=JSON.stringify(arg);" + | |
$"return JSON.parse({_jsBindName}.InvokeInterface(argson));" + | |
"}"; | |
//TODO: Async version with callback | |
list.Add(line1); | |
} | |
return "{" + string.Join(",", list) + "}"; | |
} | |
[Export] | |
#if !Android22 | |
[JavascriptInterface] | |
#endif | |
// ReSharper disable once UnusedMember.Global | |
public string InvokeInterface(string json) | |
{ | |
var r = new InvokeResponseModel(); | |
try | |
{ | |
#if Android22 | |
var im = fastJSON.JSON.ToObject<InvokeRequestModel>(json); | |
#else | |
var im = Newtonsoft.Json.JsonConvert.DeserializeObject<InvokeRequestModel>(json); | |
#endif | |
r.Result = GetType().InvokeMember(im.MethodName, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, this, im.Arguments); | |
r.Success = true; | |
} | |
catch (Exception ex) | |
{ | |
r.Success = false; | |
r.Exception = ex; | |
} | |
#if Android22 | |
return fastJSON.JSON.ToJSON(r); | |
#else | |
return Newtonsoft.Json.JsonConvert.SerializeObject(r); | |
#endif | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment