コード例 #1
0
 protected override void Dispose(bool disposing)
 {
     if (this.class_ref != IntPtr.Zero)
     {
         JNIEnv.DeleteGlobalRef(this.class_ref);
     }
     this.class_ref = IntPtr.Zero;
     base.Dispose(disposing);
 }
コード例 #2
0
        public void ConversionsAndThreadsAndInstanceMappingsOhMy()
        {
            IntPtr lrefJliArray = JNIEnv.NewObjectArray <int> (new[] { 1 });
            IntPtr grefJliArray = JNIEnv.NewGlobalRef(lrefJliArray);

            JNIEnv.DeleteLocalRef(lrefJliArray);

            Java.Lang.Object[] jarray = (Java.Lang.Object[])
                                        JNIEnv.GetArray(grefJliArray, JniHandleOwnership.DoNotTransfer, typeof(Java.Lang.Object));

            Exception ignore_t1 = null;
            Exception ignore_t2 = null;

            var t1 = new Thread(() => {
                int[] output_array1 = new int[1];
                for (int i = 0; i < 2000; ++i)
                {
                    Console.WriteLine("# t1 iter: {0}", i);
                    try {
                        JNIEnv.CopyObjectArray(grefJliArray, output_array1);
                    } catch (Exception e) {
                        ignore_t1 = e;
                        break;
                    }
                }
            });
            var t2 = new Thread(() => {
                for (int i = 0; i < 2000; ++i)
                {
                    Console.WriteLine("# t2 iter: {0}", i);
                    try {
                        JNIEnv.GetArray <int>(jarray);
                    } catch (Exception e) {
                        ignore_t2 = e;
                        break;
                    }
                }
            });

            t1.Start();
            t2.Start();
            t1.Join();
            t2.Join();

            for (int i = 0; i < jarray.Length; ++i)
            {
                jarray [i].Dispose();
                jarray [i] = null;
            }

            JNIEnv.DeleteGlobalRef(grefJliArray);

            Assert.IsNull(ignore_t1, string.Format("No exception should be thrown [t1]! Got: {0}", ignore_t1));
            Assert.IsNull(ignore_t2, string.Format("No exception should be thrown [t2]! Got: {0}", ignore_t2));
        }
コード例 #3
0
 private static void DeleteRef(IntPtr handle, JniHandleOwnership transfer)
 {
     if (transfer == JniHandleOwnership.TransferLocalRef)
     {
         JNIEnv.DeleteLocalRef(handle);
     }
     else if (transfer == JniHandleOwnership.TransferGlobalRef)
     {
         JNIEnv.DeleteGlobalRef(handle);
     }
 }
コード例 #4
0
        internal static void StaticDestroy()
        {
            JNIEnv.DeleteGlobalRef(blankJavaDataBuffer);

            // release created audio tracks and java buffers.
            foreach (var trackInfo in audioTrackPool)
            {
                trackInfo.Dispose();
            }

            audioTrackPool.Clear();
        }
コード例 #5
0
        /// <summary>
        /// Equivalent of Display.GetRealSize (introduced in API 17), except this version works as far back as
        /// API 14.
        /// </summary>
        static AG.Point GetRealSize(Display display)
        {
            var realSize = new AG.Point();

            var klassDisplay  = JNIEnv.FindClass("android/view/Display");
            var displayHandle = JNIEnv.ToJniHandle(display);

            try {
                // If the OS is running Jelly Bean (API 17), we can call Display.GetRealSize via JNI
                if ((int)Build.VERSION.SdkInt >= 17 /*BuildVersionCodes.JellyBeanMr1*/)
                {
                    var getRealSizeMethodId = JNIEnv.GetMethodID(
                        klassDisplay,
                        "getRealSize",
                        "(Landroid/graphics/Point;)V");

                    JNIEnv.CallVoidMethod(
                        displayHandle, getRealSizeMethodId, new JValue(realSize));
                }
                else if (Build.VERSION.SdkInt >= BuildVersionCodes.IceCreamSandwich)
                {
                    // Otherwise, this OS is older. As long as it's API 14-16, these private
                    // methods can get the real size.
                    var rawHeightMethodId = JNIEnv.GetMethodID(
                        klassDisplay,
                        "getRawHeight",
                        "()I");
                    var rawWidthMethodId = JNIEnv.GetMethodID(
                        klassDisplay,
                        "getRawWidth",
                        "()I");

                    var height = JNIEnv.CallIntMethod(displayHandle, rawHeightMethodId);
                    var width  = JNIEnv.CallIntMethod(displayHandle, rawWidthMethodId);

                    realSize = new AG.Point(width, height);
                }
                else
                {
                    // Just return something for API < 14
                    display.GetSize(realSize);
                }
            } finally {
                JNIEnv.DeleteGlobalRef(klassDisplay);
            }

            return(realSize);
        }
