1. 程式人生 > >Android ndk jni中回撥java的方法&欄位描述符

Android ndk jni中回撥java的方法&欄位描述符

一、jobject和jclass

1.如果定義native方法時使用了static關鍵字,那麼生成的標頭檔案裡就會傳入jclass,代表這個類的引用。
2.如果沒有使用static關鍵字,那麼就會傳入jobject,代表類的物件的引用。

二、jni回撥java

先貼程式碼
1.java

package com.example.testcallback;

import android.util.Log;

public class TestCallbackManager {
    private final String TAG = "TestCallbackManager"
; static { System.loadLibrary("TestCallback"); } public native void start(); public void myCallback(int a) { Log.e(TAG, "Callback: " + a); } }

2.生成的標頭檔案
ps:如果native方法定義成static,這裡就不是jobject,而是jclass

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_testcallback_TestCallbackManager */ #ifndef _Included_com_example_testcallback_TestCallbackManager #define _Included_com_example_testcallback_TestCallbackManager #ifdef __cplusplus extern "C" { #endif /* * Class: com_example_testcallback_TestCallbackManager * Method: start * Signature: ()V */
JNIEXPORT void JNICALL Java_com_example_testcallback_TestCallbackManager_start (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif

3.c檔案

#include <jni.h>
#include <android/log.h>
#include "com_example_testcallback_TestCallbackManager.h"

#define TAG "TestCallbackJNI"
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)

JNIEXPORT void JNICALL Java_com_example_testcallback_TestCallbackManager_start
        (JNIEnv *env, jobject obj) {
    __android_log_print(ANDROID_LOG_ERROR, "Callback JNI", "begin");

    jclass clazz = (*env)->GetObjectClass(env, obj);
    jmethodID mID = (*env)->GetMethodID(env, clazz, "myCallback", "(I)V");
    (*env)->CallVoidMethod(env, obj, mID, 10);

    __android_log_print(ANDROID_LOG_ERROR, "Callback JNI", "end");
}

