1. 程式人生 > >c調用java

c調用java

lint n) ges file adl med blog 由於 machine

技術分享

public class MainActivity extends AppCompatActivity {

    private JNI jni;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        jni = new JNI();
    }

    public void test1(View v){
        jni.callVoid();
    }
    
public void test2(View v){ jni.callInt(); } public void test3(View v){ jni.callString(); } public void test4(View v){ //jni.callShowToast(); callShowToast(); } public void showToast(String s){ Toast.makeText(this, s, Toast.LENGTH_SHORT).show(); }
public native void callShowToast(); }

public class JNI {
    static {
        System.loadLibrary("ccalljava");
    }
   // C調用java空方法
    public void helloFromJava(){
        Log.e("calljava","hello from java");
    }
   // C調用java中的帶兩個int參數的方法
    public int add(int x,int y) {
        return x+y;
    }
   
// C調用java中參數為string的方法 public void printString(String s){ Log.e("calljava",s); } public native void callVoid(); public native void callInt(); public native void callString(); public native void callShowToast(); }

技術分享

上面圖片是下面代碼的標題

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_itheima_ccalljava_JNI */

#ifndef _Included_com_itheima_ccalljava_JNI
#define _Included_com_itheima_ccalljava_JNI
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     com_itheima_ccalljava_JNI
 * Method:    callVoid
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_itheima_ccalljava_JNI_callVoid
  (JNIEnv *, jobject);

/*
 * Class:     com_itheima_ccalljava_JNI
 * Method:    callInt
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_itheima_ccalljava_JNI_callInt
  (JNIEnv *, jobject);

/*
 * Class:     com_itheima_ccalljava_JNI
 * Method:    callString
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_itheima_ccalljava_JNI_callString
  (JNIEnv *, jobject);

#ifdef __cplusplus
}
#endif
#endif

Android.mk文件:下面

# Copyright (C) 2009 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
#LOCAL_PATH 獲取當前路徑
LOCAL_PATH := $(call my-dir)
# 清除上次編譯獲取的編譯環境變量 會保存LOCAL_PATH
include $(CLEAR_VARS)

#指定編譯生成的模塊叫什麽名字  生成的.so名字會加上lib前綴和.so後綴
LOCAL_MODULE    := ccalljava
#指定要編譯的.c源文件叫什麽名字
LOCAL_SRC_FILES := ccalljava.c
LOCAL_LDLIBS += -llog

#生成動態鏈接庫 .so文件
include $(BUILD_SHARED_LIBRARY)

#include <jni.h>
// Created by fullcircle on 2017/2/19.
//
#include <android/log.h>
#define LOG_TAG "System.out"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
JNIEXPORT void JNICALL Java_com_zz_ccalljava_JNI_callVoid
(JNIEnv * env, jobject thiz){
    //①找到字節碼對象  Class  jclass      (*FindClass)(JNIEnv*, const char*);
    //第二個參數 要找到的字節碼的全類名
    jclass clazz = (*env)->FindClass(env,"com/zz/ccalljava/JNI");
    //②在Class 中找到要調用的方法 Method
    //jmethodID   (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
    //GetMethodID 第二個參數 clazz字節碼對象 第三個參數方法的名字 第四個參數 方法簽名 可以通過javap -s 獲取
    //在Studio中到模塊的 build/intermediates/classes/debug 執行javap -s 要生成方法簽名的類的全路徑
    jmethodID methodID = (*env)->GetMethodID(env,clazz,"helloFromJava","()V");
    //③通過Class獲取對象(有時可以省略 當native方法和要回調的java方法在同一個類中就可以使用傳過來的jobject調用方法)
    //④通過對象調用方法 void        (*CallVoidMethod)(JNIEnv*, jobject, jmethodID, ...);
    (*env)->CallVoidMethod(env,thiz,methodID);
}

/*
 * Class:     com_zz_ccalljava_JNI
 * Method:    callInt
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_zz_ccalljava_JNI_callInt
(JNIEnv * env, jobject thiz){
    //①找到class
    jclass clazz =(*env)->FindClass(env,"com/zz/ccalljava/JNI");
    //②找到方法
    jmethodID  methodID = (*env)->GetMethodID(env,clazz,"add","(II)I");
    //③調用方法
    int result = (*env)->CallIntMethod(env,thiz,methodID,3,4);
    LOGE("result=%d",result);
}

/*
 * Class:     com_zz_ccalljava_JNI
 * Method:    callString
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_com_zz_ccalljava_JNI_callString
(JNIEnv * env, jobject thiz){
    jclass clazz = (*env)->FindClass(env,"com/zz/ccalljava/JNI");
    jmethodID methodID=(*env)->GetMethodID(env,clazz,"printString","(Ljava/lang/String;)V");
    jstring jstr = (*env)->NewStringUTF(env,"hello from c");
    (*env)->CallVoidMethod(env,thiz,methodID,jstr);
}

JNIEXPORT void JNICALL Java_com_zz_ccalljava_JNI_callShowToast
        (JNIEnv * env, jobject thiz){
    jclass clazz =(*env)->FindClass(env,"com/zz/ccalljava/MainActivity");
    jmethodID methodID = (*env)->GetMethodID(env,clazz,"showToast","(Ljava/lang/String;)V");
    //由於callShowToast這個native方法是在 jni這個類中 要調用的java方法是在MainActivity中 所以不能使用傳入的jobject
    //需要創建一個對象 jobject     (*AllocObject)(JNIEnv*, jclass);
    jobject jobj =(*env)->AllocObject(env,clazz);
    jstring jstr = (*env)->NewStringUTF(env,"hello from c");
    (*env)->CallVoidMethod(env,jobj,methodID,jstr);
}


JNIEXPORT void JNICALL Java_com_zz_ccalljava_MainActivity_callShowToast
        (JNIEnv * env, jobject thiz){
    jclass clazz =(*env)->FindClass(env,"com/zz/ccalljava/MainActivity");
    jmethodID methodID = (*env)->GetMethodID(env,clazz,"showToast","(Ljava/lang/String;)V");
    //由於callShowToast這個native方法是在 jni這個類中 要調用的java方法是在MainActivity中 所以不能使用傳入的jobject
    //需要創建一個對象 jobject     (*AllocObject)(JNIEnv*, jclass);
   // jobject jobj =(*env)->AllocObject(env,clazz);
    jstring jstr = (*env)->NewStringUTF(env,"hello from c");
    (*env)->CallVoidMethod(env,thiz,methodID,jstr);
}

c調用java