コード例 #6
0
        public void MoarThreadingTests()
        {
            IntPtr lrefJliArray = JNIEnv.NewObjectArray <int> (new[] { 1 });
            IntPtr grefJliArray = JNIEnv.NewGlobalRef(lrefJliArray);

            JNIEnv.DeleteLocalRef(lrefJliArray);

            Exception ignore_t1 = null;
            Exception ignore_t2 = null;

            var t1 = new Thread(() => {
                int[] output_array1 = new int[1];
                for (int i = 0; i < 2000; ++i)
                {
                    Console.WriteLine("# t1 iter: {0}", i);
                    try {
                        JNIEnv.CopyObjectArray(grefJliArray, output_array1);
                    } catch (Exception e) {
                        ignore_t1 = e;
                        break;
                    }
                }
            });
            var t2 = new Thread(() => {
                for (int i = 0; i < 2000; ++i)
                {
                    Console.WriteLine("# t2 iter: {0}", i);
                    try {
                        JNIEnv.GetObjectArray(grefJliArray, new[] { typeof(int) });
                    } catch (Exception e) {
                        ignore_t2 = e;
                        break;
                    }
                }
            });

            t1.Start();
            t2.Start();
            t1.Join();
            t2.Join();

            JNIEnv.DeleteGlobalRef(grefJliArray);

            Assert.IsNull(ignore_t1, string.Format("No exception should be thrown [t1]! Got: {0}", ignore_t1));
            Assert.IsNull(ignore_t2, string.Format("No exception should be thrown [t2]! Got: {0}", ignore_t2));
        }
コード例 #7
0
        public ActivityTrackerWrapper()
        {
            var monodroidDll = Assembly.GetAssembly(typeof(Application));

            trackerType = monodroidDll.GetType("Android.App.ActivityTracker");
            tracker     = Activator.CreateInstance(trackerType);

            // We cannot use the C# APIs to perform registration, because if there is a custom Application
            // subclass used for the app, accessing it at this time generates a MCW for the underlying Java
            // class, ultimately causing an infinite loop and stack overflow, since this is being called
            // during RegisterJniNatives.
            //
            // So, we use JNI to make sure the calls happen in Java land. This JNI code is equivalent to:
            //
            //    ((Application)Application.Context).RegisterActivityLifecycleCallbacks (
            //        (Application.IActivityLifecycleCallbacks) tracker);

            var trackerJValue =
                new JValue(JNIEnv.ToJniHandle((Application.IActivityLifecycleCallbacks)tracker));

            var klassMonoApp    = JNIEnv.FindClass("mono/MonoPackageManager");
            var klassAndroidApp = JNIEnv.FindClass("android/app/Application");

            try {
                var contextFieldId = JNIEnv.GetStaticFieldID(
                    klassMonoApp, "Context", "Landroid/content/Context;");
                var contextLref = JNIEnv.GetStaticObjectField(klassMonoApp, contextFieldId);

                var registerMethodId = JNIEnv.GetMethodID(
                    klassAndroidApp,
                    "registerActivityLifecycleCallbacks",
                    "(Landroid/app/Application$ActivityLifecycleCallbacks;)V");

                JNIEnv.CallNonvirtualVoidMethod(
                    contextLref, klassAndroidApp, registerMethodId, trackerJValue);
            } finally {
                JNIEnv.DeleteGlobalRef(klassMonoApp);
                JNIEnv.DeleteGlobalRef(klassAndroidApp);
            }

            // Uncomment if we need access to ActivityStarted event:
            //var activityStartedEvent = trackerType.GetEvent ("ActivityStarted");
            //Action<object, EventArgs> handler = OnActivityStarted;
            //var d = Delegate.CreateDelegate (activityStartedEvent.EventHandlerType, this, "OnActivityStarted");
            //activityStartedEvent.AddEventHandler (tracker, d);
        }
コード例 #8
0
 protected override bool ReleaseHandle()
 {
     try
     {
         if (handle != IntPtr.Zero)
         {
             JNIEnv env = JNIEnv.GetEnvNoThrow(javaVM);
             if (env == null)
             {
                 return(false);
             }
             env.DeleteGlobalRef(this);
         }
         return(true);
     }
     finally
     {
         handle = IntPtr.Zero;
     }
 }
