真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

androidjni調(diào)用過程,android jni教程

如何在Android下使用JNI

第一步:

從策劃到設(shè)計制作,每一步都追求做到細膩,制作可持續(xù)發(fā)展的企業(yè)網(wǎng)站。為客戶提供成都網(wǎng)站建設(shè)、成都網(wǎng)站制作、網(wǎng)站策劃、網(wǎng)頁設(shè)計、域名與空間、網(wǎng)絡(luò)空間、網(wǎng)絡(luò)營銷、VI設(shè)計、 網(wǎng)站改版、漏洞修補等服務(wù)。為客戶提供更好的一站式互聯(lián)網(wǎng)解決方案,以客戶的口碑塑造優(yōu)易品牌,攜手廣大客戶,共同發(fā)展進步。

使用Java編寫HelloWorld 的Android應(yīng)用程序:

復(fù)制代碼

package com.lucyfyr;

import android.app.Activity;

import android.os.Bundle;

import android.util.Log;

public class HelloWorld extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

Log.v("dufresne", printJNI("I am HelloWorld Activity"));

}

static

{

//加載庫文件

System.loadLibrary("HelloWorldJni");

}

//聲明原生函數(shù) 參數(shù)為String類型 返回類型為String

private native String printJNI(String inputStr);

}

復(fù)制代碼

這一步我們可以使用eclipse來生成一個App;

因為eclipse會自動為我們編譯此Java文件,后面要是用到。

第二步:

生成共享庫的頭文件:

進入到eclipse生成的Android Project中 :/HelloWorld/bin/classes/com/lucyfyr/ 下:

可以看到里面后很多后綴為.class的文件,就是eclipse為我們自動編譯好了的java文件,其中就有:

HelloWorld.class文件。

退回到classes一級目錄:/HelloWorld/bin/classes/

執(zhí)行如下命令:

javah com.lucyfyr.HelloWorld

生成文件:com_lucyfyr_HelloWorld.h

android 怎么調(diào)用jni里面的方法

調(diào)用jni里面的方法,過程如下:

第一步:

使用Java編寫HelloWorld 的Android應(yīng)用程序:

package com.lucyfyr;

import android.app.Activity;

import android.os.Bundle;

import android.util.Log;

public class HelloWorld extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

Log.v("dufresne", printJNI("I am HelloWorld Activity"));

}

static

{

//加載庫文件

System.loadLibrary("HelloWorldJni");

}

//聲明原生函數(shù) 參數(shù)為String類型 返回類型為String

private native String printJNI(String inputStr);

}

這一步我們可以使用eclipse來生成一個App;

因為eclipse會自動為我們編譯此Java文件,后面要是用到。

第二步:

生成共享庫的頭文件:

進入到eclipse生成的Android Project中 :/HelloWorld/bin/classes/com/lucyfyr/ 下:

可以看到里面后很多后綴為.class的文件,就是eclipse為我們自動編譯好了的java文件,其中就有:

HelloWorld.class文件。

退回到classes一級目錄:/HelloWorld/bin/classes/

執(zhí)行如下命令:

javah com.lucyfyr.HelloWorld

生成文件:com_lucyfyr_HelloWorld.h

/* DO NOT EDIT THIS FILE - it is machine generated */

#include jni.h

/* Header for class com_lucyfyr_HelloWorld */

#ifndef _Included_com_lucyfyr_HelloWorld

#define _Included_com_lucyfyr_HelloWorld

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: com_lucyfyr_HelloWorld

* Method: printJNI

* Signature: (Ljava/lang/String;)Ljava/lang/String;

*/

JNIEXPORT jstring JNICALL Java_com_lucyfyr_HelloWorld_printJNI

(JNIEnv *, jobject, jstring);

#ifdef __cplusplus

}

#endif

#endif

可以看到自動生成對應(yīng)的函數(shù):Java_com_lucyfyr_HelloWorld_printJNI

Java_ + 包名(com.lucyfyr) + 類名(HelloWorld) + 接口名(printJNI):必須要按此JNI規(guī)范來操作;

java虛擬機就可以在com.simon.HelloWorld類調(diào)用printJNI接口的時候自動找到這個C實現(xiàn)的Native函數(shù)調(diào)用。

當(dāng)然函數(shù)名太長,可以在.c文件中通過函數(shù)名映射表來實現(xiàn)簡化。

第三步:

實現(xiàn)JNI原生函數(shù)源文件:

新建com_lucyfyr_HelloWorld.c文件:

