美文网首页NDK/JNIAndroid-NDK/JNI
JNI/NDK编程(三)——C 调用 Java 成员变量

JNI/NDK编程(三)——C 调用 Java 成员变量

作者: 27efec53a72d | 来源:发表于2018-03-22 13:51 被阅读77次

    本文源码:https://github.com/jt1024/JNIBasicForAndroid

    环境

    1.Android Studio 3.0
    2.gradle-4.1-all
    3.android sdk 26

    一、在Android Studio 新建安卓工程

    二、基本配置

    参照:
    JNI/NDK编程(一)——无参函数之Hello world !JNI/NDK编程(二)——带参函数之模拟登录

    三、编写代码

    1.编写C++文件 login_lib.cpp
    路径:NDKThirdDemo/app/src/main/cpp/login_lib.cpp

    #include <jni.h>
    #include "string.h"
    
    extern "C" JNIEXPORT jstring JNICALL
    Java_com_tao_ndkthirddemo_Java2CLogin_login(JNIEnv *env, jobject instance, jstring username, jstring password, jint authcode) {
        jclass jclazz;
    
        //1.加载java类得到class对象
        jclazz = env->FindClass("com/tao/ndkthirddemo/Java2CLogin");
    
        //2.获取java类成员变量
        //2.1 获取java类成员变量ID
        jfieldID codeErrorID = env->GetFieldID(jclazz, "codeError", "Ljava/lang/String;");
        jfieldID usernameOrPasswordErrorID = env->GetFieldID(jclazz, "usernameOrPasswordError", "Ljava/lang/String;");
        jfieldID loginSuccessErrorID = env->GetStaticFieldID(jclazz, "loginSuccess", "Ljava/lang/String;");
        //2.2 通过成员变量ID获取java类成员变量
        jstring jcodeError = (jstring) env->GetObjectField(instance, codeErrorID);
        jstring jusernameOrPasswordError = (jstring) env->GetObjectField(instance, usernameOrPasswordErrorID);
        jstring jloginSuccess = (jstring) env->GetStaticObjectField(jclazz, loginSuccessErrorID);
        //return jloginSuccess;
    
        //3.验证
        if (authcode == 888) {
            const char *cStr;
            const char *pStr;
            jboolean isCopy;
            cStr = env->GetStringUTFChars(username, &isCopy);
            pStr = env->GetStringUTFChars(password, &isCopy);
            int reUsername = strcmp(cStr, "admin");
            int rePassword = strcmp(pStr, "1234");
            if (reUsername == 0 && rePassword == 0) {
                return jloginSuccess;
            } else {
                return jusernameOrPasswordError;
            }
        } else {
            return jcodeError;
        }
    }
    

    2.编写Jave文件 Java2CLogin
    路径:NDKThirdDemo/app/src/main/java/com.tao.ndkthirddemo.Java2CLogin

    package com.tao.ndkthirddemo;
    
    /**
     * 作者: 麦典威
     * 修改时间:2018/3/15 8:07
     * 版权声明:www.ekwing.com
     * 功能: ${TODO}
     */
    
    
    public class Java2CLogin {
    
        private String codeError = "验证码错误!";
        private String usernameOrPasswordError = "用户名或密码错误!";
        private static String loginSuccess = "登录成功!";
    
        static {
            System.loadLibrary("login_lib");
        }
    
        /**
         * 带参数的 native 函数
         *
         * @param username 用户名
         * @param password 密码
         * @param authcode 验证码
         * @return
         */
        public native String login(String username, String password, int authcode);
    
    }
    

    3.编写Activity文件 MainActivity
    路径:NDKThirdDemo/app/src/main/java/com.tao.ndkthirddemo.MainActivity

    package com.tao.ndkthirddemo;
    
    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 static final String TAG = "MainActivity";
        private EditText edtUsername, edtPassword, edtAuthcode;
        private Button btnLogin;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
        }
    
        private void initView() {
            edtUsername = findViewById(R.id.edt_username);
            edtPassword = findViewById(R.id.edt_password);
            edtAuthcode = findViewById(R.id.edt_authcode);
            btnLogin = findViewById(R.id.btn_login);
    
            btnLogin.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String username = edtUsername.getText().toString().trim();
                    String password = edtPassword.getText().toString().trim();
                    String authcodeStr = edtAuthcode.getText().toString().trim();
                    int authcode = Integer.parseInt(authcodeStr.equals("") ? "0" : authcodeStr);
                    String result = new Java2CLogin().login(username, password, authcode);
                    Log.e(TAG, "C 调用 Java 成员变量获取的结果是:" + result);
                    Toast.makeText(MainActivity.this, result, Toast.LENGTH_LONG).show();
                }
            });
        }
    }
    

    4.编写 activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.tao.ndkthirddemo.MainActivity">
    
        <EditText
            android:id="@+id/edt_username"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="请输入用户名(admin)" />
    
        <EditText
            android:id="@+id/edt_password"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="请输入密码(1234)" />
    
        <EditText
            android:id="@+id/edt_authcode"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="请输入验证码(888)" />
    
        <Button
            android:id="@+id/btn_login"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:text="登录——C 调用 Java 成员变量" />
    
    </LinearLayout>
    

    5.编写CMakeLists.txt文件,以后如果编写其他jni类,只需替换里面的“login_lib”

    # For more information about using CMake with Android Studio, read the
    # documentation: https://d.android.com/studio/projects/add-native-code.html
    
    # Sets the minimum version of CMake required to build the native library.
    
    cmake_minimum_required(VERSION 3.4.1)
    
    # Creates and names a library, sets it as either STATIC
    # or SHARED, and provides the relative paths to its source code.
    # You can define multiple libraries, and CMake builds them for you.
    # Gradle automatically packages shared libraries with your APK.
    
    add_library( # Sets the name of the library.
                 login_lib
    
                 # Sets the library as a shared library.
                 SHARED
    
                 # Provides a relative path to your source file(s).
                 src/main/cpp/login_lib.cpp )
    
    # Searches for a specified prebuilt library and stores the path as a
    # variable. Because CMake includes system libraries in the search path by
    # default, you only need to specify the name of the public NDK library
    # you want to add. CMake verifies that the library exists before
    # completing its build.
    
    find_library( # Sets the name of the path variable.
                  log-lib
    
                  # Specifies the name of the NDK library that
                  # you want CMake to locate.
                  log )
    
    # Specifies libraries CMake should link to your target library. You
    # can link multiple libraries, such as libraries you define in this
    # build script, prebuilt third-party libraries, or system libraries.
    
    target_link_libraries( # Specifies the target library.
                           login_lib
    
                           # Links the target library to the log library
                           # included in the NDK.
                           ${log-lib} )
    

    四、编译

    点击build——>Rebuild Project 或 Make Progject
    参照:
    JNI/NDK编程(一)——无参函数之Hello world !JNI/NDK编程(二)——带参函数之模拟登录

    五、运行程序

    相关文章

      网友评论

        本文标题:JNI/NDK编程(三)——C 调用 Java 成员变量

        本文链接:https://www.haomeiwen.com/subject/ycraqftx.html