コード例 #9
0
        protected virtual void Dispose(bool disposing)
        {
            // free native resources if there are any.
            foreach (KeyValuePair <string, IntPtr> javaClass in usedClasses)
            {
                if (javaClass.Value != IntPtr.Zero)
                {
                    env.DeleteGlobalRef(javaClass.Value);
                    usedClasses[javaClass.Key] = IntPtr.Zero;
                }
            }
            for (int i = 0, end = usedObject.Count; i < end; ++i)
            {
                IntPtr javaObject = usedObject[i];
                if (javaObject != IntPtr.Zero)
                {
                    env.DeleteLocalRef(javaObject);
                    usedObject[i] = IntPtr.Zero;
                }
            }

            if (disposing)
            {
                // free managed resources
                if (jvm != null)
                {
                    jvm.Dispose();
                    jvm = null;
                }

                if (env != null)
                {
                    env.Dispose();
                    env = null;
                }
            }
        }
コード例 #10
0
        internal static void Dispose(IJavaPeerable instance, ref IntPtr handle, IntPtr key_handle, JObjectRefType handle_type)
        {
            if (handle == IntPtr.Zero)
            {
                return;
            }

            if (Logger.LogGlobalRef)
            {
                JNIEnv._monodroid_gref_log(
                    string.Format("Disposing handle 0x{0}\n", handle.ToString("x")));
            }

            JNIEnv.AndroidValueManager.RemovePeer(instance, key_handle);

            switch (handle_type)
            {
            case JObjectRefType.Global:
                lock (instance) {
                    JNIEnv.DeleteGlobalRef(handle);
                    handle = IntPtr.Zero;
                }
                break;

            case JObjectRefType.WeakGlobal:
                lock (instance) {
                    JNIEnv.DeleteWeakGlobalRef(handle);
                    handle = IntPtr.Zero;
                }
                break;

            default:
                throw new InvalidOperationException("Trying to dispose handle of type '" +
                                                    handle_type + "' which is not supported.");
            }
        }
コード例 #11
0
        public void InvokeOverriddenAbsListView_AdapterProperty()
        {
            IntPtr grefAbsListView_class = JNIEnv.FindClass("android/widget/AbsListView");
            // AbsListView doesn't override getAdapter(), and thus it inherits the
            // AdapterView method; no need to check its behavior.
            IntPtr AbsListView_setAdapter = IntPtr.Zero;

            if ((int)Build.VERSION.SdkInt >= 11)
            {
                AbsListView_setAdapter = JNIEnv.GetMethodID(grefAbsListView_class, "setAdapter", "(Landroid/widget/ListAdapter;)V");
            }

            IntPtr grefAdapterView_class  = JNIEnv.FindClass("android/widget/AdapterView");
            IntPtr AdapterView_getAdapter = JNIEnv.GetMethodID(grefAdapterView_class, "getAdapter", "()Landroid/widget/Adapter;");
            IntPtr AdapterView_setAdapter = JNIEnv.GetMethodID(grefAdapterView_class, "setAdapter", "(Landroid/widget/Adapter;)V");

            JNIEnv.DeleteGlobalRef(grefAbsListView_class);
            JNIEnv.DeleteGlobalRef(grefAdapterView_class);

            using (var adapter = new CanOverrideAbsListView_Adapter(Application.Context)) {
                var a = Java.Lang.Object.GetObject <IListAdapter>(
                    JNIEnv.CallObjectMethod(adapter.Handle, AdapterView_getAdapter), JniHandleOwnership.TransferLocalRef);
                Assert.AreSame(adapter.AdapterValue, a);

                if (AbsListView_setAdapter != IntPtr.Zero)
                {
                    adapter.AdapterSetterInvoked = false;
                    JNIEnv.CallVoidMethod(adapter.Handle, AbsListView_setAdapter, new JValue(IntPtr.Zero));
                    Assert.IsTrue(adapter.AdapterSetterInvoked);
                }

                adapter.AdapterSetterInvoked = false;
                JNIEnv.CallVoidMethod(adapter.Handle, AdapterView_setAdapter, new JValue(IntPtr.Zero));
                Assert.IsTrue(adapter.AdapterSetterInvoked);
            }
        }
コード例 #12
0
 public void Dispose()
 {
     Track.Release();
     Track.Dispose();
     JNIEnv.DeleteGlobalRef(javaDataBuffer);
 }