Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
sxychenjing
engine
提交
acfbced1
E
engine
项目概览
sxychenjing
/
engine
与 Fork 源项目一致
从无法访问的项目Fork
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
E
engine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
acfbced1
编写于
1月 12, 2016
作者:
J
Jason Simmons
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
JNI bridge support for constructors, arrays, and strings
上级
35863afd
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
321 addition
and
11 deletion
+321
-11
sky/engine/bindings/jni/dart_jni.cc
sky/engine/bindings/jni/dart_jni.cc
+235
-8
sky/engine/bindings/jni/dart_jni.h
sky/engine/bindings/jni/dart_jni.h
+62
-3
sky/engine/bindings/jni/jni.dart
sky/engine/bindings/jni/jni.dart
+24
-0
未找到文件。
sky/engine/bindings/jni/dart_jni.cc
浏览文件 @
acfbced1
...
...
@@ -9,6 +9,7 @@
#include "base/logging.h"
#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "base/strings/string_util.h"
#include "sky/engine/tonic/dart_args.h"
#include "sky/engine/tonic/dart_binding_macros.h"
#include "sky/engine/tonic/dart_converter.h"
...
...
@@ -65,14 +66,22 @@ bool CheckDartException(Dart_Handle result, Dart_Handle* exception) {
DART_NATIVE_CALLBACK_STATIC
(
JniClass
,
FromName
);
#define FOR_EACH_BINDING(V) \
V(JniArray, GetLength) \
V(JniClass, CallStaticLongMethod) \
V(JniClass, NewObject) \
V(JniClass, GetFieldId) \
V(JniClass, GetMethodId) \
V(JniClass, GetStaticFieldId) \
V(JniClass, GetStaticIntField) \
V(JniClass, GetStaticMethodId) \
V(JniClass, GetStaticObjectField) \
V(JniObject, GetIntField)
V(JniObject, CallBooleanMethod) \
V(JniObject, CallIntMethod) \
V(JniObject, CallObjectMethod) \
V(JniObject, GetIntField) \
V(JniObjectArray, GetArrayElement) \
V(JniObjectArray, SetArrayElement) \
V(JniString, GetText)
FOR_EACH_BINDING
(
DART_NATIVE_CALLBACK
)
...
...
@@ -94,7 +103,8 @@ void DartJni::InitForIsolate() {
}
ScopedJavaGlobalRef
<
jobject
>
DartJni
::
class_loader_
;
jmethodID
DartJni
::
load_class_method_id_
;
jmethodID
DartJni
::
class_loader_load_class_method_id_
;
jmethodID
DartJni
::
class_get_name_method_id_
;
bool
DartJni
::
InitJni
()
{
JNIEnv
*
env
=
base
::
android
::
AttachCurrentThread
();
...
...
@@ -105,24 +115,44 @@ bool DartJni::InitJni() {
env
,
env
->
FindClass
(
"java/lang/ClassLoader"
));
CHECK
(
!
base
::
android
::
ClearException
(
env
));
load_class_method_id_
=
env
->
GetMethodID
(
class_loader_
load_class_method_id_
=
env
->
GetMethodID
(
class_loader_clazz
.
obj
(),
"loadClass"
,
"(Ljava/lang/String;)Ljava/lang/Class;"
);
CHECK
(
!
base
::
android
::
ClearException
(
env
));
ScopedJavaLocalRef
<
jclass
>
class_clazz
(
env
,
env
->
FindClass
(
"java/lang/Class"
));
CHECK
(
!
base
::
android
::
ClearException
(
env
));
class_get_name_method_id_
=
env
->
GetMethodID
(
class_clazz
.
obj
(),
"getName"
,
"()Ljava/lang/String;"
);
CHECK
(
!
base
::
android
::
ClearException
(
env
));
return
true
;
}
ScopedJavaLocalRef
<
jclass
>
DartJni
::
GetClass
(
JNIEnv
*
env
,
const
char
*
name
)
{
jobject
clazz
=
env
->
CallObjectMethod
(
class_loader_
.
obj
(),
load_class_method_id_
,
class_loader_
load_class_method_id_
,
base
::
android
::
ConvertUTF8ToJavaString
(
env
,
name
).
obj
());
return
ScopedJavaLocalRef
<
jclass
>
(
env
,
static_cast
<
jclass
>
(
clazz
));
}
std
::
string
DartJni
::
GetObjectClassName
(
JNIEnv
*
env
,
jobject
obj
)
{
jclass
clazz
=
env
->
GetObjectClass
(
obj
);
DCHECK
(
clazz
);
jstring
name
=
static_cast
<
jstring
>
(
env
->
CallObjectMethod
(
clazz
,
class_get_name_method_id_
));
DCHECK
(
name
);
return
base
::
android
::
ConvertJavaStringToUTF8
(
env
,
name
);
}
class
JniMethodArgs
{
public:
void
Convert
(
JNIEnv
*
env
,
...
...
@@ -286,7 +316,27 @@ PassRefPtr<JniObject> JniClass::GetStaticObjectField(jfieldID fieldId) {
jobject
obj
=
env
->
GetStaticObjectField
(
clazz_
.
obj
(),
fieldId
);
if
(
CheckJniException
(
env
,
&
exception
))
goto
fail
;
return
JniObject
::
create
(
env
,
obj
);
return
JniObject
::
Create
(
env
,
obj
);
}
fail:
Dart_ThrowException
(
exception
);
ASSERT_NOT_REACHED
();
}
PassRefPtr
<
JniObject
>
JniClass
::
NewObject
(
jmethodID
methodId
,
const
Vector
<
Dart_Handle
>&
args
)
{
Dart_Handle
exception
=
nullptr
;
{
ENTER_JNI
();
JniMethodArgs
java_args
;
java_args
.
Convert
(
env
,
args
,
&
exception
);
if
(
exception
)
goto
fail
;
jobject
obj
=
env
->
NewObjectA
(
clazz_
.
obj
(),
methodId
,
java_args
.
jvalues
());
if
(
CheckJniException
(
env
,
&
exception
))
goto
fail
;
return
JniObject
::
Create
(
env
,
obj
);
}
fail:
Dart_ThrowException
(
exception
);
...
...
@@ -323,8 +373,20 @@ JniObject::JniObject(JNIEnv* env, jobject object)
JniObject
::~
JniObject
()
{
}
PassRefPtr
<
JniObject
>
JniObject
::
create
(
JNIEnv
*
env
,
jobject
object
)
{
return
adoptRef
(
new
JniObject
(
env
,
object
));
PassRefPtr
<
JniObject
>
JniObject
::
Create
(
JNIEnv
*
env
,
jobject
object
)
{
std
::
string
class_name
=
DartJni
::
GetObjectClassName
(
env
,
object
);
JniObject
*
result
;
if
(
class_name
==
"java.lang.String"
)
{
result
=
new
JniString
(
env
,
static_cast
<
jstring
>
(
object
));
}
else
if
(
base
::
StartsWith
(
class_name
,
"[L"
,
base
::
CompareCase
::
SENSITIVE
))
{
result
=
new
JniObjectArray
(
env
,
static_cast
<
jobjectArray
>
(
object
));
}
else
{
result
=
new
JniObject
(
env
,
object
);
}
return
adoptRef
(
result
);
}
jint
JniObject
::
GetIntField
(
jfieldID
fieldId
)
{
...
...
@@ -332,7 +394,7 @@ jint JniObject::GetIntField(jfieldID fieldId) {
{
ENTER_JNI
();
jint
result
=
env
->
GetIntField
(
object_
.
obj
(),
fieldId
);
jint
result
=
env
->
GetIntField
(
java_object
(),
fieldId
);
if
(
CheckJniException
(
env
,
&
exception
))
goto
fail
;
return
result
;
...
...
@@ -342,4 +404,169 @@ fail:
ASSERT_NOT_REACHED
();
}
PassRefPtr
<
JniObject
>
JniObject
::
CallObjectMethod
(
jmethodID
methodId
,
const
Vector
<
Dart_Handle
>&
args
)
{
Dart_Handle
exception
=
nullptr
;
{
ENTER_JNI
();
JniMethodArgs
java_args
;
java_args
.
Convert
(
env
,
args
,
&
exception
);
if
(
exception
)
goto
fail
;
jobject
result
=
env
->
CallObjectMethodA
(
java_object
(),
methodId
,
java_args
.
jvalues
());
if
(
CheckJniException
(
env
,
&
exception
))
goto
fail
;
return
JniObject
::
Create
(
env
,
result
);
}
fail:
Dart_ThrowException
(
exception
);
ASSERT_NOT_REACHED
();
}
bool
JniObject
::
CallBooleanMethod
(
jmethodID
methodId
,
const
Vector
<
Dart_Handle
>&
args
)
{
Dart_Handle
exception
=
nullptr
;
{
ENTER_JNI
();
JniMethodArgs
java_args
;
java_args
.
Convert
(
env
,
args
,
&
exception
);
if
(
exception
)
goto
fail
;
jboolean
result
=
env
->
CallBooleanMethodA
(
java_object
(),
methodId
,
java_args
.
jvalues
());
if
(
CheckJniException
(
env
,
&
exception
))
goto
fail
;
return
result
==
JNI_TRUE
;
}
fail:
Dart_ThrowException
(
exception
);
ASSERT_NOT_REACHED
();
}
jint
JniObject
::
CallIntMethod
(
jmethodID
methodId
,
const
Vector
<
Dart_Handle
>&
args
)
{
Dart_Handle
exception
=
nullptr
;
{
ENTER_JNI
();
JniMethodArgs
java_args
;
java_args
.
Convert
(
env
,
args
,
&
exception
);
if
(
exception
)
goto
fail
;
jint
result
=
env
->
CallIntMethodA
(
java_object
(),
methodId
,
java_args
.
jvalues
());
if
(
CheckJniException
(
env
,
&
exception
))
goto
fail
;
return
result
;
}
fail:
Dart_ThrowException
(
exception
);
ASSERT_NOT_REACHED
();
}
IMPLEMENT_WRAPPERTYPEINFO
(
jni
,
JniString
);
JniString
::
JniString
(
JNIEnv
*
env
,
jstring
object
)
:
JniObject
(
env
,
object
)
{}
JniString
::~
JniString
()
{
}
jstring
JniString
::
java_string
()
{
return
static_cast
<
jstring
>
(
java_object
());
}
String
JniString
::
GetText
()
{
Dart_Handle
exception
=
nullptr
;
{
ENTER_JNI
();
jsize
length
=
env
->
GetStringLength
(
java_string
());
if
(
CheckJniException
(
env
,
&
exception
))
goto
fail
;
const
jchar
*
chars
=
env
->
GetStringChars
(
java_string
(),
NULL
);
if
(
CheckJniException
(
env
,
&
exception
))
goto
fail
;
String
result
(
chars
,
length
);
env
->
ReleaseStringChars
(
java_string
(),
chars
);
return
result
;
}
fail:
Dart_ThrowException
(
exception
);
ASSERT_NOT_REACHED
();
}
IMPLEMENT_WRAPPERTYPEINFO
(
jni
,
JniArray
);
JniArray
::
JniArray
(
JNIEnv
*
env
,
jarray
array
)
:
JniObject
(
env
,
array
)
{}
JniArray
::~
JniArray
()
{
}
jsize
JniArray
::
GetLength
()
{
Dart_Handle
exception
=
nullptr
;
{
ENTER_JNI
();
jsize
result
=
env
->
GetArrayLength
(
java_array
<
jarray
>
());
if
(
CheckJniException
(
env
,
&
exception
))
goto
fail
;
return
result
;
}
fail:
Dart_ThrowException
(
exception
);
ASSERT_NOT_REACHED
();
}
template
<
typename
JArrayType
>
JArrayType
JniArray
::
java_array
()
const
{
return
static_cast
<
JArrayType
>
(
java_object
());
}
IMPLEMENT_WRAPPERTYPEINFO
(
jni
,
JniObjectArray
);
JniObjectArray
::
JniObjectArray
(
JNIEnv
*
env
,
jobjectArray
array
)
:
JniArray
(
env
,
array
)
{}
JniObjectArray
::~
JniObjectArray
()
{
}
PassRefPtr
<
JniObject
>
JniObjectArray
::
GetArrayElement
(
jsize
index
)
{
Dart_Handle
exception
=
nullptr
;
{
ENTER_JNI
();
jobject
obj
=
env
->
GetObjectArrayElement
(
java_array
<
jobjectArray
>
(),
index
);
if
(
CheckJniException
(
env
,
&
exception
))
goto
fail
;
return
JniObject
::
Create
(
env
,
obj
);
}
fail:
Dart_ThrowException
(
exception
);
ASSERT_NOT_REACHED
();
}
void
JniObjectArray
::
SetArrayElement
(
jsize
index
,
const
JniObject
*
value
)
{
Dart_Handle
exception
=
nullptr
;
{
ENTER_JNI
();
env
->
SetObjectArrayElement
(
java_array
<
jobjectArray
>
(),
index
,
value
->
java_object
());
if
(
CheckJniException
(
env
,
&
exception
))
goto
fail
;
return
;
}
fail:
Dart_ThrowException
(
exception
);
ASSERT_NOT_REACHED
();
}
}
// namespace blink
sky/engine/bindings/jni/dart_jni.h
浏览文件 @
acfbced1
...
...
@@ -23,9 +23,12 @@ class DartJni {
static
base
::
android
::
ScopedJavaLocalRef
<
jclass
>
GetClass
(
JNIEnv
*
env
,
const
char
*
name
);
static
std
::
string
GetObjectClassName
(
JNIEnv
*
env
,
jobject
obj
);
private:
static
base
::
android
::
ScopedJavaGlobalRef
<
jobject
>
class_loader_
;
static
jmethodID
load_class_method_id_
;
static
jmethodID
class_loader_load_class_method_id_
;
static
jmethodID
class_get_name_method_id_
;
};
class
JniObject
;
...
...
@@ -47,6 +50,9 @@ class JniClass : public RefCounted<JniClass>, public DartWrappable {
jint
GetStaticIntField
(
jfieldID
fieldId
);
PassRefPtr
<
JniObject
>
GetStaticObjectField
(
jfieldID
fieldId
);
PassRefPtr
<
JniObject
>
NewObject
(
jmethodID
methodId
,
const
Vector
<
Dart_Handle
>&
args
);
jlong
CallStaticLongMethod
(
jmethodID
methodId
,
const
Vector
<
Dart_Handle
>&
args
);
...
...
@@ -63,16 +69,69 @@ class JniObject : public RefCounted<JniObject>, public DartWrappable {
public:
~
JniObject
()
override
;
static
PassRefPtr
<
JniObject
>
create
(
JNIEnv
*
env
,
jobject
object
);
static
PassRefPtr
<
JniObject
>
Create
(
JNIEnv
*
env
,
jobject
object
);
jobject
java_object
()
const
{
return
object_
.
obj
();
}
jint
GetIntField
(
jfieldID
fieldId
);
private:
PassRefPtr
<
JniObject
>
CallObjectMethod
(
jmethodID
methodId
,
const
Vector
<
Dart_Handle
>&
args
);
bool
CallBooleanMethod
(
jmethodID
methodId
,
const
Vector
<
Dart_Handle
>&
args
);
jint
CallIntMethod
(
jmethodID
methodId
,
const
Vector
<
Dart_Handle
>&
args
);
protected:
JniObject
(
JNIEnv
*
env
,
jobject
object
);
base
::
android
::
ScopedJavaGlobalRef
<
jobject
>
object_
;
};
// Wrapper for a JNI string
class
JniString
:
public
JniObject
{
DEFINE_WRAPPERTYPEINFO
();
friend
class
JniObject
;
public:
~
JniString
()
override
;
String
GetText
();
private:
JniString
(
JNIEnv
*
env
,
jstring
string
);
jstring
java_string
();
};
// Wrapper for a JNI array
class
JniArray
:
public
JniObject
{
DEFINE_WRAPPERTYPEINFO
();
public:
~
JniArray
()
override
;
jsize
GetLength
();
protected:
JniArray
(
JNIEnv
*
env
,
jarray
array
);
template
<
typename
JArrayType
>
JArrayType
java_array
()
const
;
};
class
JniObjectArray
:
public
JniArray
{
DEFINE_WRAPPERTYPEINFO
();
friend
class
JniObject
;
public:
~
JniObjectArray
()
override
;
PassRefPtr
<
JniObject
>
GetArrayElement
(
jsize
index
);
void
SetArrayElement
(
jsize
index
,
const
JniObject
*
value
);
private:
JniObjectArray
(
JNIEnv
*
env
,
jobjectArray
array
);
};
template
<
>
struct
DartConverter
<
jfieldID
>
{
static
jfieldID
FromArguments
(
Dart_NativeArguments
args
,
...
...
sky/engine/bindings/jni/jni.dart
浏览文件 @
acfbced1
...
...
@@ -4,6 +4,7 @@
library
dart_jni
;
import
'dart:collection'
;
import
'dart:nativewrappers'
;
/// Wrapper for a Java class accessed via JNI.
...
...
@@ -18,10 +19,33 @@ class JniClass extends NativeFieldWrapperClass2 {
int
getStaticIntField
(
int
fieldId
)
native
'JniClass_GetStaticIntField'
;
JniObject
getStaticObjectField
(
int
fieldId
)
native
'JniClass_GetStaticObjectField'
;
JniObject
newObject
(
int
methodId
,
List
args
)
native
'JniClass_NewObject'
;
int
callStaticLongMethod
(
int
methodId
,
List
args
)
native
'JniClass_CallStaticLongMethod'
;
}
/// Wrapper for a Java object accessed via JNI.
class
JniObject
extends
NativeFieldWrapperClass2
{
int
getIntField
(
String
name
,
String
sig
)
native
'JniObject_getIntField'
;
JniObject
callObjectMethod
(
int
methodId
,
List
args
)
native
'JniObject_CallObjectMethod'
;
bool
callBooleanMethod
(
int
methodId
,
List
args
)
native
'JniObject_CallBooleanMethod'
;
int
callIntMethod
(
int
methodId
,
List
args
)
native
'JniObject_CallIntMethod'
;
}
/// Wrapper for a Java string.
class
JniString
extends
JniObject
{
// Retrieve the value as a Dart string.
String
get
text
native
'JniString_GetText'
;
}
/// Wrapper for a Java array.
class
JniArray
extends
JniObject
{
int
get
length
native
'JniArray_GetLength'
;
}
class
JniObjectArray
extends
JniArray
{
JniObject
operator
[](
int
index
)
native
'JniObjectArray_GetArrayElement'
;
void
operator
[]=(
int
index
,
JniObject
value
)
native
'JniObjectArray_SetArrayElement'
;
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录