在Android Studio下编写JNI(二)NDK调用java

之前介绍过了,之前创建一个基本的NDK的例子,所以下边我就直接给代码截图,总的来说假如你熟悉Java反射的话,那你理解可能回好一点,在NDK中也是使用反射去调用


使用javap打印方法签名

如果要是有javap  命令在AS中必须去该目录下才能使用,javap得到签名使用(javap -s  Activity路径,斜杠以点代替)


这是hello.c
#include <jni.h>
#include <string.h>
#include <unistd.h> // sleep 的头文件
//引入log
#include <android/log.h>

#define LOG_TAG "System.out"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__)
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)

char *JString2CStr(JNIEnv *env, jstring jstr) {
    char *str = NULL;
    jclass classStr = (*env)->FindClass(env, "java/lang/String");
    jstring strencode = (*env)->NewStringUTF(env, "GB2312");
    jmethodID mid = (*env)->GetMethodID(env, classStr, "getBytes", "(Ljava/lang/String;)[B");
    jbyteArray array = (*env)->CallObjectMethod(env, jstr, mid, strencode);
    jsize alength = (*env)->GetArrayLength(env, array);
    jbyte *byte = (*env)->GetByteArrayElements(env, array, JNI_FALSE);
    if (alength > 0) {
        str = (char *) malloc(alength + 1);// "\0"
        str[alength] = '\0';
    }
    //recycle memory
    (*env)->ReleaseByteArrayElements(env, array, byte, 0);
    return str;
}

void showJavaDialog(JNIEnv* env,jobject obj,char* msg){
//    1.获取Java虚拟机,找到class的子节码
    jclass jclazz = (*env)->FindClass(env, "com/wan/xiaofan/testndk/MainActivity");
    /**
     * jclazz 如果找到方法,返回的是一个内存地址,则大于0,反之等于0
     */
    if(jclazz==0){
        LOGD("没有找到类\n");
    }else{
        LOGD("找到类\n");
    }
    //获取字节码里的方法
    jmethodID jmethod=  (*env)->GetMethodID(env,jclazz,"showDialog","(Ljava/lang/String;)V");
    if(jmethod==0){
        LOGD("没有找到方法\n");
    }else{
        LOGD("找到方法\n");
    }
//    调用方法
    (*env)->CallVoidMethod(env,obj,jmethod,(*env)->NewStringUTF(env,msg));
}

void dismissJavaDialog(JNIEnv* env,jobject obj){
//    1.获取Java虚拟机,找到class的子节码
    jclass jclazz = (*env)->FindClass(env, "com/wan/xiaofan/testndk/MainActivity");
    /**
     * jclazz 如果找到方法,返回的是一个内存地址,则大于0,反之等于0
     */
    if(jclazz==0){
        LOGD("没有找到类\n");
    }else{
        LOGD("找到类\n");
    }
    //获取字节码里的方法
    jmethodID jmethod=  (*env)->GetMethodID(env,jclazz,"dismissDialog","()V");
    if(jmethod==0){
        LOGD("没有找到方法\n");
    }else{
        LOGD("找到方法\n");
    }
}

int safepay(JNIEnv *env, jobject obj, char *userName, char *pwd, float money, int radomCode,
            long long time) {
    LOGI("自定义的加密算法,加密userName\n");
    //通知界面,更新UI,显示对话框
    showJavaDialog(env,obj,"自定义的加密算法,加密userName");
    sleep(1);
    dismissJavaDialog(env,obj);

    LOGI("检查本地环境\n");
    showJavaDialog(env,obj,"检查本地环境");
    sleep(2);
    dismissJavaDialog(env,obj);

    LOGI("验证支付证书,扫描本地支付环境\n");
    showJavaDialog(env,obj,"验证支付证书,扫描本地支付环境");
    sleep(2);
    dismissJavaDialog(env,obj);

    LOGI("交易金额是否超过最大限度\n");
    showJavaDialog(env,obj,"交易金额是否超过最大限度");
    sleep(3);
    dismissJavaDialog(env,obj);

    LOGI("提交数据到服务器,服务器端查询数据库,检查用户名和密码是否正确,连接网银接口\n");
    showJavaDialog(env,obj,"提交数据到服务器,服务器端查询数据库,检查用户名和密码是否正确,连接网银接口");
    sleep(4);
    dismissJavaDialog(env,obj);

    char *tempName = "zhangsan";
    char *tempPwd = "123";
    if (strcmp(tempName, userName) == 0 && strcmp(tempPwd, pwd) == 0 && money < 5000) {
        return 200;
    } else {
        return 404;
    }
}
/**
 * env jvm环境的指针变化
 * obj java对象
 */
