android fromxscalewordk是什么

Google Docs For Android Gets Biggest Update In Its History With Android L Support, Word Compatibility, New UI, And More [APK Download]
Total Shares763
We knew big changes were coming to Google's office suite with the , but we didn't expect it this fast. Not only does today's Docs update fix that Android L incompatibility, it adds a ton of new features. Hold on to your butts.
What&s New
Fewer persistent icons in action bar
Floating new document button
Adds dictionary permissions for better spellcheck and corrections (also can add words to dictionary more easily)
New account selection drop-down style
Create and edit Word docs
New details page
File list differentiates between Word and Docs files
New editing UI
Open files from device storage
Send files as PDF or Word
It's a pretty tiny version number bump for adding so many new features & just 1.3.144.18 to 1.3.251.9. The entire editing interface had been overhauled with new features and the ability to create and edit Microsoft .docx files. This is the merging of QuickOffice with Google Drive we've been waiting for. There are a few UI tweaks, but the new editing features are the big news. There are a few more screens of the old UI down below.
Old behavior on the right
Old look on the right
It's not quite a Material Design app yet, but the floating new doc button at the bottom is a step in that direction. The app already had a blue action bar, but a few more functions have been moved into the menus so there are fewer buttons hanging out at the top. The account selector has also been tweaked. You'll be able to check it out for yourself even if you're on Android L & the bug that
on the L preview has been fixed.
More old screens
The APK is signed by Google and upgrades your existing app. The cryptographic signature guarantees that the file is safe to install and was not tampered with in any way. Rather than wait for Google to push this download to your devices, which can take days, download and install it just like any other APK.
File name: com.google.android.apps.docs.editors.docs-1.3.251.9.apk.
Version: 1.3.251.9 (Android 4.0+).
MD5: 05ea9ebea08e7dc2235dfb.
[Thanks, Ankur]
Generally speaking, what kinds of problems / complaints are you having about your Nexus 5X or 6P?
Performance issues / lag / slowness.
Poor / unpredictable battery life.
Wireless (Wi-Fi, Bluetooth, mobile data, NFC) connectivity issues.
Problems with the camera(s).
Call quality issues.
Stability problems / crashes.
Unusual physical damage / wear.
Audio issues.
Display quality / brightness / other display problems.
Other (elaborate in comments)
&Loading ...Android文档-开发者指南-第一部分:入门-中英文对照版-word_图文_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
Android文档-开发者指南-第一部分:入门-中英文对照版-word
上传于||暂无简介
阅读已结束,如果下载本文需要使用
想免费下载本文?
下载文档到电脑,查找使用更方便
还剩35页未读,继续阅读
你可能喜欢xml - Android Word-Wrap EditText text - Stack Overflow
to customize your list.
Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.
J it only takes a minute:
Join the Stack Overflow community to:
Ask programming questions
Answer and help your peers
Get recognized for your expertise
I have been trying to get my EditText box to word wrap, but can't seem to do it.
I have dealt with much more complicated issues while developing Android applications, and this seems like it should be a straight-forward process.
However, the issue remains, and I have a large text box that is only allowing me to enter text on one line, continuing straight across, scrolling horizontally as I enter text.
Here is the XML code for the EditText object from my layout file.
&?xml version="1.0" encoding="utf-8"?&
&LinearLayout
android:id="@+id/myWidget48"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
xmlns:android="/apk/res/android"
&ScrollView
android:id="@+id/myScrollView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
&LinearLayout
android:id="@+id/widget37"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="@+id/txtNotes"
android:layout_width="300px"
android:layout_height="120px"
android:scrollbars="vertical"
android:textSize="18sp"
android:gravity="left"
android:layout_marginTop="10dip"
android:inputType="textCapSentences"
&/EditText&
&/LinearLayout&
&/ScrollView&
&/LinearLayout&
1,63711621
Besides finding the source of the issue, I found the solution. If android:inputType is used, then textMultiLine must be used to enable multi-line support. Also, using inputType supersedes the code android:singleLine="false". If using inputType, then, to reiterate, textMultiLine must be used or the EditText object will only consist of one line, without word-wrapping.
Edit: Thank you Jacob Malliet for providing further good advice on this. He suggested to set the boolean scrollHorizontally property to false, 'android:scrollHorizontally="false"'.
Example XML code:
android:id ="@+id/edtInput"
android:layout_width ="0dip"
android:layout_height ="wrap_content"
android:layout_weight ="1"
android:inputType="textCapSentences|textMultiLine"
android:maxLines ="4"
android:maxLength ="2000"
android:hint ="@string/compose_hint"
android:scrollHorizontally="false" /&
1,63711621
Ok i figured it out, you must set android:scrollHorizontally="false" for your EditText in your xml. I'm pretty sure this should work.
5,64421733
I figured it out.
android:inputType="textCapSentences"
was the issue.
Adding this line to an EditText object will make the object be a single line EditText, and will not let words wrap, or allow a user to press 'Enter' to insert a line feed or carriage return in the EditText.
1,63711621
Assume that you just want to have one line at first then expand it to 5 lines and you want to have maximum 10 lines.
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/etMessageBox"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:autoLink="all"
android:hint="@string/message_edit_text_hint"
android:lines="5"
android:minLines="1"
android:gravity="top|left"
android:maxLines="10"
android:scrollbars="none"
android:inputType="textMultiLine|textCapSentences"/&
By increasing android:lines you can define expand it how many lines.
12k27110202
Enclosing the entire activity in scroll view and placing the following edit text with in linear layout worked like a charm for me.
The edit text would scroll itself vertically pressing enter, code as follows
android:id="@+id/editText1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:ems="10"
android:hint="Enter somehting"
android:inputType="textMultiLine"
android:maxLength="2000"
android:maxLines="6"
android:scrollHorizontally="false"
android:scrollbars="vertical" &
2,27841940
&TableLayout xmlns:android="/apk/res/android"
android:id="@+id/table"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:stretchColumns="1"
android:id="@+id/newRow"&
&LinearLayout
android:layout_width="fill_parent"
android:orientation="vertical"
android:layout_height="wrap_content"
android:gravity="left"
android:paddingBottom="10dip"&
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Some Text"
&/LinearLayout&
&/TableRow&
android:layout_height="2dip"
android:background="#FF909090" /&
&TableRow&
&RelativeLayout xmlns:android="/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingTop="10dip"&
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Some Text"
android:paddingBottom="5dip"
android:id="@+id/editbox"
android:layout_width="wrap_content"
android:layout_height="150px"
android:gravity="top"
android:inputType="textFilter"
android:scrollHorizontally="false"
&/RelativeLayout&
&/TableRow&
&TableRow&
&LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/btnone"
android:layout_width="3dip"
android:layout_height="wrap_content"
android:layout_margin="2dip"
android:layout_weight="1"
android:text="Btn"
android:id="@+id/btntwo"
android:layout_width="3dip"
android:layout_height="wrap_content"
android:layout_margin="2dip"
android:layout_weight="1"
android:text="Btn"
&/LinearLayout&
&/TableRow&
&/TableLayout&
20.2k17110193
Your Answer
Sign up or
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Post as a guest
By posting your answer, you agree to the
Not the answer you're looking for?
Browse other questions tagged
Stack Overflow works best with JavaScript enabled适合于平板电脑的 Microsoft Office 套件[Android]
(快来投票)
Loading...
作为最好用的办公软件,Office 本无需过多介绍,算上之前的 iPad 版本,微软总算把强大的 Office 全面搬到了移动端,并且能免费试用核心功能,没听说过“很多人使用 Office 不到 5% 功能”这句老话么?
大屏幕天生就比小屏幕适合移动办公,手机端需要拖来拖去使用的情况在平板端就舒服多了,来看一段官方视频:
另外安装前看看你的平板合适不:
屏幕尺寸大于或等于 7 英寸的 Android 平板电脑
操作系统版本:KitKat (4.4.X)
基于 ARM 的处理器
1 GB 或以上的 RAM
使用习惯于桌面端相同,只需要把鼠标换成手指头。如果你有 Office365 的付费订阅版本,就可以使用全部功能了,未找到全部功能与核心功能列表…
总之平时办公经常需要 Office 三件套的同学赶紧上一个,随时随地办公老板最喜欢了。
喜欢这篇文章?
按分类查看文章:
大家都在讨论些什么
: 实际试了下,也确实初三难度。: 同问?: 第二题怎么解?: 视频那个前面那个动画好炫: 学习了,顺便推荐我自己在做地图网站Maplet, 有一些相同之处。 http://www.maplet.org
。 完全用开源技术做的WebGIS。公益非赢利网站,以教育、科普为主。: 从图上来看,初三难度 同位角,圆周角,外角和。。: 是国内生物学老师,迫切需要此款app.请教如何安装谷歌服务,如何能使用?
最热门标签
传说中的小众软件 让你的手机应用与众不同。
个人 blog 转载时请遵循 “署名-非商业性使用-相同方式共享” 的创作共用协议;
商业网站或未授权媒体不得复制本站内容。山岚的一缺
正如章所说跟踪代码是可行的,但是跟踪某些代码会出现anr,点击取消,还是不好运,有提高办法吗?回答是有(gdb还没试过,本文只讨论ida)。
下面是我使用&0 * Message("%s = %d\n", GetString(Dword(R2+0x10),-1, ASCSTR_C), R2+0x20)打出的记录
enforceInterface = writeInterfaceToken = writeStrongBinder = transact = lockCanvasNative = nativeDraw = native_getClipBounds = native_measureText = native_drawText = nativeDraw = unlockCanvasAndPost = enforceInterface = writeInterfaceToken = writeStrongBinder = transact = native_get_long = method = native_measureText = getFontMetricsInt = native_measureText = native_measureText = lockCanvasNative = drawText = nativeDraw = native_getClipBounds = native_measureText = native_drawText = nativeDraw = native_getClipBounds = native_measureText = native_drawText = nativeDraw = unlockCanvasAndPost =
反复调用然后anr了。
为了改善这种情况。经过仔细查阅IDA文档Edit breakpoint一章,发现
Low level condition:
Evaluate the condition on the remote computer. Such conditions are
faster, especially during remote debugging, because there is no
network traffic between IDA and the remote computer on each
breakpoint hit.
低级条件,在远程计算机计算条件。这种条件运行更快,特别是在远程调试的时候。详细内容如下:
Low level breakpoint conditions
Low level breakpoint conditions can be used to speed up the debugger. They are evaluated like this:
- for remote debugging, such a condition is evaluated on the remote
computer. The following actions are bypassed:
- copying the breakpoint event to the local computer
- switching from debthread to the main thread
- updating internal IDA structures and caches
- updating the screen
- for local debugging, such a condition is evaluated at low level.
The following actions are bypassed:
- switching from debthread to the main thread
- updating internal IDA structures and caches
- updating the screen
In both cases, there is a significant speed up. This improvement imposes some limitations on the breakpoint condition:
expressions can be used for low level conditions
- only functions marked as 'thread-safe' may be called
- only entire registers can be accessed (e.g. EAX is ok but AL is not)
Essentially this means that the only available functions are:
- read/write process registers
- read/write process memory
- file i/o
- auxiliary string and object functions
- Message() function (for debugging the breakpoint conditions)
Low level breakpoint conditions are available only for Win32, WinCE, Linux, Mac, Android debuggers.&
从中看到对我有影响的就是使用的函数必须带有'thread-safe'字样提示。
&诸如前文使用的
0 * print(GetString(DbgDword(R2+0x10),-1, ASCSTR_C))
"method" == GetString(DbgDword(R2+0x10),-1, ASCSTR_C)
0 * Message("%s = %d\n", GetString(DbgDword(R2+0x10),-1, ASCSTR_C), R2+0x20)
其中DbgDword就是线程安全的,而Dword就不是,如此
// Get value of program double word (4 bytes) using the debugger memory
ea - linear address
// returns: the value of the double word. Throws an exception on failure.
// Thread-safe function (may be called only from the main thread and debthread)
long DbgDword (long ea);
表达式中另一个函数也不行
// Get string contents
- linear address
- string length. -1 means to calculate the max string length
type - the string type (one of ASCSTR_... constants)
// Returns: string contents or empty string
string GetString(long ea, long len, long type);
See also&&function.
所以报错,不允许。
为了找到替代,找到一大圈无果。直到一个一个比较,先比较前几个吧如案例
可以在这个论坛下载
#include &sys/types.h&
#include &signal.h&
#include &stdio.h&
#include &unistd.h&
#include &dlfcn.h&
#include &string.h&
#include &errno.h&
package com.
public class MainActivity{
private native String crackme(String paramString1, String paramString2);
Native的对应函数名要以&Java_&开头,后面依次跟上Java的&package名&、&class名&、&函数名&,中间以下划线&_& 分割,在package名中的&.&也要改为&_&。
此外,关于函数的参数和返回值也有相应的规则。对于Java中的基本类型如int 、double 、char等,在Native端都有相对应的类型来表示,如jint 、jdouble 、jchar 等;其他的对象类型则统统由jobject 来表示(String 是个例外,由于其使用广泛,故在Native代码中有 jstring 这个类型来表示,正如在上例中返回值String 对应到Native代码中的返回值jstring )。而对于Java中的数组,在Native中由jarray 对应,具体到基本类型和一般对象类型的数组则有jintArray 等和jobjectArray 分别对应(String 数组在这里没有例外,同样用jobjectArray 表示)。
还有一点需要注意的是,在JNI的Native函数中,其前两个参数JNIEnv *和jobject 是必需的&&前者是一个JNIEnv 结构体的指针是JNI的核心数据,这个结构体中定义了很多JNI的接口函数指针,使开发者可以使用JNI所定义的接口功能;后者指代的是调用这个JNI函数的Java对象,有点类似于C++中的this 指针。在上述两个参数之后,还需要根据Java端的函数声明依次对应添加参数。
在上例中,Java中声明的JNI函数对应命名为:
com_crackme_MainActivity
//Signature: (Ljava/lang/S)Ljava/lang/S
jstring Java_com_crackme_MainActivity_crackme(JNIEnv *,jobject,jstring,jstring);
jstring (*crackme)(JNIEnv *,jobject,jstring, jstring) = NULL;
//事先把libcrackme.so放到root/system/lib/目录下
void *filehandle = dlopen("/system/lib/libcrackme.so", RTLD_LAZY);
//(jstring (*)(JNIEnv *,jobject, jstring, jstring))
if(filehandle)
crackme = (jstring (*)(JNIEnv *,jobject, jstring, jstring))dlsym(filehandle, "Java_com_crackme_MainActivity_crackme");
if(crackme){
jstring s = crackme(env, obj, a, b);
dlclose(filehandle);
filehandle = NULL;
typedef void *CRACKME;
//typedef jstring *CRACKME(JNIEnv *,jobject, jstring, jstring);
int main(int argc, char **argv)
int i = 0;
handle = dlopen("/home/Sansan/a/libcrackme.so", RTLD_LAZY);
if (!handle) {
printf("%s, %d, NULL == handle. errno = %d, %s\n", __FUNCTION__, __LINE__, errno, strerror(errno));
return -1;
crackme = dlsym(handle, "JNI_OnLoad");
if (!crackme) {
printf("%s, %d, NULL == crackme\n", __FUNCTION__, __LINE__);
return -1;
printf("%s, %d, crackme = %p\n", __FUNCTION__, __LINE__, crackme);
dlclose(handle);
&条件语句类似这样
'c' == DbgByte(DbgDword(R2+0x10)) && 'r' == DbgByte(1+DbgDword(R2+0x10)) && 'a' == DbgByte(2+DbgDword(R2+0x10)) && 'c' == DbgByte(3+DbgDword(R2+0x10)) && 'k' == DbgByte(4+DbgDword(R2+0x10))
跳到目标,如果F5不行需要弄一下。
最后F5结果,有神奇F5就是容易点啊,虽说君子善假于物也,依靠工具会产生惰性,分析汇编能力会下降。
int __fastcall sub_80905D1C(int a1, int a2, int a3, int a4)
int v4; // r6@1
int v5; // r4@1
int v6; // r7@1
int v7; // r0@1
v6 = (*(int (**)(void))(*(_DWORD *)a1 + 676))();
v7 = (*(int (__fastcall **)(int, int, _DWORD))(*(_DWORD *)v5 + 676))(v5, v4, 0);
((void (__fastcall *)(_UNKNOWN *, int, int))sub_)(&"Failure", v6, v7);
((void (__fastcall *)(_UNKNOWN *))sub_80905C44)(&"Failure");
return (*(int (__fastcall **)(int, _UNKNOWN *))(*(_DWORD *)v5 + 668))(v5, &"Failure");
int __fastcall sub_(int a1, int a2, int a3)
int v3; // r6@1
int v4; // r4@1
int v5; // r5@1
int // r0@1
int v7; // r0@3
int v8; // r7@3
int v9; // r0@3
int v10; // r7@3
int v11; // r3@3
int v12; // [sp+4h] [bp-24h]@3
int v13; // [sp+8h] [bp-20h]@3
int v14; // [sp+Ch] [bp-1Ch]@3
result = ((int (*)(void))unk_)();
v7 = ((int (__fastcall *)(int))strlen_0)(v5);
v9 = ((int (__fastcall *)(int))strlen_0)(v3);
v10 = v8 + 1;
v12 = v9 + 1;
*(_DWORD *)(v4 + 52) = ((int (__fastcall *)(int))malloc_0)(v10);
result = ((int (__fastcall *)(int))malloc_0)(v12);
v11 = *(_DWORD *)(v4 + 52);
*(_DWORD *)(v4 + 56) =
if ( v11 )
if ( result )
((void (__fastcall *)(int, _DWORD, int))memset_0)(v11, 0, v10);
((void (__fastcall *)(_DWORD, _DWORD, int))memset_0)(*(_DWORD *)(v4 + 56), 0, v12);
((void (__fastcall *)(_DWORD, int, int))memcpy_0)(*(_DWORD *)(v4 + 52), v5, v13);
result = ((int (__fastcall *)(_DWORD, int, int))memcpy_0)(*(_DWORD *)(v4 + 56), v3, v14);
int __fastcall sub_(int a1)
int v1; // r4@1
if ( *(_DWORD *)(a1 + 52) )
((void (*)(void))free)();
*(_DWORD *)(v1 + 52) = 0;
if ( *(_DWORD *)(v1 + 56) )
((void (*)(void))free)();
*(_DWORD *)(v1 + 56) = 0;
memset_0(v1 + 60, 0, 30);
return memset_0(v1, 0, 50);
接下来的工作分析吧,很常规了。。。
附两个头可以直接导入,使用其中的结构体,但是对于C++方式结构体,即类的不知道怎么导入,记住先倒入依赖的头stddarg.h(jni依赖它)
* stdarg.h
* Provides facilities for stepping through a list of function arguments of
* an unknown number and type.
* NOTE: Gcc should provide stdarg.h, and I believe their version will work
with crtdll. If necessary I think you can replace this with the GCC
* Note that the type used in va_arg is supposed to match the actual type
* *after default promotions*. Thus, va_arg (..., short) is not valid.
* This file is part of the Mingw32 package.
* Contributors:
Created by Colin Peters &colin@bird.fu.is.saga-u.ac.jp&
THIS SOFTWARE IS NOT COPYRIGHTED
This source code is offered for use in the public domain. You may
use, modify or distribute it freely.
This code is distributed in the hope that it will be useful but
WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
DISCLAMED. This includes but is not limited to warranties of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* $Revision: 1.2 $
* $Author: noer $
00:51:16 $
#ifndef _STDARG_H_
#define _STDARG_H_
* Don't do any of this stuff for the resource compiler.
#ifndef RC_INVOKED
* I was told that Win NT likes this.
#ifndef _VA_LIST_DEFINED
#define _VA_LIST_DEFINED
#define _VA_LIST
typedef char* va_
* Amount of space required in an argument list (ie. the stack) for an
* argument of type t.
#define __va_argsiz(t)
(((sizeof(t) + sizeof(int) - 1) / sizeof(int)) * sizeof(int))
* Start variable argument list processing by setting AP to point to the
* argument after pN.
* In GNU the stack is not necessarily arranged very neatly in order to
* pack shorts and such into a smaller argument list. Fortunately a
* neatly arranged version is available through the use of __builtin_next_arg.
#define va_start(ap, pN)
((ap) = ((va_list) __builtin_next_arg(pN)))
* For a simple minded compiler this should work (it works in GNU too for
* vararg lists that don't follow shorts and such).
#define va_start(ap, pN)
((ap) = ((va_list) (&pN) + __va_argsiz(pN)))
* End processing of variable argument list. In this case we do nothing.
#define va_end(ap)
* Increment ap to the next argument in the list while returing a
* pointer to what ap pointed to first, which is of type t.
* We cast to void* and then to t* because this avoids a warning about
* increasing the alignment requirement.
#define va_arg(ap, t)
(((ap) = (ap) + __va_argsiz(t)),
*((t*) (void*) ((ap) - __va_argsiz(t))))
#endif /* Not RC_INVOKED */
#endif /* not _STDARG_H_ */
//xref: /development/ndk/platforms/android-3/include/jni.h
///2.3.6/xref/development/ndk/platforms/android-3/include/jni.h
* Copyright 2006 The Android Open Source Project
* JNI specification, as defined by Sun:
* /javase/6/docs/technotes/guides/jni/spec/jniTOC.html
* Everything here is expected to be VM-neutral.
#ifndef _JNI_H
#define _JNI_H
//#include &stdarg.h&
* Primitive types that match up with Java equivalents.
#ifdef HAVE_INTTYPES_H
//@@@@@@@@@ # include &inttypes.h&
typedef uint8_
/* unsigned 8 bits */
typedef int8_
/* signed 8 bits */
typedef uint16_
/* unsigned 16 bits */
typedef int16_
/* signed 16 bits */
typedef int32_
/* signed 32 bits */
typedef int64_
/* signed 64 bits */
typedef float
/* 32-bit IEEE 754 */
typedef double
/* 64-bit IEEE 754 */
typedef unsigned char
/* unsigned 8 bits */
typedef signed char
/* signed 8 bits */
typedef unsigned short
/* unsigned 16 bits */
typedef short
/* signed 16 bits */
typedef int
/* signed 32 bits */
typedef long long
/* signed 64 bits */
typedef float
/* 32-bit IEEE 754 */
typedef double
/* 64-bit IEEE 754 */
/* "cardinal indices and sizes" */
#ifdef __cplusplus
* Reference types, in C++
class _jobject {};
class _jclass : public _jobject {};
class _jstring : public _jobject {};
class _jarray : public _jobject {};
class _jobjectArray : public _jarray {};
class _jbooleanArray : public _jarray {};
class _jbyteArray : public _jarray {};
class _jcharArray : public _jarray {};
class _jshortArray : public _jarray {};
class _jintArray : public _jarray {};
class _jlongArray : public _jarray {};
class _jfloatArray : public _jarray {};
class _jdoubleArray : public _jarray {};
class _jthrowable : public _jobject {};
typedef _jobject*
typedef _jclass*
typedef _jstring*
typedef _jarray*
typedef _jobjectArray*
typedef _jbooleanArray* jbooleanA
typedef _jbyteArray*
typedef _jcharArray*
typedef _jshortArray*
typedef _jintArray*
typedef _jlongArray*
typedef _jfloatArray*
typedef _jdoubleArray*
typedef _jthrowable*
typedef _jobject*
#else /* not __cplusplus */
* Reference types, in C.
typedef void*
typedef jo
typedef job
typedef jo
typedef jarray
typedef jarray
typedef jarray
typedef jarray
typedef jarray
typedef jarray
typedef jarray
typedef jarray
typedef jarray
typedef jobjec
#endif /* not __cplusplus */
struct _jfieldID;
/* opaque structure */
typedef struct _jfieldID* jfieldID;
/* field IDs */
struct _jmethodID;
/* opaque structure */
typedef struct _jmethodID* jmethodID;
/* method IDs */
struct JNIInvokeI
typedef union jvalue {
typedef enum jobjectRefType {
JNIInvalidRefType = 0,
JNILocalRefType = 1,
JNIGlobalRefType = 2,
JNIWeakGlobalRefType = 3
} jobjectRefT
typedef struct {
const char*
const char*
} JNINativeM
struct _JNIE
struct _JavaVM;
typedef const struct JNINativeInterface* C_JNIE
#if defined(__cplusplus)
typedef _JNIEnv JNIE
typedef _JavaVM JavaVM;
typedef const struct JNINativeInterface* JNIE
typedef const struct JNIInvokeInterface* JavaVM;
* Table of interface function pointers.
struct JNINativeInterface {
reserved0;
reserved1;
reserved2;
reserved3;
(*GetVersion)(JNIEnv *);
(*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*,
(*FindClass)(JNIEnv*, const char*);
(*FromReflectedMethod)(JNIEnv*, jobject);
(*FromReflectedField)(JNIEnv*, jobject);
/* spec doesn't show jboolean parameter */
(*ToReflectedMethod)(JNIEnv*, jclass, jmethodID, jboolean);
(*GetSuperclass)(JNIEnv*, jclass);
(*IsAssignableFrom)(JNIEnv*, jclass, jclass);
/* spec doesn't show jboolean parameter */
(*ToReflectedField)(JNIEnv*, jclass, jfieldID, jboolean);
(*Throw)(JNIEnv*, jthrowable);
(*ThrowNew)(JNIEnv *, jclass, const char *);
jthrowable
(*ExceptionOccurred)(JNIEnv*);
(*ExceptionDescribe)(JNIEnv*);
(*ExceptionClear)(JNIEnv*);
(*FatalError)(JNIEnv*, const char*);
(*PushLocalFrame)(JNIEnv*, jint);
(*PopLocalFrame)(JNIEnv*, jobject);
(*NewGlobalRef)(JNIEnv*, jobject);
(*DeleteGlobalRef)(JNIEnv*, jobject);
(*DeleteLocalRef)(JNIEnv*, jobject);
(*IsSameObject)(JNIEnv*, jobject, jobject);
(*NewLocalRef)(JNIEnv*, jobject);
(*EnsureLocalCapacity)(JNIEnv*, jint);
(*AllocObject)(JNIEnv*, jclass);
(*NewObject)(JNIEnv*, jclass, jmethodID, ...);
(*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list);
(*NewObjectA)(JNIEnv*, jclass, jmethodID, jvalue*);
(*GetObjectClass)(JNIEnv*, jobject);
(*IsInstanceOf)(JNIEnv*, jobject, jclass);
(*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
(*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...);
(*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list);
(*CallObjectMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
(*CallBooleanMethod)(JNIEnv*, jobject, jmethodID, ...);
(*CallBooleanMethodV)(JNIEnv*, jobject, jmethodID, va_list);
(*CallBooleanMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
(*CallByteMethod)(JNIEnv*, jobject, jmethodID, ...);
(*CallByteMethodV)(JNIEnv*, jobject, jmethodID, va_list);
(*CallByteMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
(*CallCharMethod)(JNIEnv*, jobject, jmethodID, ...);
(*CallCharMethodV)(JNIEnv*, jobject, jmethodID, va_list);
(*CallCharMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
(*CallShortMethod)(JNIEnv*, jobject, jmethodID, ...);
(*CallShortMethodV)(JNIEnv*, jobject, jmethodID, va_list);
(*CallShortMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
(*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);
(*CallIntMethodV)(JNIEnv*, jobject, jmethodID, va_list);
(*CallIntMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
(*CallLongMethod)(JNIEnv*, jobject, jmethodID, ...);
(*CallLongMethodV)(JNIEnv*, jobject, jmethodID, va_list);
(*CallLongMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
(*CallFloatMethod)(JNIEnv*, jobject, jmethodID, ...);
(*CallFloatMethodV)(JNIEnv*, jobject, jmethodID, va_list);
(*CallFloatMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
(*CallDoubleMethod)(JNIEnv*, jobject, jmethodID, ...);
(*CallDoubleMethodV)(JNIEnv*, jobject, jmethodID, va_list);
(*CallDoubleMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
(*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
(*CallVoidMethodV)(JNIEnv*, jobject, jmethodID, va_list);
(*CallVoidMethodA)(JNIEnv*, jobject, jmethodID, jvalue*);
(*CallNonvirtualObjectMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
(*CallNonvirtualObjectMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
(*CallNonvirtualObjectMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
(*CallNonvirtualBooleanMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
(*CallNonvirtualBooleanMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
(*CallNonvirtualBooleanMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
(*CallNonvirtualByteMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
(*CallNonvirtualByteMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
(*CallNonvirtualByteMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
(*CallNonvirtualCharMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
(*CallNonvirtualCharMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
(*CallNonvirtualCharMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
(*CallNonvirtualShortMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
(*CallNonvirtualShortMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
(*CallNonvirtualShortMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
(*CallNonvirtualIntMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
(*CallNonvirtualIntMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
(*CallNonvirtualIntMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
(*CallNonvirtualLongMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
(*CallNonvirtualLongMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
(*CallNonvirtualLongMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
(*CallNonvirtualFloatMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
(*CallNonvirtualFloatMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
(*CallNonvirtualFloatMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
(*CallNonvirtualDoubleMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
(*CallNonvirtualDoubleMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
(*CallNonvirtualDoubleMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
(*CallNonvirtualVoidMethod)(JNIEnv*, jobject, jclass,
jmethodID, ...);
(*CallNonvirtualVoidMethodV)(JNIEnv*, jobject, jclass,
jmethodID, va_list);
(*CallNonvirtualVoidMethodA)(JNIEnv*, jobject, jclass,
jmethodID, jvalue*);
(*GetFieldID)(JNIEnv*, jclass, const char*, const char*);
(*GetObjectField)(JNIEnv*, jobject, jfieldID);
(*GetBooleanField)(JNIEnv*, jobject, jfieldID);
(*GetByteField)(JNIEnv*, jobject, jfieldID);
(*GetCharField)(JNIEnv*, jobject, jfieldID);
(*GetShortField)(JNIEnv*, jobject, jfieldID);
(*GetIntField)(JNIEnv*, jobject, jfieldID);
(*GetLongField)(JNIEnv*, jobject, jfieldID);
(*GetFloatField)(JNIEnv*, jobject, jfieldID);
(*GetDoubleField)(JNIEnv*, jobject, jfieldID);
(*SetObjectField)(JNIEnv*, jobject, jfieldID, jobject);
(*SetBooleanField)(JNIEnv*, jobject, jfieldID, jboolean);
(*SetByteField)(JNIEnv*, jobject, jfieldID, jbyte);
(*SetCharField)(JNIEnv*, jobject, jfieldID, jchar);
(*SetShortField)(JNIEnv*, jobject, jfieldID, jshort);
(*SetIntField)(JNIEnv*, jobject, jfieldID, jint);
(*SetLongField)(JNIEnv*, jobject, jfieldID, jlong);
(*SetFloatField)(JNIEnv*, jobject, jfieldID, jfloat);
(*SetDoubleField)(JNIEnv*, jobject, jfieldID, jdouble);
(*GetStaticMethodID)(JNIEnv*, jclass, const char*, const char*);
(*CallStaticObjectMethod)(JNIEnv*, jclass, jmethodID, ...);
(*CallStaticObjectMethodV)(JNIEnv*, jclass, jmethodID, va_list);
(*CallStaticObjectMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
(*CallStaticBooleanMethod)(JNIEnv*, jclass, jmethodID, ...);
(*CallStaticBooleanMethodV)(JNIEnv*, jclass, jmethodID,
(*CallStaticBooleanMethodA)(JNIEnv*, jclass, jmethodID,
(*CallStaticByteMethod)(JNIEnv*, jclass, jmethodID, ...);
(*CallStaticByteMethodV)(JNIEnv*, jclass, jmethodID, va_list);
(*CallStaticByteMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
(*CallStaticCharMethod)(JNIEnv*, jclass, jmethodID, ...);
(*CallStaticCharMethodV)(JNIEnv*, jclass, jmethodID, va_list);
(*CallStaticCharMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
(*CallStaticShortMethod)(JNIEnv*, jclass, jmethodID, ...);
(*CallStaticShortMethodV)(JNIEnv*, jclass, jmethodID, va_list);
(*CallStaticShortMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
(*CallStaticIntMethod)(JNIEnv*, jclass, jmethodID, ...);
(*CallStaticIntMethodV)(JNIEnv*, jclass, jmethodID, va_list);
(*CallStaticIntMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
(*CallStaticLongMethod)(JNIEnv*, jclass, jmethodID, ...);
(*CallStaticLongMethodV)(JNIEnv*, jclass, jmethodID, va_list);
(*CallStaticLongMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
(*CallStaticFloatMethod)(JNIEnv*, jclass, jmethodID, ...);
(*CallStaticFloatMethodV)(JNIEnv*, jclass, jmethodID, va_list);
(*CallStaticFloatMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
(*CallStaticDoubleMethod)(JNIEnv*, jclass, jmethodID, ...);
(*CallStaticDoubleMethodV)(JNIEnv*, jclass, jmethodID, va_list);
(*CallStaticDoubleMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
(*CallStaticVoidMethod)(JNIEnv*, jclass, jmethodID, ...);
(*CallStaticVoidMethodV)(JNIEnv*, jclass, jmethodID, va_list);
(*CallStaticVoidMethodA)(JNIEnv*, jclass, jmethodID, jvalue*);
(*GetStaticFieldID)(JNIEnv*, jclass, const char*,
const char*);
(*GetStaticObjectField)(JNIEnv*, jclass, jfieldID);
(*GetStaticBooleanField)(JNIEnv*, jclass, jfieldID);
(*GetStaticByteField)(JNIEnv*, jclass, jfieldID);
(*GetStaticCharField)(JNIEnv*, jclass, jfieldID);
(*GetStaticShortField)(JNIEnv*, jclass, jfieldID);
(*GetStaticIntField)(JNIEnv*, jclass, jfieldID);
(*GetStaticLongField)(JNIEnv*, jclass, jfieldID);
(*GetStaticFloatField)(JNIEnv*, jclass, jfieldID);
(*GetStaticDoubleField)(JNIEnv*, jclass, jfieldID);
(*SetStaticObjectField)(JNIEnv*, jclass, jfieldID, jobject);
(*SetStaticBooleanField)(JNIEnv*, jclass, jfieldID, jboolean);
(*SetStaticByteField)(JNIEnv*, jclass, jfieldID, jbyte);
(*SetStaticCharField)(JNIEnv*, jclass, jfieldID, jchar);
(*SetStaticShortField)(JNIEnv*, jclass, jfieldID, jshort);
(*SetStaticIntField)(JNIEnv*, jclass, jfieldID, jint);
(*SetStaticLongField)(JNIEnv*, jclass, jfieldID, jlong);
(*SetStaticFloatField)(JNIEnv*, jclass, jfieldID, jfloat);
(*SetStaticDoubleField)(JNIEnv*, jclass, jfieldID, jdouble);
(*NewString)(JNIEnv*, const jchar*, jsize);
(*GetStringLength)(JNIEnv*, jstring);
const jchar* (*GetStringChars)(JNIEnv*, jstring, jboolean*);
(*ReleaseStringChars)(JNIEnv*, jstring, const jchar*);
(*NewStringUTF)(JNIEnv*, const char*);
(*GetStringUTFLength)(JNIEnv*, jstring);
/* JNI spec says this returns const jbyte*, but that's inconsistent */
const char* (*GetStringUTFChars)(JNIEnv*, jstring, jboolean*);
(*ReleaseStringUTFChars)(JNIEnv*, jstring, const char*);
(*GetArrayLength)(JNIEnv*, jarray);
jobjectArray (*NewObjectArray)(JNIEnv*, jsize, jclass, jobject);
(*GetObjectArrayElement)(JNIEnv*, jobjectArray, jsize);
(*SetObjectArrayElement)(JNIEnv*, jobjectArray, jsize, jobject);
jbooleanArray (*NewBooleanArray)(JNIEnv*, jsize);
jbyteArray
(*NewByteArray)(JNIEnv*, jsize);
jcharArray
(*NewCharArray)(JNIEnv*, jsize);
jshortArray
(*NewShortArray)(JNIEnv*, jsize);
(*NewIntArray)(JNIEnv*, jsize);
jlongArray
(*NewLongArray)(JNIEnv*, jsize);
jfloatArray
(*NewFloatArray)(JNIEnv*, jsize);
jdoubleArray
(*NewDoubleArray)(JNIEnv*, jsize);
(*GetBooleanArrayElements)(JNIEnv*, jbooleanArray, jboolean*);
(*GetByteArrayElements)(JNIEnv*, jbyteArray, jboolean*);
(*GetCharArrayElements)(JNIEnv*, jcharArray, jboolean*);
(*GetShortArrayElements)(JNIEnv*, jshortArray, jboolean*);
(*GetIntArrayElements)(JNIEnv*, jintArray, jboolean*);
(*GetLongArrayElements)(JNIEnv*, jlongArray, jboolean*);
(*GetFloatArrayElements)(JNIEnv*, jfloatArray, jboolean*);
(*GetDoubleArrayElements)(JNIEnv*, jdoubleArray, jboolean*);
(*ReleaseBooleanArrayElements)(JNIEnv*, jbooleanArray,
jboolean*, jint);
(*ReleaseByteArrayElements)(JNIEnv*, jbyteArray,
jbyte*, jint);
(*ReleaseCharArrayElements)(JNIEnv*, jcharArray,
jchar*, jint);
(*ReleaseShortArrayElements)(JNIEnv*, jshortArray,
jshort*, jint);
(*ReleaseIntArrayElements)(JNIEnv*, jintArray,
jint*, jint);
(*ReleaseLongArrayElements)(JNIEnv*, jlongArray,
jlong*, jint);
(*ReleaseFloatArrayElements)(JNIEnv*, jfloatArray,
jfloat*, jint);
(*ReleaseDoubleArrayElements)(JNIEnv*, jdoubleArray,
jdouble*, jint);
(*GetBooleanArrayRegion)(JNIEnv*, jbooleanArray,
jsize, jsize, jboolean*);
(*GetByteArrayRegion)(JNIEnv*, jbyteArray,
jsize, jsize, jbyte*);
(*GetCharArrayRegion)(JNIEnv*, jcharArray,
jsize, jsize, jchar*);
(*GetShortArrayRegion)(JNIEnv*, jshortArray,
jsize, jsize, jshort*);
(*GetIntArrayRegion)(JNIEnv*, jintArray,
jsize, jsize, jint*);
(*GetLongArrayRegion)(JNIEnv*, jlongArray,
jsize, jsize, jlong*);
(*GetFloatArrayRegion)(JNIEnv*, jfloatArray,
jsize, jsize, jfloat*);
(*GetDoubleArrayRegion)(JNIEnv*, jdoubleArray,
jsize, jsize, jdouble*);
/* spec shows some jni.h do, some don't */
(*SetBooleanArrayRegion)(JNIEnv*, jbooleanArray,
jsize, jsize, const jboolean*);
(*SetByteArrayRegion)(JNIEnv*, jbyteArray,
jsize, jsize, const jbyte*);
(*SetCharArrayRegion)(JNIEnv*, jcharArray,
jsize, jsize, const jchar*);
(*SetShortArrayRegion)(JNIEnv*, jshortArray,
jsize, jsize, const jshort*);
(*SetIntArrayRegion)(JNIEnv*, jintArray,
jsize, jsize, const jint*);
(*SetLongArrayRegion)(JNIEnv*, jlongArray,
jsize, jsize, const jlong*);
(*SetFloatArrayRegion)(JNIEnv*, jfloatArray,
jsize, jsize, const jfloat*);
(*SetDoubleArrayRegion)(JNIEnv*, jdoubleArray,
jsize, jsize, const jdouble*);
(*RegisterNatives)(JNIEnv*, jclass, const JNINativeMethod*,
(*UnregisterNatives)(JNIEnv*, jclass);
(*MonitorEnter)(JNIEnv*, jobject);
(*MonitorExit)(JNIEnv*, jobject);
(*GetJavaVM)(JNIEnv*, JavaVM**);
(*GetStringRegion)(JNIEnv*, jstring, jsize, jsize, jchar*);
(*GetStringUTFRegion)(JNIEnv*, jstring, jsize, jsize, char*);
(*GetPrimitiveArrayCritical)(JNIEnv*, jarray, jboolean*);
(*ReleasePrimitiveArrayCritical)(JNIEnv*, jarray, void*, jint);
const jchar* (*GetStringCritical)(JNIEnv*, jstring, jboolean*);
(*ReleaseStringCritical)(JNIEnv*, jstring, const jchar*);
(*NewWeakGlobalRef)(JNIEnv*, jobject);
(*DeleteWeakGlobalRef)(JNIEnv*, jweak);
(*ExceptionCheck)(JNIEnv*);
(*NewDirectByteBuffer)(JNIEnv*, void*, jlong);
(*GetDirectBufferAddress)(JNIEnv*, jobject);
(*GetDirectBufferCapacity)(JNIEnv*, jobject);
/* added in JNI 1.6 */
jobjectRefType (*GetObjectRefType)(JNIEnv*, jobject);
* C++ object wrapper.
* This is usually overlaid on a C struct whose first element is a
* JNINativeInterface*.
We rely somewhat on compiler behavior.
struct _JNIEnv {
/* it does not seem to be entirely opaque */
const struct JNINativeInterface*
#if defined(__cplusplus)
jint GetVersion()
{ return functions-&GetVersion(this); }
jclass DefineClass(const char *name, jobject loader, const jbyte* buf,
jsize bufLen)
{ return functions-&DefineClass(this, name, loader, buf, bufLen); }
jclass FindClass(const char* name)
{ return functions-&FindClass(this, name); }
jmethodID FromReflectedMethod(jobject method)
{ return functions-&FromReflectedMethod(this, method); }
jfieldID FromReflectedField(jobject field)
{ return functions-&FromReflectedField(this, field); }
jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic)
{ return functions-&ToReflectedMethod(this, cls, methodID, isStatic); }
jclass GetSuperclass(jclass clazz)
{ return functions-&GetSuperclass(this, clazz); }
jboolean IsAssignableFrom(jclass clazz1, jclass clazz2)
{ return functions-&IsAssignableFrom(this, clazz1, clazz2); }
jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic)
{ return functions-&ToReflectedField(this, cls, fieldID, isStatic); }
jint Throw(jthrowable obj)
{ return functions-&Throw(this, obj); }
jint ThrowNew(jclass clazz, const char* message)
{ return functions-&ThrowNew(this, clazz, message); }
jthrowable ExceptionOccurred()
{ return functions-&ExceptionOccurred(this); }
void ExceptionDescribe()
{ functions-&ExceptionDescribe(this); }
void ExceptionClear()
{ functions-&ExceptionClear(this); }
void FatalError(const char* msg)
{ functions-&FatalError(this, msg); }
jint PushLocalFrame(jint capacity)
{ return functions-&PushLocalFrame(this, capacity); }
jobject PopLocalFrame(jobject result)
{ return functions-&PopLocalFrame(this, result); }
jobject NewGlobalRef(jobject obj)
{ return functions-&NewGlobalRef(this, obj); }
void DeleteGlobalRef(jobject globalRef)
{ functions-&DeleteGlobalRef(this, globalRef); }
void DeleteLocalRef(jobject localRef)
{ functions-&DeleteLocalRef(this, localRef); }
jboolean IsSameObject(jobject ref1, jobject ref2)
{ return functions-&IsSameObject(this, ref1, ref2); }
jobject NewLocalRef(jobject ref)
{ return functions-&NewLocalRef(this, ref); }
jint EnsureLocalCapacity(jint capacity)
{ return functions-&EnsureLocalCapacity(this, capacity); }
jobject AllocObject(jclass clazz)
{ return functions-&AllocObject(this, clazz); }
jobject NewObject(jclass clazz, jmethodID methodID, ...)
va_start(args, methodID);
jobject result = functions-&NewObjectV(this, clazz, methodID, args);
va_end(args);
jobject NewObjectV(jclass clazz, jmethodID methodID, va_list args)
{ return functions-&NewObjectV(this, clazz, methodID, args); }
jobject NewObjectA(jclass clazz, jmethodID methodID, jvalue* args)
{ return functions-&NewObjectA(this, clazz, methodID, args); }
jclass GetObjectClass(jobject obj)
{ return functions-&GetObjectClass(this, obj); }
jboolean IsInstanceOf(jobject obj, jclass clazz)
{ return functions-&IsInstanceOf(this, obj, clazz); }
jmethodID GetMethodID(jclass clazz, const char* name, const char* sig)
{ return functions-&GetMethodID(this, clazz, name, sig); }
#define CALL_TYPE_METHOD(_jtype, _jname)
_jtype Call##_jname##Method(jobject obj, jmethodID methodID, ...)
va_start(args, methodID);
result = functions-&Call##_jname##MethodV(this, obj, methodID,
va_end(args);
#define CALL_TYPE_METHODV(_jtype, _jname)
_jtype Call##_jname##MethodV(jobject obj, jmethodID methodID,
va_list args)
{ return functions-&Call##_jname##MethodV(this, obj, methodID, args); }
#define CALL_TYPE_METHODA(_jtype, _jname)
_jtype Call##_jname##MethodA(jobject obj, jmethodID methodID,
jvalue* args)
{ return functions-&Call##_jname##MethodA(this, obj, methodID, args); }
#define CALL_TYPE(_jtype, _jname)
CALL_TYPE_METHOD(_jtype, _jname)
CALL_TYPE_METHODV(_jtype, _jname)
CALL_TYPE_METHODA(_jtype, _jname)
CALL_TYPE(jobject, Object)
CALL_TYPE(jboolean, Boolean)
CALL_TYPE(jbyte, Byte)
CALL_TYPE(jchar, Char)
CALL_TYPE(jshort, Short)
CALL_TYPE(jint, Int)
CALL_TYPE(jlong, Long)
CALL_TYPE(jfloat, Float)
CALL_TYPE(jdouble, Double)
void CallVoidMethod(jobject obj, jmethodID methodID, ...)
va_start(args, methodID);
functions-&CallVoidMethodV(this, obj, methodID, args);
va_end(args);
void CallVoidMethodV(jobject obj, jmethodID methodID, va_list args)
{ functions-&CallVoidMethodV(this, obj, methodID, args); }
void CallVoidMethodA(jobject obj, jmethodID methodID, jvalue* args)
{ functions-&CallVoidMethodA(this, obj, methodID, args); }
#define CALL_NONVIRT_TYPE_METHOD(_jtype, _jname)
_jtype CallNonvirtual##_jname##Method(jobject obj, jclass clazz,
jmethodID methodID, ...)
va_start(args, methodID);
result = functions-&CallNonvirtual##_jname##MethodV(this, obj,
clazz, methodID, args);
va_end(args);
#define CALL_NONVIRT_TYPE_METHODV(_jtype, _jname)
_jtype CallNonvirtual##_jname##MethodV(jobject obj, jclass clazz,
jmethodID methodID, va_list args)
{ return functions-&CallNonvirtual##_jname##MethodV(this, obj, clazz,
methodID, args); }
#define CALL_NONVIRT_TYPE_METHODA(_jtype, _jname)
_jtype CallNonvirtual##_jname##MethodA(jobject obj, jclass clazz,
jmethodID methodID, jvalue* args)
{ return functions-&CallNonvirtual##_jname##MethodA(this, obj, clazz,
methodID, args); }
#define CALL_NONVIRT_TYPE(_jtype, _jname)
CALL_NONVIRT_TYPE_METHOD(_jtype, _jname)
CALL_NONVIRT_TYPE_METHODV(_jtype, _jname)
CALL_NONVIRT_TYPE_METHODA(_jtype, _jname)
CALL_NONVIRT_TYPE(jobject, Object)
CALL_NONVIRT_TYPE(jboolean, Boolean)
CALL_NONVIRT_TYPE(jbyte, Byte)
CALL_NONVIRT_TYPE(jchar, Char)
CALL_NONVIRT_TYPE(jshort, Short)
CALL_NONVIRT_TYPE(jint, Int)
CALL_NONVIRT_TYPE(jlong, Long)
CALL_NONVIRT_TYPE(jfloat, Float)
CALL_NONVIRT_TYPE(jdouble, Double)
void CallNonvirtualVoidMethod(jobject obj, jclass clazz,
jmethodID methodID, ...)
va_start(args, methodID);
functions-&CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args);
va_end(args);
void CallNonvirtualVoidMethodV(jobject obj, jclass clazz,
jmethodID methodID, va_list args)
{ functions-&CallNonvirtualVoidMethodV(this, obj, clazz, methodID, args); }
void CallNonvirtualVoidMethodA(jobject obj, jclass clazz,
jmethodID methodID, jvalue* args)
{ functions-&CallNonvirtualVoidMethodA(this, obj, clazz, methodID, args); }
jfieldID GetFieldID(jclass clazz, const char* name, const char* sig)
{ return functions-&GetFieldID(this, clazz, name, sig); }
jobject GetObjectField(jobject obj, jfieldID fieldID)
{ return functions-&GetObjectField(this, obj, fieldID); }
jboolean GetBooleanField(jobject obj, jfieldID fieldID)
{ return functions-&GetBooleanField(this, obj, fieldID); }
jbyte GetByteField(jobject obj, jfieldID fieldID)
{ return functions-&GetByteField(this, obj, fieldID); }
jchar GetCharField(jobject obj, jfieldID fieldID)
{ return functions-&GetCharField(this, obj, fieldID); }
jshort GetShortField(jobject obj, jfieldID fieldID)
{ return functions-&GetShortField(this, obj, fieldID); }
jint GetIntField(jobject obj, jfieldID fieldID)
{ return functions-&GetIntField(this, obj, fieldID); }
jlong GetLongField(jobject obj, jfieldID fieldID)
{ return functions-&GetLongField(this, obj, fieldID); }
jfloat GetFloatField(jobject obj, jfieldID fieldID)
{ return functions-&GetFloatField(this, obj, fieldID); }
jdouble GetDoubleField(jobject obj, jfieldID fieldID)
{ return functions-&GetDoubleField(this, obj, fieldID); }
void SetObjectField(jobject obj, jfieldID fieldID, jobject value)
{ functions-&SetObjectField(this, obj, fieldID, value); }
void SetBooleanField(jobject obj, jfieldID fieldID, jboolean value)
{ functions-&SetBooleanField(this, obj, fieldID, value); }
void SetByteField(jobject obj, jfieldID fieldID, jbyte value)
{ functions-&SetByteField(this, obj, fieldID, value); }
void SetCharField(jobject obj, jfieldID fieldID, jchar value)
{ functions-&SetCharField(this, obj, fieldID, value); }
void SetShortField(jobject obj, jfieldID fieldID, jshort value)
{ functions-&SetShortField(this, obj, fieldID, value); }
void SetIntField(jobject obj, jfieldID fieldID, jint value)
{ functions-&SetIntField(this, obj, fieldID, value); }
void SetLongField(jobject obj, jfieldID fieldID, jlong value)
{ functions-&SetLongField(this, obj, fieldID, value); }
void SetFloatField(jobject obj, jfieldID fieldID, jfloat value)
{ functions-&SetFloatField(this, obj, fieldID, value); }
void SetDoubleField(jobject obj, jfieldID fieldID, jdouble value)
{ functions-&SetDoubleField(this, obj, fieldID, value); }
jmethodID GetStaticMethodID(jclass clazz, const char* name, const char* sig)
{ return functions-&GetStaticMethodID(this, clazz, name, sig); }
#define CALL_STATIC_TYPE_METHOD(_jtype, _jname)
_jtype CallStatic##_jname##Method(jclass clazz, jmethodID methodID,
va_start(args, methodID);
result = functions-&CallStatic##_jname##MethodV(this, clazz,
methodID, args);
va_end(args);
#define CALL_STATIC_TYPE_METHODV(_jtype, _jname)
_jtype CallStatic##_jname##MethodV(jclass clazz, jmethodID methodID,
va_list args)
{ return functions-&CallStatic##_jname##MethodV(this, clazz, methodID,
#define CALL_STATIC_TYPE_METHODA(_jtype, _jname)
_jtype CallStatic##_jname##MethodA(jclass clazz, jmethodID methodID,
jvalue* args)
{ return functions-&CallStatic##_jname##MethodA(this, clazz, methodID,
#define CALL_STATIC_TYPE(_jtype, _jname)
CALL_STATIC_TYPE_METHOD(_jtype, _jname)
CALL_STATIC_TYPE_METHODV(_jtype, _jname)
CALL_STATIC_TYPE_METHODA(_jtype, _jname)
CALL_STATIC_TYPE(jobject, Object)
CALL_STATIC_TYPE(jboolean, Boolean)
CALL_STATIC_TYPE(jbyte, Byte)
CALL_STATIC_TYPE(jchar, Char)
CALL_STATIC_TYPE(jshort, Short)
CALL_STATIC_TYPE(jint, Int)
CALL_STATIC_TYPE(jlong, Long)
CALL_STATIC_TYPE(jfloat, Float)
CALL_STATIC_TYPE(jdouble, Double)
void CallStaticVoidMethod(jclass clazz, jmethodID methodID, ...)
va_start(args, methodID);
functions-&CallStaticVoidMethodV(this, clazz, methodID, args);
va_end(args);
void CallStaticVoidMethodV(jclass clazz, jmethodID methodID, va_list args)
{ functions-&CallStaticVoidMethodV(this, clazz, methodID, args); }
void CallStaticVoidMethodA(jclass clazz, jmethodID methodID, jvalue* args)
{ functions-&CallStaticVoidMethodA(this, clazz, methodID, args); }
jfieldID GetStaticFieldID(jclass clazz, const char* name, const char* sig)
{ return functions-&GetStaticFieldID(this, clazz, name, sig); }
jobject GetStaticObjectField(jclass clazz, jfieldID fieldID)
{ return functions-&GetStaticObjectField(this, clazz, fieldID); }
jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID)
{ return functions-&GetStaticBooleanField(this, clazz, fieldID); }
jbyte GetStaticByteField(jclass clazz, jfieldID fieldID)
{ return functions-&GetStaticByteField(this, clazz, fieldID); }
jchar GetStaticCharField(jclass clazz, jfieldID fieldID)
{ return functions-&GetStaticCharField(this, clazz, fieldID); }
jshort GetStaticShortField(jclass clazz, jfieldID fieldID)
{ return functions-&GetStaticShortField(this, clazz, fieldID); }
jint GetStaticIntField(jclass clazz, jfieldID fieldID)
{ return functions-&GetStaticIntField(this, clazz, fieldID); }
jlong GetStaticLongField(jclass clazz, jfieldID fieldID)
{ return functions-&GetStaticLongField(this, clazz, fieldID); }
jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID)
{ return functions-&GetStaticFloatField(this, clazz, fieldID); }
jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID)
{ return functions-&GetStaticDoubleField(this, clazz, fieldID); }
void SetStaticObjectField(jclass clazz, jfieldID fieldID, jobject value)
{ functions-&SetStaticObjectField(this, clazz, fieldID, value); }
void SetStaticBooleanField(jclass clazz, jfieldID fieldID, jboolean value)
{ functions-&SetStaticBooleanField(this, clazz, fieldID, value); }
void SetStaticByteField(jclass clazz, jfieldID fieldID, jbyte value)
{ functions-&SetStaticByteField(this, clazz, fieldID, value); }
void SetStaticCharField(jclass clazz, jfieldID fieldID, jchar value)
{ functions-&SetStaticCharField(this, clazz, fieldID, value); }
void SetStaticShortField(jclass clazz, jfieldID fieldID, jshort value)
{ functions-&SetStaticShortField(this, clazz, fieldID, value); }
void SetStaticIntField(jclass clazz, jfieldID fieldID, jint value)
{ functions-&SetStaticIntField(this, clazz, fieldID, value); }
void SetStaticLongField(jclass clazz, jfieldID fieldID, jlong value)
{ functions-&SetStaticLongField(this, clazz, fieldID, value); }
void SetStaticFloatField(jclass clazz, jfieldID fieldID, jfloat value)
{ functions-&SetStaticFloatField(this, clazz, fieldID, value); }
void SetStaticDoubleField(jclass clazz, jfieldID fieldID, jdouble value)
{ functions-&SetStaticDoubleField(this, clazz, fieldID, value); }
jstring NewString(const jchar* unicodeChars, jsize len)
{ return functions-&NewString(this, unicodeChars, len); }
jsize GetStringLength(jstring string)
{ return functions-&GetStringLength(this, string); }
const jchar* GetStringChars(jstring string, jboolean* isCopy)
{ return functions-&GetStringChars(this, string, isCopy); }
void ReleaseStringChars(jstring string, const jchar* chars)
{ functions-&ReleaseStringChars(this, string, chars); }
jstring NewStringUTF(const char* bytes)
{ return functions-&NewStringUTF(this, bytes); }
jsize GetStringUTFLength(jstring string)
{ return functions-&GetStringUTFLength(this, string); }
const char* GetStringUTFChars(jstring string, jboolean* isCopy)
{ return functions-&GetStringUTFChars(this, string, isCopy); }
void ReleaseStringUTFChars(jstring string, const char* utf)
{ functions-&ReleaseStringUTFChars(this, string, utf); }
jsize GetArrayLength(jarray array)
{ return functions-&GetArrayLength(this, array); }
jobjectArray NewObjectArray(jsize length, jclass elementClass,
jobject initialElement)
{ return functions-&NewObjectArray(this, length, elementClass,
initialElement); }
jobject GetObjectArrayElement(jobjectArray array, jsize index)
{ return functions-&GetObjectArrayElement(this, array, index); }
void SetObjectArrayElement(jobjectArray array, jsize index, jobject value)
{ functions-&SetObjectArrayElement(this, array, index, value); }
jbooleanArray NewBooleanArray(jsize length)
{ return functions-&NewBooleanArray(this, length); }
jbyteArray NewByteArray(jsize length)
{ return functions-&NewByteArray(this, length); }
jcharArray NewCharArray(jsize length)
{ return functions-&NewCharArray(this, length); }
jshortArray NewShortArray(jsize length)
{ return functions-&NewShortArray(this, length); }
jintArray NewIntArray(jsize length)
{ return functions-&NewIntArray(this, length); }
jlongArray NewLongArray(jsize length)
{ return functions-&NewLongArray(this, length); }
jfloatArray NewFloatArray(jsize length)
{ return functions-&NewFloatArray(this, length); }
jdoubleArray NewDoubleArray(jsize length)
{ return functions-&NewDoubleArray(this, length); }
jboolean* GetBooleanArrayElements(jbooleanArray array, jboolean* isCopy)
{ return functions-&GetBooleanArrayElements(this, array, isCopy); }
jbyte* GetByteArrayElements(jbyteArray array, jboolean* isCopy)
{ return functions-&GetByteArrayElements(this, array, isCopy); }
jchar* GetCharArrayElements(jcharArray array, jboolean* isCopy)
{ return functions-&GetCharArrayElements(this, array, isCopy); }
jshort* GetShortArrayElements(jshortArray array, jboolean* isCopy)
{ return functions-&GetShortArrayElements(this, array, isCopy); }
jint* GetIntArrayElements(jintArray array, jboolean* isCopy)
{ return functions-&GetIntArrayElements(this, array, isCopy); }
jlong* GetLongArrayElements(jlongArray array, jboolean* isCopy)
{ return functions-&GetLongArrayElements(this, array, isCopy); }
jfloat* GetFloatArrayElements(jfloatArray array, jboolean* isCopy)
{ return functions-&GetFloatArrayElements(this, array, isCopy); }
jdouble* GetDoubleArrayElements(jdoubleArray array, jboolean* isCopy)
{ return functions-&GetDoubleArrayElements(this, array, isCopy); }
void ReleaseBooleanArrayElements(jbooleanArray array, jboolean* elems,
jint mode)
{ functions-&ReleaseBooleanArrayElements(this, array, elems, mode); }
void ReleaseByteArrayElements(jbyteArray array, jbyte* elems,
jint mode)
{ functions-&ReleaseByteArrayElements(this, array, elems, mode); }
void ReleaseCharArrayElements(jcharArray array, jchar* elems,
jint mode)
{ functions-&ReleaseCharArrayElements(this, array, elems, mode); }
void ReleaseShortArrayElements(jshortArray array, jshort* elems,
jint mode)
{ functions-&ReleaseShortArrayElements(this, array, elems, mode); }
void ReleaseIntArrayElements(jintArray array, jint* elems,
jint mode)
{ functions-&ReleaseIntArrayElements(this, array, elems, mode); }
void ReleaseLongArrayElements(jlongArray array, jlong* elems,
jint mode)
{ functions-&ReleaseLongArrayElements(this, array, elems, mode); }
void ReleaseFloatArrayElements(jfloatArray array, jfloat* elems,
jint mode)
{ functions-&ReleaseFloatArrayElements(this, array, elems, mode); }
void ReleaseDoubleArrayElements(jdoubleArray array, jdouble* elems,
jint mode)
{ functions-&ReleaseDoubleArrayElements(this, array, elems, mode); }
void GetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len,
jboolean* buf)
{ functions-&GetBooleanArrayRegion(this, array, start, len, buf); }
void GetByteArrayRegion(jbyteArray array, jsize start, jsize len,
jbyte* buf)
{ functions-&GetByteArrayRegion(this, array, start, len, buf); }
void GetCharArrayRegion(jcharArray array, jsize start, jsize len,
jchar* buf)
{ functions-&GetCharArrayRegion(this, array, start, len, buf); }
void GetShortArrayRegion(jshortArray array, jsize start, jsize len,
jshort* buf)
{ functions-&GetShortArrayRegion(this, array, start, len, buf); }
void GetIntArrayRegion(jintArray array, jsize start, jsize len,
jint* buf)
{ functions-&GetIntArrayRegion(this, array, start, len, buf); }
void GetLongArrayRegion(jlongArray array, jsize start, jsize len,
jlong* buf)
{ functions-&GetLongArrayRegion(this, array, start, len, buf); }
void GetFloatArrayRegion(jfloatArray array, jsize start, jsize len,
jfloat* buf)
{ functions-&GetFloatArrayRegion(this, array, start, len, buf); }
void GetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len,
jdouble* buf)
{ functions-&GetDoubleArrayRegion(this, array, start, len, buf); }
void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len,
const jboolean* buf)
{ functions-&SetBooleanArrayRegion(this, array, start, len, buf); }
void SetByteArrayRegion(jbyteArray array, jsize start, jsize len,
const jbyte* buf)
{ functions-&SetByteArrayRegion(this, array, start, len, buf); }
void SetCharArrayRegion(jcharArray array, jsize start, jsize len,
const jchar* buf)
{ functions-&SetCharArrayRegion(this, array, start, len, buf); }
void SetShortArrayRegion(jshortArray array, jsize start, jsize len,
const jshort* buf)
{ functions-&SetShortArrayRegion(this, array, start, len, buf); }
void SetIntArrayRegion(jintArray array, jsize start, jsize len,
const jint* buf)
{ functions-&SetIntArrayRegion(this, array, start, len, buf); }
void SetLongArrayRegion(jlongArray array, jsize start, jsize len,
const jlong* buf)
{ functions-&SetLongArrayRegion(this, array, start, len, buf); }
void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len,
const jfloat* buf)
{ functions-&SetFloatArrayRegion(this, array, start, len, buf); }
void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len,
const jdouble* buf)
{ functions-&SetDoubleArrayRegion(this, array, start, len, buf); }
jint RegisterNatives(jclass clazz, const JNINativeMethod* methods,
jint nMethods)
{ return functions-&RegisterNatives(this, clazz, methods, nMethods); }
jint UnregisterNatives(jclass clazz)
{ return functions-&UnregisterNatives(this, clazz); }
jint MonitorEnter(jobject obj)
{ return functions-&MonitorEnter(this, obj); }
jint MonitorExit(jobject obj)
{ return functions-&MonitorExit(this, obj); }
jint GetJavaVM(JavaVM** vm)
{ return functions-&GetJavaVM(this, vm); }
void GetStringRegion(jstring str, jsize start, jsize len, jchar* buf)
{ functions-&GetStringRegion(this, str, start, len, buf); }
void GetStringUTFRegion(jstring str, jsize start, jsize len, char* buf)
{ return functions-&GetStringUTFRegion(this, str, start, len, buf); }
void* GetPrimitiveArrayCritical(jarray array, jboolean* isCopy)
{ return functions-&GetPrimitiveArrayCritical(this, array, isCopy); }
void ReleasePrimitiveArrayCritical(jarray array, void* carray, jint mode)
{ functions-&ReleasePrimitiveArrayCritical(this, array, carray, mode); }
const jchar* GetStringCritical(jstring string, jboolean* isCopy)
{ return functions-&GetStringCritical(this, string, isCopy); }
void ReleaseStringCritical(jstring string, const jchar* carray)
{ functions-&ReleaseStringCritical(this, string, carray); }
jweak NewWeakGlobalRef(jobject obj)
{ return functions-&NewWeakGlobalRef(this, obj); }
void DeleteWeakGlobalRef(jweak obj)
{ functions-&DeleteWeakGlobalRef(this, obj); }
jboolean ExceptionCheck()
{ return functions-&ExceptionCheck(this); }
jobject NewDirectByteBuffer(void* address, jlong capacity)
{ return functions-&NewDirectByteBuffer(this, address, capacity); }
void* GetDirectBufferAddress(jobject buf)
{ return functions-&GetDirectBufferAddress(this, buf); }
jlong GetDirectBufferCapacity(jobject buf)
{ return functions-&GetDirectBufferCapacity(this, buf); }
/* added in JNI 1.6 */
jobjectRefType GetObjectRefType(jobject obj)
{ return functions-&GetObjectRefType(this, obj); }
#endif /*__cplusplus*/
* JNI invocation interface.
struct JNIInvokeInterface {
reserved0;
reserved1;
reserved2;
(*DestroyJavaVM)(JavaVM*);
(*AttachCurrentThread)(JavaVM*, JNIEnv**, void*);
(*DetachCurrentThread)(JavaVM*);
(*GetEnv)(JavaVM*, void**, jint);
(*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*);
* C++ version.
struct _JavaVM {
const struct JNIInvokeInterface*
#if defined(__cplusplus)
jint DestroyJavaVM()
{ return functions-&DestroyJavaVM(this); }
jint AttachCurrentThread(JNIEnv** p_env, void* thr_args)
{ return functions-&AttachCurrentThread(this, p_env, thr_args); }
jint DetachCurrentThread()
{ return functions-&DetachCurrentThread(this); }
jint GetEnv(void** env, jint version)
{ return functions-&GetEnv(this, env, version); }
jint AttachCurrentThreadAsDaemon(JNIEnv** p_env, void* thr_args)
{ return functions-&AttachCurrentThreadAsDaemon(this, p_env, thr_args); }
#endif /*__cplusplus*/
struct JavaVMAttachArgs {
/* must be &= JNI_VERSION_1_2 */
const char*
/* NULL or name of thread as modified UTF-8 str */
/* global ref of a ThreadGroup object, or NULL */
typedef struct JavaVMAttachArgs JavaVMAttachA
* JNI 1.2+ initialization.
(As of 1.6, the pre-1.2 structures are no
* longer supported.)
typedef struct JavaVMOption {
const char* optionS
typedef struct JavaVMInitArgs {
/* use JNI_VERSION_1_2 or later */
JavaVMOption*
} JavaVMInitA
#ifdef __cplusplus
extern "C" {
* VM initialization functions.
* Note these are the only symbols exported for JNI by the VM.
jint JNI_GetDefaultJavaVMInitArgs(void*);
jint JNI_CreateJavaVM(JavaVM**, JNIEnv**, void*);
jint JNI_GetCreatedJavaVMs(JavaVM**, jsize, jsize*);
* Prototypes for functions exported by loadable shared libs.
* called by JNI, not provided by JNI.
jint JNI_OnLoad(JavaVM* vm, void* reserved);
void JNI_OnUnload(JavaVM* vm, void* reserved);
#ifdef __cplusplus
* Manifest constants.
#define JNI_FALSE
#define JNI_TRUE
#define JNI_VERSION_1_1 0x
#define JNI_VERSION_1_2 0x
#define JNI_VERSION_1_4 0x
#define JNI_VERSION_1_6 0x
#define JNI_OK
/* no error */
#define JNI_ERR
/* generic error */
#define JNI_EDETACHED
/* thread detached from the VM */
#define JNI_EVERSION
/* JNI version error */
#define JNI_COMMIT
/* copy content, do not free buffer */
#define JNI_ABORT
/* free buffer w/o copying back */
/* need these for Windows-aware headers */
#define JNIIMPORT
#define JNIEXPORT
#define JNICALL
#endif /*_JNI_H*/
然后可以使用其中的结构体了。
有人曾搞成excel但是不知道地址了,临时下载,当时看到下来看是不能传出去的。
&原文链接:
阅读排行榜}

我要回帖

更多关于 android uri.fromfile 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信