Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
// 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
You can’t perform that action at this time.