JNIEXPORT jint JNICALL Java_com_wan_xiaofan_testndk_MainActivity_safePay(JNIEnv* env, jobject obj,
                                                                jstring jusername, jstring jpwd,
                                                                jfloat jmoney, jint jradomCode,
                                                                jlong jtime) {
//username 用户名 password 密码 money 金钱 randomcode 随机码 time 时间戳
    char *name = JString2CStr(env, jusername);
    char *pwd = JString2CStr(env, jpwd);
    return safepay(env, obj, name, pwd, jmoney, jradomCode, jtime);

}

MainActivity

package com.wan.xiaofan.testndk;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
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 EditText editText_1, editText_2, editText_3;
    private Button button;
    private NDK ndk = null;
    private ProgressDialog pd;
    static {
        System.loadLibrary("mytest");
    }

    /**
     * username 用户名 password 密码 money 金钱 randomcode 随机码 time 时间戳
     */
    public native int safePay(String username, String password, float money,int randomCode, long time);


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ndk = new NDK();

        initview();

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        String userName = editText_1.getText().toString().trim();
                        String pwd = editText_2.getText().toString().trim();
                        String money = editText_3.getText().toString().trim();
                        Log.i("wxf",""+userName);
                        Log.i("wxf",""+pwd);
                        Log.i("wxf",""+money);
                        int code=safePay(userName,pwd,Float.valueOf(money),(int) (System.currentTimeMillis() % 1000),System.currentTimeMillis());
                        if(code==200){
                            showToast("支付成功");
                        }else{
                            showToast("支付失败");
                        }
                    }
                }).start();


            }
        });
    }

    private void initview() {
        button = (Button) findViewById(R.id.button);
        editText_1 = (EditText) findViewById(R.id.editText1);
        editText_2 = (EditText) findViewById(R.id.editText2);
        editText_3 = (EditText) findViewById(R.id.editText3);
    }
    /**
     * 保证代码一定在主线程运行。
     *
     * @param msg
     *            对话框的消息
     */
    public void showDialog(final String msg) {
        if ("main".equals(Thread.currentThread().getName())) {
            // 工作在主线程
            initDialog(msg);
        } else {
            // 子线程
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    initDialog(msg);
                }
            });
        }
    }
    private void initDialog(final String msg) {
        pd = new ProgressDialog(MainActivity.this);
        pd.setTitle("提醒");
        pd.setMessage(msg);
        pd.show();
    }

    /**
     * 关闭对话框的操作
     */
    public void dismissDialog() {
        if (pd != null && pd.isShowing()) {
            pd.dismiss();
        }
    }
    /**
     * 显示土司
     *
     * @param msg
     */
    public void showToast(final String msg) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG).show();
            }
        });
    }
}

xml这是

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <EditText
        android:id="@+id/editText1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:text="zhangsan"
        android:hint="用户名默认zhangsan"
        android:inputType="textPersonName" />

    <EditText
        android:id="@+id/editText2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:text="123"
        android:hint="密码默认123"
        android:inputType="textPersonName" />

    <EditText
        android:id="@+id/editText3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:ems="10"
        android:text="2000.2"
        android:hint="金额,单次不能超过5000"
        android:inputType="textPersonName" />

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="提交" />

</LinearLayout>


如果提示



在mk文件中加入



注意:

1、如果使用javap -s 在Activity中有该方法,而在签名中没有,运行一下项目即可,应该事文件还未过去

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值