@@ -57,7 +57,7 @@ public void Dispose()
5757
5858 if ( m_jobject != IntPtr . Zero )
5959 {
60- AndroidJNISafe . DeleteGlobalRef ( m_jobject ) ;
60+ AndroidJNISafe . QueueDeleteGlobalRef ( m_jobject ) ;
6161 }
6262 }
6363
@@ -797,7 +797,9 @@ protected void _Set<FieldType>(IntPtr fieldID, FieldType val)
797797 AndroidJNISafe . SetCharField ( m_jobject , fieldID , ( Char ) ( object ) val ) ;
798798 }
799799 else if ( typeof ( FieldType ) == typeof ( String ) )
800+ {
800801 AndroidJNISafe . SetStringField ( m_jobject , fieldID , ( String ) ( object ) val ) ;
802+ }
801803 else if ( typeof ( FieldType ) == typeof ( AndroidJavaClass ) )
802804 {
803805 AndroidJNISafe . SetObjectField ( m_jobject , fieldID , val == null ? IntPtr . Zero : ( ( AndroidJavaClass ) ( object ) val ) . m_jclass ) ;
@@ -806,10 +808,14 @@ protected void _Set<FieldType>(IntPtr fieldID, FieldType val)
806808 {
807809 AndroidJNISafe . SetObjectField ( m_jobject , fieldID , val == null ? IntPtr . Zero : ( ( AndroidJavaObject ) ( object ) val ) . m_jobject ) ;
808810 }
811+ else if ( AndroidReflection . IsAssignableFrom ( typeof ( AndroidJavaProxy ) , typeof ( FieldType ) ) )
812+ {
813+ AndroidJNISafe . SetObjectField ( m_jobject , fieldID , val == null ? IntPtr . Zero : ( ( AndroidJavaProxy ) ( object ) val ) . GetRawProxy ( ) ) ;
814+ }
809815 else if ( AndroidReflection . IsAssignableFrom ( typeof ( System . Array ) , typeof ( FieldType ) ) )
810816 {
811817 IntPtr jobject = AndroidJNIHelper . ConvertToJNIArray ( ( Array ) ( object ) val ) ;
812- AndroidJNISafe . SetObjectField ( m_jclass , fieldID , jobject ) ;
818+ AndroidJNISafe . SetObjectField ( m_jobject , fieldID , jobject ) ;
813819 }
814820 else
815821 {
@@ -1011,6 +1017,10 @@ protected void _SetStatic<FieldType>(IntPtr fieldID, FieldType val)
10111017 {
10121018 AndroidJNISafe . SetStaticObjectField ( m_jclass , fieldID , val == null ? IntPtr . Zero : ( ( AndroidJavaObject ) ( object ) val ) . m_jobject ) ;
10131019 }
1020+ else if ( AndroidReflection . IsAssignableFrom ( typeof ( AndroidJavaProxy ) , typeof ( FieldType ) ) )
1021+ {
1022+ AndroidJNISafe . SetStaticObjectField ( m_jclass , fieldID , val == null ? IntPtr . Zero : ( ( AndroidJavaProxy ) ( object ) val ) . GetRawProxy ( ) ) ;
1023+ }
10141024 else if ( AndroidReflection . IsAssignableFrom ( typeof ( System . Array ) , typeof ( FieldType ) ) )
10151025 {
10161026 IntPtr jobject = AndroidJNIHelper . ConvertToJNIArray ( ( Array ) ( object ) val ) ;
@@ -1551,16 +1561,46 @@ public static IntPtr ConvertToJNIArray(System.Array array)
15511561 {
15521562 jniObjs [ i ] = objArray [ i ] . GetRawObject ( ) ;
15531563 IntPtr objectType = objArray [ i ] . GetRawClass ( ) ;
1554- if ( arrayType != objectType )
1564+ if ( arrayType == IntPtr . Zero )
15551565 {
1556- if ( arrayType == IntPtr . Zero )
1557- {
1558- arrayType = objectType ;
1559- }
1560- else
1561- {
1562- arrayType = fallBackType ; // java/lang/Object
1563- }
1566+ arrayType = objectType ;
1567+ }
1568+ else if ( arrayType != fallBackType && ! AndroidJNI . IsSameObject ( arrayType , objectType ) )
1569+ {
1570+ arrayType = fallBackType ; // java/lang/Object
1571+ }
1572+ }
1573+ else
1574+ {
1575+ jniObjs [ i ] = IntPtr . Zero ;
1576+ }
1577+ }
1578+ // zero sized array will call this with IntPtr.Zero type translated into java/lang/Object
1579+ IntPtr res = AndroidJNISafe . ToObjectArray ( jniObjs , arrayType ) ;
1580+ AndroidJNISafe . DeleteLocalRef ( fallBackType ) ;
1581+ return res ;
1582+ }
1583+ else if ( AndroidReflection . IsAssignableFrom ( typeof ( AndroidJavaProxy ) , type ) )
1584+ {
1585+ AndroidJavaProxy [ ] objArray = ( AndroidJavaProxy [ ] ) array ;
1586+ int arrayLen = array . GetLength ( 0 ) ;
1587+ IntPtr [ ] jniObjs = new IntPtr [ arrayLen ] ;
1588+ IntPtr fallBackType = AndroidJNISafe . FindClass ( "java/lang/Object" ) ;
1589+ IntPtr arrayType = IntPtr . Zero ;
1590+
1591+ for ( int i = 0 ; i < arrayLen ; ++ i )
1592+ {
1593+ if ( objArray [ i ] != null )
1594+ {
1595+ jniObjs [ i ] = objArray [ i ] . GetRawProxy ( ) ;
1596+ IntPtr objectType = objArray [ i ] . javaInterface . GetRawClass ( ) ;
1597+ if ( arrayType == IntPtr . Zero )
1598+ {
1599+ arrayType = objectType ;
1600+ }
1601+ else if ( arrayType != fallBackType && ! AndroidJNI . IsSameObject ( arrayType , objectType ) )
1602+ {
1603+ arrayType = fallBackType ; // java/lang/Object
15641604 }
15651605 }
15661606 else
@@ -1573,6 +1613,7 @@ public static IntPtr ConvertToJNIArray(System.Array array)
15731613 AndroidJNISafe . DeleteLocalRef ( fallBackType ) ;
15741614 return res ;
15751615 }
1616+
15761617 else
15771618 {
15781619 throw new Exception ( "JNI; Unknown array type '" + type + "'" ) ;
@@ -1832,6 +1873,13 @@ public static string GetSignature(object obj)
18321873 return "L" + javaClass . Call < System . String > ( "getName" ) + ";" ;
18331874 }
18341875 }
1876+ else if ( obj == ( object ) type && AndroidReflection . IsAssignableFrom ( typeof ( AndroidJavaProxy ) , type ) )
1877+ {
1878+ // underlying Java class/interface can be found only for an actual object of 'type',
1879+ // and we cannot use Activator.CreateInstance(type) here because default constructor might not exist for 'type',
1880+ // returning empty string, this way ReflectionHelper finds field by name only.
1881+ return "" ;
1882+ }
18351883 else if ( type . Equals ( typeof ( AndroidJavaRunnable ) ) )
18361884 {
18371885 return "Ljava/lang/Runnable;" ;
@@ -1861,7 +1909,7 @@ public static string GetSignature(object obj)
18611909 System . Text . StringBuilder sb = new System . Text . StringBuilder ( ) ;
18621910 sb . Append ( '[' ) ;
18631911 sb . Append ( GetSignature ( type . GetElementType ( ) ) ) ;
1864- return sb . ToString ( ) ;
1912+ return sb . Length > 1 ? sb . ToString ( ) : "" ;
18651913 }
18661914 else
18671915 {
0 commit comments