博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android NDK JNI C++ <7> eg
阅读量:6405 次
发布时间:2019-06-23

本文共 4758 字,大约阅读时间需要 15 分钟。

刚开始一直没有找到该系列的第五篇博客,郁闷的要死,本打算重写的,看来没必要了.那这一篇就相当于小结第五篇和第六篇使用的样例.

所有的NDK都是在Linux系统下开发的,jni C或者CPP文件这一篇开始是在windosws7 VC6.0中开发的.所以下面的新建Android项目之类的都是在我的Ubuntu12.04中进行的.

<1> : 首先新建一个Android工程androidjnicppdemo1,包名package com.org.androidjnicppdemo1;

<2> : 在工程下新建一个jnipack的包,在这个包下新建一个JniClass.java的文件,build后(一定要先生成class文件),在工程根目录下新建一个jni,让后让终端进入jni文件目录下执行:

javah -classpath ../bin/classes jnipack.JniClass

把生成的jnipack_JniClass.h名改为JniClass.h,不要包名.

<3> : 上面的操作和以前的没什么区别.让后启动VC6.0,VC6.0耗内存非常少,所以这个很快捷.新建一个console工程就可以了,然后新建一个JniClass.h的头文件和JniClass.cpp文件,将上面生成的JniClass.h文件内容拷贝VC同名下的文件中,然后具体实现在JniClass.cpp文件中实现.

截图如下:

JniClass.c代码如下:

#include "JniClass.h"jclass mClass;jobject mObject;jmethodID mMethodID;jmethodID mMethodAddID;jfieldID mFieldID;JNIEXPORT void JNICALL Java_jnipack_JniClass_nativeinit(JNIEnv *env, jobject thiz){    jclass cls=(*env)->GetObjectClass(env,thiz);    mClass=(jclass)(*env)->NewGlobalRef(env,cls);//    mClass=(jclass)(*env)->FindClass(env,"jnipack.JniClass");    mObject=(jobject)(*env)->NewGlobalRef(env,thiz);    mFieldID=(*env)->GetFieldID(env,mClass,"native_para","I");    mMethodID=(*env)->GetMethodID(env,mClass,"SubJava","(II)I");    mMethodAddID=(*env)->GetMethodID(env,mClass,"AddJava","(II)I");}JNIEXPORT jint JNICALL Java_jnipack_JniClass_Add(JNIEnv *env, jobject thiz, jint a, jint b){    jint res=0;    jint para=0;    para=(jint)(*env)->GetIntField(env,mObject,mFieldID);    res=(*env)->CallIntMethod(env,mObject,mMethodAddID,a,(b+para));    return res;}JNIEXPORT jstring JNICALL Java_jnipack_JniClass_getLibVersion(JNIEnv *env, jobject thiz){        return (*env)->NewStringUTF(env,"jnilibs : 1.0");    }

 补充上面的内容,传递数组的方法j*array,*代表int等数据类型:

java代码增加:

public native int AddArray(int[] arr);

Jni实现代码中:

JNIEXPORT jint JNICALL Java_jnipack_JniClass_AddArray(JNIEnv *env, jobject thiz,        jintArray arr) {    jint len = 5;    jint i = 0;    jint res = 0;    jint *arri;    arri = (*env)->GetIntArrayElements(env, arr, 0);    for (i = 0; i < 5; i++) {        res = res + arri[i];    }    return res;}

调用:

 

<4> : 现在在上面的工程中继续添加一个CPP的程序:

plus.h:

#ifndef PLUS_HEADER_H__#define PLUS_HEADER_H__class cale{public:    cale(){};//不要添加virtual修饰符    virtual ~cale(){};    virtual int addplus(int a,int b);    virtual char* showmsg();};#endif

plus.cpp:

#include "plus.h"char* cale::showmsg(){    return "cpp program !";};int cale::addplus(int a,int b){    return a+b;};

swig.i:

%module swig%{#include "plus.h"%}%include "plus.h"

swig.sh:

#!/bin/bashswig -c++ -java -package orgcpp -outdir ../src/orgcpp -o plusplus.cpp swig.i

Android.mk:这个文件里面即有cpp又有c的文件,混合起来都可以build的,NB啊.

LOCAL_PATH :=$(call my-dir)include $(CLEAR_VARS)LOCAL_MODULE := jnilibsLOCAL_SRC_FILES := JniClass.c plusplus.cpp plus.cpp#LOCAL_CFLAGS    :=-frttiinclude $(BUILD_SHARED_LIBRARY)

<5>应该没有了,运行脚本然后build后,调用如下:

package com.org.androidjnicppdemo1;import orgcpp.cale;import jnipack.JniClass;import android.os.Bundle;import android.app.Activity;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;public class MainActivity extends Activity implements OnClickListener{    private Button mGetVerBtn;    private Button mCallNativeAddBtn;    private Button mCppBtn;        private JniClass jClass=new JniClass();    //    private cale ce=new cale();        @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);                mGetVerBtn=(Button)findViewById(R.id.getver);        mGetVerBtn.setOnClickListener(this);                mCallNativeAddBtn=(Button)findViewById(R.id.callnativeadd);        mCallNativeAddBtn.setOnClickListener(this);                mCppBtn=(Button)findViewById(R.id.cpp);        mCppBtn.setOnClickListener(this);            }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        // Inflate the menu; this adds items to the action bar if it is present.        getMenuInflater().inflate(R.menu.main, menu);        return true;    }    @Override    public void onClick(View arg0) {        // TODO Auto-generated method stub        int id;        id=arg0.getId();                switch(id){        case R.id.getver:            Toast.makeText(this, "lib : "+jClass.getLibVersion(), Toast.LENGTH_SHORT).show();            break;        case R.id.callnativeadd:            Toast.makeText(this, "native call : "+jClass.Add(16, 12), Toast.LENGTH_LONG).show();            break;        case R.id.cpp://            Toast.makeText(this, "cpp : "+ce.showmsg(), Toast.LENGTH_LONG).show();            break;        }            }}

 

综合上面:

<1> : jni回调java代码;

<2> : java调用jni的c代码;

<3> : java调用jni的c++代码;

<4> : 增加常量native_para传递和使用;

其他图片:

 

 

 

 

下一节开始jni多线程操作.

 

 

 

 

 

 

 

 

转载地址:http://ljtea.baihongyu.com/

你可能感兴趣的文章
Elementui实战知识点随记
查看>>
Oracle10g RAC 修改IP [转载]
查看>>
关于char p[] = "hello world"; char *p = "hello world";
查看>>
FIREDAC的心得
查看>>
NPOI批量导入大量数据
查看>>
了解 Windows Azure 存储计费 – 带宽、事务和容量
查看>>
mysql5.7.22 zip 版安装
查看>>
【题解】最大公约数之和 V3 51nod 1237 杜教筛
查看>>
架构师速成6.7-设计开发思路-uml 分类: 架构师速成 ...
查看>>
js设置radio选中
查看>>
8皇后以及N皇后算法探究,回溯算法的JAVA实现,非递归,数据结构“栈”实现...
查看>>
第一次发博客-说说我的B/S开发框架(asp.net mvc + web api + easyui)
查看>>
python之路之线程,进程,协程
查看>>
ZROI2018提高day3t1
查看>>
VC的水波效果
查看>>
微信支付SDK集成
查看>>
如何使用wepy和 vant-weapp开发小程序
查看>>
Angular7教程-03-Angular常用操作(上)
查看>>
洛谷 P1200 [USACO1.1]你的飞碟在这儿Your Ride Is Here
查看>>
【python】python的列表表达式或解析式,帅就一个字
查看>>