@@ -21,8 +21,21 @@ extern "C"
21
21
// / for invoke result compare
22
22
static jclass gStrCls ;
23
23
24
- static std::map<jobject, jclass> objectGlobalCache;
25
- static std::map<jobject, int > referenceCount;
24
+ // / key is jobject, value is pai which contain jclass and reference count
25
+ static std::map<jobject, std::pair<jclass, int >> objectGlobalReference;
26
+
27
+ void _addGlobalObject (jobject globalObject, jclass globalClass) {
28
+ std::pair<jclass, int > objPair = std::make_pair (globalClass, 0 );
29
+ objectGlobalReference[globalObject] = objPair;
30
+ }
31
+
32
+ jclass _getGlobalClass (jobject globalObject) {
33
+ if (objectGlobalReference.find (globalObject) != objectGlobalReference.end ()) {
34
+ std::pair<jclass, int > objPair = objectGlobalReference[globalObject];
35
+ return objPair.first ;
36
+ }
37
+ return nullptr ;
38
+ }
26
39
27
40
void _detachThreadDestructor (void *arg)
28
41
{
@@ -31,6 +44,7 @@ extern "C"
31
44
detachKey = 0 ;
32
45
}
33
46
47
+ // / each thread attach once
34
48
JNIEnv *_getEnv ()
35
49
{
36
50
if (gJvm == nullptr )
@@ -77,6 +91,7 @@ extern "C"
77
91
gFindClassMethod = env->GetMethodID (classLoaderClass, " findClass" ,
78
92
" (Ljava/lang/String;)Ljava/lang/Class;" );
79
93
94
+ // / cache string class
80
95
jclass strCls = env->FindClass (" java/lang/String" );
81
96
gStrCls = static_cast <jclass>(env->NewGlobalRef (strCls));
82
97
@@ -94,6 +109,7 @@ extern "C"
94
109
jclass nativeClass = nullptr ;
95
110
nativeClass = env->FindClass (name);
96
111
jthrowable exception = env->ExceptionOccurred ();
112
+ // / class loader not found class
97
113
if (exception)
98
114
{
99
115
env->ExceptionClear ();
@@ -106,6 +122,7 @@ extern "C"
106
122
}
107
123
108
124
// / fill all arguments to jvalues
125
+ // / when argument is string the stringTypeBitmask's bit is 1
109
126
void _fillArgs (void **arguments, char **argumentTypes, jvalue *argValues, int argumentCount, uint32_t stringTypeBitmask)
110
127
{
111
128
JNIEnv *env = _getEnv ();
@@ -161,7 +178,7 @@ extern "C"
161
178
jclass cls = _findClass (env, targetClassName);
162
179
jobject newObj = _newObject (cls, arguments, argumentTypes, argumentCount, stringTypeBitmask);
163
180
jobject gObj = env->NewGlobalRef (newObj);
164
- objectGlobalCache[ gObj ] = static_cast <jclass>(env->NewGlobalRef (cls));
181
+ _addGlobalObject ( gObj , static_cast <jclass>(env->NewGlobalRef (cls) ));
165
182
166
183
env->DeleteLocalRef (newObj);
167
184
env->DeleteLocalRef (cls);
@@ -171,12 +188,17 @@ extern "C"
171
188
// / invoke native method
172
189
void *invokeNativeMethod (void *objPtr, char *methodName, void **arguments, char **dataTypes, int argumentCount, char *returnType, uint32_t stringTypeBitmask)
173
190
{
191
+ auto object = static_cast <jobject>(objPtr);
192
+ jclass cls = _getGlobalClass (object);
193
+ if (cls == nullptr )
194
+ {
195
+ DNError (" invokeNativeMethod not find class" );
196
+ return nullptr ;
197
+ }
198
+
174
199
void *nativeInvokeResult = nullptr ;
175
200
JNIEnv *env = _getEnv ();
176
201
177
- auto object = static_cast <jobject>(objPtr);
178
- jclass cls = objectGlobalCache[object];
179
-
180
202
auto *argValues = new jvalue[argumentCount];
181
203
if (argumentCount > 0 )
182
204
{
@@ -210,7 +232,7 @@ extern "C"
210
232
{
211
233
jclass objCls = env->GetObjectClass (obj);
212
234
jobject gObj = env->NewGlobalRef (obj);
213
- objectGlobalCache[ gObj ] = static_cast <jclass>(env->NewGlobalRef (objCls));
235
+ _addGlobalObject ( gObj , static_cast <jclass>(env->NewGlobalRef (objCls) ));
214
236
nativeInvokeResult = gObj ;
215
237
216
238
env->DeleteLocalRef (objCls);
@@ -257,50 +279,44 @@ extern "C"
257
279
return Dart_InitializeApiDL (data);
258
280
}
259
281
260
- // / retain native object
261
- void _retain (void *objPtr)
262
- {
263
- auto object = static_cast <jobject>(objPtr);
264
- auto it = referenceCount.find (object);
265
- int refCount = it == referenceCount.end () ? 1 : referenceCount[object] + 1 ;
266
- referenceCount[object] = refCount;
267
- }
268
-
269
- // / do release native object
270
- void _releaseTargetObject (void *objPtr)
271
- {
272
- JNIEnv *env = _getEnv ();
273
- auto object = static_cast <jobject>(objPtr);
274
- env->DeleteGlobalRef (objectGlobalCache[object]);
275
- objectGlobalCache.erase (object);
276
- env->DeleteGlobalRef (object);
277
- }
282
+ // / reference counter
283
+ void _updateObjectReference (jobject globalObject, bool isRetain) {
284
+ DNDebug (" _updateObjectReference %s" , isRetain ? " retain" : " release" );
285
+ auto it = objectGlobalReference.find (globalObject);
286
+ if (it == objectGlobalReference.end ())
287
+ {
288
+ DNError (" _updateObjectReference %s error not contain this object!!!" , isRetain ? " retain" : " release" );
289
+ return ;
290
+ }
278
291
279
- // / check reference count, if no reference exits then release
280
- void _release (void *objPtr)
281
- {
282
- auto object = static_cast <jobject>(objPtr);
283
- if (referenceCount.find (object) == referenceCount.end ())
292
+ if (isRetain)
284
293
{
285
- DNError (" release error not contain object" );
294
+ // / dart object retain this dart object
295
+ // / reference++
296
+ it->second .second += 1 ;
286
297
return ;
287
298
}
288
- int count = referenceCount[object];
289
- if (count <= 1 )
299
+
300
+ // / release reference--
301
+ it->second .second -= 1 ;
302
+
303
+ // / no dart object retained this native object
304
+ if (it->second .second <= 0 )
290
305
{
291
- referenceCount.erase (object);
292
- _releaseTargetObject (objPtr);
306
+ JNIEnv *env = _getEnv ();
307
+ env->DeleteGlobalRef (it->second .first );
308
+ objectGlobalReference.erase (it);
309
+ env->DeleteGlobalRef (globalObject);
293
310
return ;
294
311
}
295
- referenceCount[object] = count - 1 ;
296
312
}
297
313
298
314
// / release native object from cache
299
315
static void RunFinalizer (void *isolate_callback_data,
300
316
Dart_WeakPersistentHandle handle,
301
317
void *peer)
302
318
{
303
- _release ( peer);
319
+ _updateObjectReference ( static_cast <jobject>( peer), false );
304
320
}
305
321
306
322
// / retain native object
@@ -311,7 +327,7 @@ extern "C"
311
327
DNError (" Dart_IsError_DL" );
312
328
return ;
313
329
}
314
- _retain ( objPtr);
330
+ _updateObjectReference ( static_cast <jobject>( objPtr), true );
315
331
intptr_t size = 8 ;
316
332
Dart_NewWeakPersistentHandle_DL (h, objPtr, size, RunFinalizer);
317
333
}
@@ -377,7 +393,7 @@ extern "C"
377
393
{
378
394
jclass objCls = env->GetObjectClass (argument);
379
395
jobject gObj = env->NewGlobalRef (argument);
380
- objectGlobalCache[ gObj ] = static_cast <jclass>(env->NewGlobalRef (objCls));
396
+ _addGlobalObject ( gObj , static_cast <jclass>(env->NewGlobalRef (objCls) ));
381
397
arguments[i] = gObj ;
382
398
383
399
env->DeleteLocalRef (objCls);
@@ -398,7 +414,7 @@ extern "C"
398
414
399
415
const Work work = [dartObjectAddress, dataTypes, arguments, argumentCount, funName, &sem, isSemInitSuccess]() {
400
416
NativeMethodCallback methodCallback = getCallbackMethod (dartObjectAddress, funName);
401
- void *target = getDartObject (dartObjectAddress) ;
417
+ void *target = ( void *) dartObjectAddress ;
402
418
if (methodCallback != nullptr && target != nullptr )
403
419
{
404
420
methodCallback (target, funName, arguments, dataTypes, argumentCount);
0 commit comments