Android之對外開放的api關(guān)聯(lián)jni加載流程梳理

前言

zygote啟動

app_process可執(zhí)行文件的啟動

關(guān)注AndroidRuntime.start執(zhí)行的業(yè)務(wù)

關(guān)注AndroidRuntime.gRegJNI的初始化

以register_android_os_SystemClock注冊為例

總結(jié)

如何在android的jni線程中實現(xiàn)回調(diào)

jni回調(diào)是指在c/c++代碼中調(diào)用java函數(shù),當(dāng)在c/c++的線程中執(zhí)行回調(diào)函數(shù)時,會導(dǎo)致回調(diào)失敗。

其中一種在Android系統(tǒng)的解決方案是:

把c/c++中所有線程的創(chuàng)建,由pthread_create函數(shù)替換為由Java層的創(chuàng)建線程的函數(shù)AndroidRuntime::createJavaThread。

假設(shè)有c++函數(shù):

[cpp] view plaincopy

void *thread_entry(void *args)

{

while(1)

{

printf("thread running...\n");

sleep(1);

}

}

void init()

{

pthread_t thread;

pthread_create(thread,NULL,thread_entry,(void *)NULL);

}

init()函數(shù)創(chuàng)建一個線程,需要在該線程中調(diào)用java類Test的回調(diào)函數(shù)Receive:

[cpp] view plaincopy

public void Receive(char buffer[],int length){

String msg = new String(buffer);

msg = "received from jni callback:" + msg;

Log.d("Test", msg);

}

首先在c++中定義回調(diào)函數(shù)指針:

[cpp] view plaincopy

//test.h

#include pthread.h

//function type for receiving data from native

typedef void (*ReceiveCallback)(unsigned char *buf, int len);

/** Callback for creating a thread that can call into the Java framework code.

* This must be used to create any threads that report events up to the framework.

*/

typedef pthread_t (* CreateThreadCallback)(const char* name, void (*start)(void *), void* arg);

typedef struct{

ReceiveCallback recv_cb;

CreateThreadCallback create_thread_cb;

}Callback;

再修改c++中的init和thread_entry函數(shù):

[cpp] view plaincopy

//test.c

#include stdio.h

#include stdlib.h

#include pthread.h

#include sys/wait.h

#include unistd.h

#include "test.h"

void *thread_entry(void *args)

{

char *str = "i'm happy now";

Callback cb = NULL;

int len;

if(args != NULL){

cb = (Callback *)args;

}

len = strlen(str);

while(1)

{

printf("thread running...\n");

//invoke callback method to java

if(cb != NULL cb-recv_cb != NULL){

cb-recv_cb((unsigned char*)str, len);

}

sleep(1);

}

}

void init(Callback *cb)

{

pthread_t thread;

//pthread_create(thread,NULL,thread_entry,(void *)NULL);

if(cb != NULL cb-create_thread_cb != NULL)

{

cb-create_thread_cb("thread",thread_entry,(void *)cb);

}

}

然后在jni中實現(xiàn)回調(diào)函數(shù),以及其他實現(xiàn):

[cpp] view plaincopy

//jni_test.c

#include stdlib.h

#include malloc.h

#include jni.h

#include JNIHelp.h

#include "android_runtime/AndroidRuntime.h"

#include "test.h"

#define RADIO_PROVIDER_CLASS_NAME "com/tonny/Test"

using namespace android;

static jobject mCallbacksObj = NULL;

static jmethodID method_receive;

static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) {

if (env-ExceptionCheck()) {

LOGE("An exception was thrown by callback '%s'.", methodName);

LOGE_EX(env);

env-ExceptionClear();

}

}

static void receive_callback(unsigned char *buf, int len)

{

int i;

JNIEnv* env = AndroidRuntime::getJNIEnv();

jcharArray array = env-NewCharArray(len);

jchar *pArray ;

if(array == NULL){

LOGE("receive_callback: NewCharArray error.");

return;

}

pArray = (jchar*)calloc(len, sizeof(jchar));

if(pArray == NULL){

LOGE("receive_callback: calloc error.");

return;

}

//copy buffer to jchar array

for(i = 0; i len; i++)

{

*(pArray + i) = *(buf + i);

}

//copy buffer to jcharArray

env-SetCharArrayRegion(array,0,len,pArray);

//invoke java callback method

env-CallVoidMethod(mCallbacksObj, method_receive,array,len);

//release resource

env-DeleteLocalRef(array);

free(pArray);

pArray = NULL;

checkAndClearExceptionFromCallback(env, __FUNCTION__);

}