4.解釋c檔案
(1)在同一個類中,定義native方法和要呼叫的callback方法,為的是可以在當前的物件引用obj中找到當前類的引用,然後找到這個回撥方法。
(2)GetObjectClass,通過obj找到當前類。
(3)GetMethodID找到回撥方法,引數:env引用,類引用,方法名,欄位描述符(這裡看第四條)
(4)欄位描述符:
  (a)JNI中描述欄位使用欄位描述符,描述方法同樣有方法描述符。一個方法描述符包含引數型別和返回值型別。引數型別出現在前面,並由一對圓括號將它們括起來,引數型別按它們在方法宣告中出現的順序被列出來,並且多個引數型別之間沒有分隔符。如果一個方法沒有引數,被表示為一對空圓括號。方法的返回值型別緊跟引數型別的右括號後面。
  (b)描述符對應符號:
   Boolean~~~Z
   Byte~~~B
   Char~~~C
   Short~~~S
   Int~~~I
   Long~~~J
   Float~~~F
   Double~~~D
   Void~~~V
   
   objects物件:
   以”L”開頭,以”;”結尾,中間是用”/” 隔開的包及類名。比如:Ljava/lang/String;。巢狀類:Ljava/xx/外部類名$內部類名;
  (c)方法描述符中可能會包含類描述符,如方法native private String getLine(String);的描述符為:“(Ljava/lang/String;)Ljava/lang/String;”
  (d)陣列型別的描述符以“[”開頭,後面跟著陣列元素型別的描述符。如,public static void main(String[] args);的描述符是:”([Ljava/lang/String;)V”
  (e)舉例:

// 描述符:(IFDZ)V
public void method1(int a,float f,double b,boolean b){
}

// 描述符:(Ljava/lang/String;)I
public int method2(String s){
    return 0;
}

//描述符:()[I
public int[] method3(){
    return null;
}

(5)CallVoidMethod 呼叫回撥方法,並傳入相應值。

相關推薦

Android ndk jnijava方法&描述

一、jobject和jclass 1.如果定義native方法時使用了static關鍵字,那麼生成的標頭檔案裡就會傳入jclass,代表這個類的引用。 2.如果沒有使用static關鍵字,那麼就會傳入jobject,代表類的物件的引用。 二、jni回撥

jniJava方法

/** * Global Reference of java method * 回撥函式object引用 */ static jobject jSourceCallback; /** * the references of JVM */ static JavaVM *gJavaV

Jni 多執行緒程式設計,子執行緒java方法

由於c++層接收到服務端主動推送tcp資料,所以存在將c++層接收到的socket資料通過層層回撥至java的需求。 以下為c++程式碼段: 1:在c++標頭檔案中定義申明相應回撥函式指標 typedef void (*SwitchStateC

android 隱藏虛擬鍵方法

final View activityRootView = findViewById(R.id.activityRoot); activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayout

ANDROID】ASYNCTASK不ONPOSTEXECUTE方法的解決辦法。

1、doInBackground方法是否正常執行返回。 a. 是否出異常 b. 是否死迴圈 c. 是否被阻塞 2、如果doInBackground,正常執行還是沒有回撥這個方

Android App開發實現任意Java方法的攔截

在Android的App開發過程中,經常會有一些導致App程序崩潰的Framework層Bug,比如這裡講的Cookie同步引起的崩潰等問題。這種情況下,我們如果能攔截到Framework層的Api呼叫,對它做個包裝把異常捕捉住,就可以避免這個問題了。當時,純Java層是做不

Android NDK(JNI)學習總結一:Java程式碼申明native函式-Java呼叫C函式,並在C函式訪問java類和方法、屬性

本文不涉及android-ndk開發環境搭。 步驟一:新建一個APP,名稱為HelloJNI,然後定義一個類(將會在native程式碼中呼叫和訪問該類): package com.example.hellojni; public class JNITe

安卓開發——JNI——java方法

JNI開發中   在C程式碼中回撥java中的方法  package com.example.jnitest2; import android.app.Activity; import android.content.Context; import android.

android jni開發c++ 呼叫java 方法

    最近幾天搞fbreader 電子書的二次開發,其中需要 c++ 呼叫 java方法解密電子書,所以l老虎吃天,硬著頭皮看c++程式碼。  具體的思路如下,其實也就這幾步:      1. jni 中用到 java反射的方法

Android多程序appApplicationonCreate()方法被執行多次分析及解決

最近工作中碰到一個問題,在優化app,使用DDMS檢視Application log過程中看到,app啟動了三個程序,一個主程序,兩個附帶的程序。如下圖可看到一個app啟動的三個程序。  自定義Application回撥方法onCreate()被執行了3次。開始不知是何原因。 相

Android介面方法

在android開發中我們很多地方都用到了方法的回撥,回撥就是把方法的定義和功能匯入實現分開的一種機制,目的是為了解耦他的本質是基於觀察者設計模式,即觀察者設計模式的的簡化版,例如:在下載時候的進度回撥,在adapter與activity之間的回撥,在javabean和fr

android jni c語言java

上一篇介紹了 java呼叫c方法返回值,今天總結下c呼叫java。 大體說下步驟,第一步是 找到class,第二步找到方法,第三步是env指標 進行呼叫。類似於反射。 下面詳細說一下。 書寫java原生代碼,呼叫c方法,並且書寫提供給c語言呼叫的java

android NDK開發,用Cygwin調試本地代碼時報錯“Another debug session running,Use --force to kill it”原因及解決的方法

能夠 att cati kill 時報 andro 使用 deb gdb調試 在使用ndk-gdb調試的時候。運行$NDK/ndk-gdb --verbose報錯“Another debug session running,Use --force to kil

java層向jni傳遞GLSurfaceView的方法

bool 很多 code http codec android class ble extern 從java朝jni中傳遞各種數據,是在android開發中經常需要面對的事情。對於一些典型的數據類型,網上已經有很多文章介紹,這裏列出一些數據類型: 對於GLSurfa

LINUX 多執行緒 JNI java static

1.Linux 開啟執行緒 //渲染執行緒Rendering void* thread_rendering_process(void *lParam) {     unsigned int local_wr;     int index; &

python Scrapy的spider函式的引數傳遞方法

通常有兩種方法,一種是使用meta進行引數傳遞。另一種是使用lambda進行引數傳遞。 方法一: 使用meta進行引數傳遞。 舉例如下: from scrapy.spiders import S

關於對Java函式的理解

先來看幾段程式: 1.  首先定義一個類Caller,這個類裡面儲存一個介面引用。        public class Caller {     private MyCallInter

Android JNI-c/c++呼叫java方法

在使用ndk開發的時候,java呼叫c/c++方法是必須要的。但是很多時候,c/c++有callback需要反饋給java的時候(比如IM通訊登入成功資訊和一些異常資訊),就需要c/c++呼叫java方法了。 在看這篇文章之前,必須對JNI有一些基礎的瞭解,比

JNI實現| JNI呼叫JAVA函式|引數和返回值的格式

程式碼下載:http://dl.dbank.com/c0c0xs3b24 一、JNI實現回撥 通過JNI在Native層呼叫Java層的方法,來實現Native層向JAVA層傳遞訊息。 JNICallback.java publicclass JNICallback e

Android JNIC和JAVA程式碼之間的互相呼叫

jobject (*CallObjectMethod)(JNIEnv*, jobject, jmethodID, ...); jobject (*CallObjectMethodV)(JNIEnv*, jobject, jmethodID, va_list); jobject