so层Java层绑定函数_动态注册
package com.example.mypc.myxphook;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private Button add;
private Button sub;
private Button mul;
private Button div;
private float oneParam;
private float twoParam;
static{
System.loadLibrary("testJni");
}
//Actity创建事件
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
go();
}
//调用go方法来计算并且给出
private void go(){
final View.OnClickListener cl = new View.OnClickListener(){
@Override
public void onClick(View v){
//获取第一个编辑框的内容
EditText e1 = (EditText) findViewById(R.id.editText);
oneParam = Float.parseFloat(e1.getText().toString());
//获取第二个参数
EditText e2 = (EditText) findViewById(R.id.editText2);
twoParam = Float.parseFloat(e2.getText().toString());
switch (v.getId()){
case R.id.button2 :
Toast.makeText(getApplicationContext(),"计算结果为:"+String.valueOf(add(oneParam,twoParam)),Toast.LENGTH_LONG).show();
break;
case R.id.button3 :
Toast.makeText(getApplicationContext(),"计算结果为:"+String.valueOf(sub(oneParam,twoParam)),Toast.LENGTH_LONG).show();
break;
case R.id.button4 :
Toast.makeText(getApplicationContext(),"计算结果为:"+String.valueOf(mul(oneParam,twoParam)),Toast.LENGTH_LONG).show();
break;
case R.id.button5 :
Toast.makeText(getApplicationContext(),"计算结果为:"+String.valueOf(div(oneParam,twoParam)),Toast.LENGTH_LONG).show();
break;
default:
Toast.makeText(getApplicationContext(),"未找到对应的执行函数...",Toast.LENGTH_LONG);
break;
}
}
};
//设置加法按钮的点击事件
add.setOnClickListener(cl);
//设置减法按钮的点击事件
sub.setOnClickListener(cl);
//设置减法按钮的点击事件
mul.setOnClickListener(cl);
//设置减法按钮的点击事件
div.setOnClickListener(cl);
}
//初始化控件
private void init(){
//绑定四个按钮
add = (Button) findViewById(R.id.button2);
sub = (Button) findViewById(R.id.button3);
mul = (Button) findViewById(R.id.button4);
div = (Button) findViewById(R.id.button5);
}
//Native层的加法
public native float add(float one,float two);
//Native层的减法
public native float sub(float one,float two);
//Native层的乘法
public native float mul(float one,float two);
//Native层的除法
public native float div(float one,float two);
}
2.xml布局代码编写如下:<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
tools:layout_editor_absoluteY="81dp">
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="+"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/button4"
app:layout_constraintStart_toStartOf="@+id/button4"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="55dp"
android:text="-"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="@+id/button2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/button2" />
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="41dp"
android:layout_marginTop="30dp"
android:text="*"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button2" />
<Button
android:id="@+id/button5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="30dp"
android:text="/"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="@+id/button3"
app:layout_constraintTop_toBottomOf="@+id/button3" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_marginTop="51dp"
android:text="第一个数:"
android:textColor="@android:color/holo_red_light"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@+id/editText"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="10dp"
android:layout_marginTop="27dp"
android:text="第二个数:"
android:textColor="@android:color/holo_red_light"
android:textStyle="bold"
app:layout_constraintEnd_toStartOf="@+id/editText2"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/editText" />
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="14dp"
android:ems="10"
android:inputType="number"
app:layout_constraintBaseline_toBaselineOf="@+id/textView"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textView" />
<EditText
android:id="@+id/editText2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="14dp"
android:ems="10"
android:inputType="number"
app:layout_constraintBaseline_toBaselineOf="@+id/textView2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textView2" />
</android.support.constraint.ConstraintLayout>
3.编写so层代码也就是C代码如下://
// Created by MyPC on 2020/4/17.
//
#include <jni.h>
//c语言实现加法,返回结果
jfloat addc(JNIEnv* env, jobject obj, jfloat one, jfloat two){
return one+two;
}
//c语言实现减法,返回结果
jfloat subc(JNIEnv* env,jobject obj, jfloat one, jfloat two){
return one-two;
}
//c语言实现乘法,返回结果
jfloat mulc(JNIEnv* env,jobject obj, jfloat one, jfloat two){
return one*two;
}
//c语言实现除法,返回结果
jfloat divc(JNIEnv* env,jobject obj, jfloat one, jfloat two){
return one/two;
}
//定义数组双向绑定c层函数名和java函数名
JNINativeMethod nativeMethod[]={
{"add","(FF)F",(void*)addc},
{"sub","(FF)F",(void*)subc},
{"mul","(FF)F",(void*)mulc},
{"div","(FF)F",(void*)divc}
};
//注册函数
jint registerNative(JNIEnv* env){
//获取java类
jclass clazz = (*env)->FindClass(env,"com/example/mypc/myxphook/MainActivity");
//动态注册函数 也可以说是绑定函数C与JAVA
jint res = (*env)->RegisterNatives(env,clazz,nativeMethod,sizeof(nativeMethod)/sizeof(nativeMethod[0]));
//判断是否注册成功
if(res != JNI_OK){
return JNI_ERR;
}
return JNI_OK;
}
//使用JNI_OnLoad函数动态注册函数
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved){
JNIEnv* env;
//获取env返回状态
jint res =(*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4);
//判断是否成功
if(res != JNI_OK){
return JNI_ERR;
}else if(registerNative(env) != JNI_OK){
return JNI_ERR;
}
//注册成功必须返回JNI版本号
return JNI_VERSION_1_4;
}
4.运行结果如下:
总结:首先编写Java层代码,定义好native函数以及返回值类型和参数,然后编写C代码,流程如下: 1.引入jni.h头文件
#include <jni.h>
2.编写对应Java层的native函数的实现//c语言实现加法,返回结果
jfloat addc(JNIEnv* env, jobject obj, jfloat one, jfloat two){
return one+two;
}
//c语言实现减法,返回结果
jfloat subc(JNIEnv* env,jobject obj, jfloat one, jfloat two){
return one-two;
}
//c语言实现乘法,返回结果
jfloat mulc(JNIEnv* env,jobject obj, jfloat one, jfloat two){
return one*two;
}
//c语言实现除法,返回结果
jfloat divc(JNIEnv* env,jobject obj, jfloat one, jfloat two){
return one/two;
}
3.定义双向绑定的数组,代码如下://定义数组双向绑定c层函数名和java函数名,第一个是java层函数名,第二个函数名签名,第三个c层的函数
JNINativeMethod nativeMethod[]={
{"add","(FF)F",(void*)addc},
{"sub","(FF)F",(void*)subc},
{"mul","(FF)F",(void*)mulc},
{"div","(FF)F",(void*)divc}
};
3.开始绑定双向函数,代码如下://注册函数
jint registerNative(JNIEnv* env){
//获取java类,传入env 和 类名
jclass clazz = (*env)->FindClass(env,"com/example/mypc/myxphook/MainActivity");
//动态注册函数 也可以说是绑定函数C与JAVA,env,class,绑定函数的数组,数组的长度
jint res = (*env)->RegisterNatives(env,clazz,nativeMethod,sizeof(nativeMethod)/sizeof(nativeMethod[0]));
//判断是否注册成功
if(res != JNI_OK){
return JNI_ERR;
}
return JNI_OK;
}
4.默认加载的JNI_Onload函数内调用注册函数,代码如下://使用JNI_OnLoad函数动态注册函数
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved){
JNIEnv* env;
//获取env返回状态
jint res =(*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4);
//判断是否成功
if(res != JNI_OK){
return JNI_ERR;
}else if(registerNative(env) != JNI_OK){//这里就调用了上面的注册方法
return JNI_ERR;
}
//注册成功必须返回JNI版本号
return JNI_VERSION_1_4;
}