android JNI学习六

这次尝试 jni 回调中传递自定义类对象和初始化该对象并写入内容,也就是说,在 java 里没有初始化对象,而是在 C或C++ 里才初始化并写入数据,然后传递到 java 里使用。这个可以用于底层获取数据后发送到上层的。

以 android JNI学习五的代码为基础,在 android 工程里 src 文件下就已经有 jData 类

public class jData {
public int      pixelFormat;
public int      iHeightPixels;          // Image dimension height
    public int      iWidthPixels;           // Image dimension width
public byte     pImage[];               // Pointer to the Image array.
}

这次只对第一个成员 pixelFormat 写入内容。

MainActivity.java 修改如下:

package com.example.jnicall;

import java.nio.ByteBuffer;
import android.os.Bundle;
import android.app.Activity;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button mb1;
mb1 = (Button)findViewById(R.id.button1);
mb1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
add(1,2);
}
});
}

static {
System.load("/system/jni/libjnicall.so");
}
public native int add(int add1, int add2);

public void answerjnicallback(jData jdata)
{
Log.d("jni_call","APK -- answerjnicallback -- jdata.pixelFormat = "+jdata.pixelFormat );
}
}

修改 answerjnicallback 方法添加一个 jData 参数 jdata,方法里就用 logcat 输出传进来的 jdata 里的成员 pixelFormat 的值。

jni_call.cpp 文件修改如下:

#include "tools.h"
#include <jni.h>
#include "JNIHelp.h"
#include <android/log.h>
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, "jni_call", __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_DEBUG, "jni_call", __VA_ARGS__)
#define JNI_IT_OBJ_PATH "com/example/jnicall/jData"

#ifdef __cplusplus
extern "C" {
#endif
void callback(JNIEnv* env, jobject thiz)
{
LOGD("callback -- begin");
jclass cls = NULL;
jclass jDcls = NULL;
jmethodID mid = NULL;
jmethodID jDmid = NULL;
jobject jDataObj;
jfieldID fid;
jfieldID jDfid;
if((jDcls = env->FindClass(JNI_IT_OBJ_PATH)) == NULL)
    {
        return ;
    }
if((jDmid = env->GetMethodID(jDcls, "<init>", "()V")) == NULL)
    {
        return ;
    }
if((jDataObj = env->NewObject(jDcls, jDmid)) == NULL)
    {
        return ;
    }
if((jDcls = env->GetObjectClass(jDataObj)) == NULL)
{
return ;
}
if((jDfid = env->GetFieldID(jDcls, "pixelFormat", "I")) == NULL)
    {
return ;
    }
    env->SetIntField(jDataObj, jDfid, 1);
if((cls = env->GetObjectClass(thiz)) == NULL)
    {
        return ;
    }
if((mid = env->GetMethodID(cls, "answerjnicallback", "(Lcom/example/jnicall/jData;)V")) == NULL)
    {
        return ;
    }
env->CallVoidMethod(thiz, mid, jDataObj);
LOGD("callback -- end");
    return ;
}

jint Java_com_example_jnicall_MainActivity_add(JNIEnv* env, jobject thiz, jint add1, jint add2){
LOGD("add = %d",add(add1, add2));
callback(env,thiz);
    return add(add1, add2);
}
#ifdef __cplusplus
} // extern "C"
#endif

JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
    JNIEnv *env;
if ( (vm->GetEnv( (void**) &env, JNI_VERSION_1_4)) != JNI_OK) {
return -1;
}
    return JNI_VERSION_1_4;
}
主要修改 callback 函数,增加类对象的创建和写入。

先定义 java 里类名:

#define JNI_IT_OBJ_PATH "com/example/jnicall/jData"

(jDcls = env->FindClass(JNI_IT_OBJ_PATH) 获取这个类的 class,(jDmid = env->GetMethodID(jDcls, "<init>", "()V")) 再获取 jmethodID,注意第二个参数是 <init>,这个类对象不是从 java 创建传下来的(个人观点)。jDataObj = env->NewObject(jDcls, jDmid) 就是初始化创建这个对象,函数 NewObject 。下面就是写入数据,可参考前面的 jni 例子。

(mid = env->GetMethodID(cls, "answerjnicallback", "(Lcom/example/jnicall/jData;)V") 获得 java 里的函数 ID 时,第三个参数中扩后内就是报名加类名的规则。可参考以前 JNINativeMethod 的说明。

运行 apk,打印 logcat 输出结果如下:

D/jni_call( 1875): add = 3
D/jni_call( 1875): callback -- begin
D/jni_call( 1875): APK -- answerjnicallback -- jdata.pixelFormat = 1
D/jni_call( 1875): callback -- end

说明实验成功。


工程代码下载:http://download.csdn.net/detail/u013820413/7001033

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值