static pthread_t create_thread_callback(const char* name, void (*start)(void *), void* arg)

{

return (pthread_t)AndroidRuntime::createJavaThread(name, start, arg);

}

static Callback mCallbacks = {

receive_callback,

create_thread_callback

};

static void jni_class_init_native

(JNIEnv* env, jclass clazz)

{

method_receive = env-GetMethodID(clazz, "Receive", "([CI)V");

}

static int jni_init

(JNIEnv *env, jobject obj)

{

if (!mCallbacksObj)

mCallbacksObj = env-NewGlobalRef(obj);

return init(mCallbacks);

}

static const JNINativeMethod gMethods[] = {

{ "class_init_native", "()V", (void *)jni_class_init_native },

{ "native_init", "()I", (void *)jni_init },

};

static int registerMethods(JNIEnv* env) {

const char* const kClassName = RADIO_PROVIDER_CLASS_NAME;

jclass clazz;

/* look up the class */

clazz = env-FindClass(kClassName);

if (clazz == NULL) {

LOGE("Can't find class %s/n", kClassName);

return -1;

}

/* register all the methods */

if (env-RegisterNatives(clazz,gMethods,sizeof(gMethods)/sizeof(gMethods[0])) != JNI_OK)

{

LOGE("Failed registering methods for %s/n", kClassName);

return -1;

}

/* fill out the rest of the ID cache */

return 0;

}

jint JNI_OnLoad(JavaVM* vm, void* reserved) {

JNIEnv* env = NULL;

jint result = -1;

LOGI("Radio JNI_OnLoad");

if (vm-GetEnv((void**) env, JNI_VERSION_1_4) != JNI_OK) {

LOGE("ERROR: GetEnv failed/n");

goto fail;

}

if(env == NULL){

goto fail;

}

if (registerMethods(env) != 0) {

LOGE("ERROR: PlatformLibrary native registration failed/n");

goto fail;

}

/* success -- return valid version number */

result = JNI_VERSION_1_4;

fail:

return result;

}

jni的Android.mk文件中共享庫設(shè)置為:

[cpp] view plaincopy

LOCAL_SHARED_LIBRARIES := liblog libcutils libandroid_runtime libnativehelper

最后再實現(xiàn)Java中的Test類:

[java] view plaincopy

//com.tonny.Test.java

public class Test {

static{

try {

System.loadLibrary("test");

class_init_native();

} catch(UnsatisfiedLinkError ule){

System.err.println("WARNING: Could not load library libtest.so!");

}

}

public int initialize() {

return native_radio_init();

}

public void Receive(char buffer[],int length){

String msg = new String(buffer);

msg = "received from jni callback" + msg;

Log.d("Test", msg);

}

protected static native void class_init_native();

protected native int native_init();

}

android怎么用APK調(diào)用JNI簡單實例

制作Android的內(nèi)置APK,調(diào)用C或者C++去調(diào)用底層接口:

環(huán)境配置:

eclipse要配置NDK插件和系統(tǒng)環(huán)境,我用的是WIN7,先去下載NDK,解壓后就是一個目錄,把路徑記住,去XP電腦配置下環(huán)境,就像配置Java環(huán)境一樣,把路徑寫到系統(tǒng)環(huán)境的PATH就好了(這樣就可以編譯JNI了)。然后在配置eclipse的NDK插件,點擊eclipse的WINDOW/PREFERNCES,彈出框了后點擊android/NDK,有個路徑選擇,一樣選擇你下載好解壓的目錄(選擇后提示不是有效的NDK目錄的時候,你在NDK目錄里面新建一個文件,名字寫:ndk-build,沒有后綴)

如何在android studio中用JNI調(diào)用靜態(tài)庫

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE := static_add

LOCAL_SRC_FILES := libstatic_add.a

include $(PREBUILT_STATIC_LIBRARY)

include $(CLEAR_VARS)

LOCAL_MODULE := share_add

LOCAL_SRC_FILES := hello-jni.c

LOCAL_LDFLAGS += $(LOCAL_PATH)/libstatic_add.a(可以任意指定路徑)

LOCAL_C_INCLUDES := $(LOCAL_PATH)/jni/app/src/main/jni

LOCAL_LDLIBS := -llog

include $(BUILD_SHARED_LIBRARY)


當(dāng)前文章:androidjni調(diào)用過程,android jni教程
標題來源:http://weahome.cn/article/dsdhhip.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部