Mono for Androidでjava/util/concurrent/CountDownLatchを使えるようにしてみた
モーダルダイアログを実現したくて見つけたJavaのコードサンプルで使っているCountDownLatch。
Mono for Android v1.9ではまだ実装されていなかったので自前で実装してみた。
using System; using Android; using Android.Runtime; namespace Utilty { public class CountDownLatch : Java.Lang.Object, IJavaObject { internal static IntPtr class_ref = JNIEnv.FindClass ("java/util/concurrent/CountDownLatch"); private static Delegate cb_await; private static Delegate cb_coutnDown; private static IntPtr id_ctor; private static IntPtr id_await; private static IntPtr id_coutnDown; [Register(".ctro","(I)V", "")] public CountDownLatch (int count) : base(IntPtr.Zero) { if (base.Handle == IntPtr.Zero) { if (base.GetType () != typeof(CountDownLatch)) { IntPtr kls = JNIEnv.FindClass (base.GetType ()); IntPtr jmethod = JNIEnv.GetMethodID (kls, "<init>", "(I)V"); JValue[] parms = new JValue[] {new JValue(count)}; base.SetHandle (JNIEnv.NewObject (kls, jmethod, parms), true); JNIEnv.DeleteGlobalRef (kls); } else { if (id_ctor == IntPtr.Zero) { id_ctor = JNIEnv.GetMethodID (class_ref, "<init>", "(I)V"); } JValue[] parms = new JValue[] {new JValue(count)}; base.SetHandle (JNIEnv.NewObject (class_ref, id_ctor, parms), true); } } } public CountDownLatch (IntPtr doNotUse) : base (doNotUse) { } [Register("await", "()V", "GetAwaitHandler")] public void Await () { if (id_await == IntPtr.Zero) { id_await = JNIEnv.GetMethodID (class_ref, "await", "()V"); } if (base.GetType () == this.ThresholdType) { JNIEnv.CallVoidMethod (base.Handle, id_await); } else { JNIEnv.CallNonvirtualVoidMethod (base.Handle, this.ThresholdClass, id_await); } } private static Delegate GetAwaitHandler () { if (cb_await == null) cb_await = JNINativeWrapper.CreateDelegate (new Action<IntPtr, IntPtr> (CountDownLatch.n_Await)); return cb_await; } private static void n_Await (IntPtr jnienv, IntPtr native__this) { Java.Lang.Object.GetObject<CountDownLatch> (native__this, false).Await (); } [Register("countDown", "()V", "GetCountDownHandler")] public void CountDown () { if (id_coutnDown == IntPtr.Zero) { id_coutnDown = JNIEnv.GetMethodID (class_ref, "countDown", "()V"); } if (base.GetType () == this.ThresholdType) { JNIEnv.CallVoidMethod (base.Handle, id_coutnDown); } else { JNIEnv.CallNonvirtualVoidMethod (base.Handle, this.ThresholdClass, id_coutnDown); } } private static Delegate GetCountDownHandler () { if (cb_coutnDown == null) cb_coutnDown = JNINativeWrapper.CreateDelegate (new Action<IntPtr, IntPtr> (CountDownLatch.n_CountDown)); return cb_coutnDown; } private static void n_CountDown (IntPtr jnienv, IntPtr native__this) { Java.Lang.Object.GetObject<CountDownLatch> (native__this, false).CountDown (); } protected override IntPtr ThresholdClass { get { return class_ref; } } protected override Type ThresholdType { get { return typeof(CountDownLatch); } } } }
- namespaceをJava.Util.Concurrentとするとビルドしてパッケージ化するときにエラーがおきるので断念。
- class定義に[Register("java/util/concurrent/CountDownLatch")]をつけるとこれまたビルドしてパッケージ化するときにエラーがおきるのでつけなかった。
ご利用はくれぐれも自己責任で。