導航:首頁 > 操作系統 > androidnewstringutf

androidnewstringutf

發布時間:2022-07-01 17:20:59

A. 關於安卓5.0NewStringUTF報錯問題怎麼解決

首先,解壓縮下載來的底包(tgz格式壓縮包),會得到4-6個img鏡像文件,其中就有針對bootloader、radio的(後者只在移動網路版設備上有),都放在刷機目錄里。然後像平常刷機那樣,在命令行內進入刷機目錄,連接電腦,關鍵的時候就到了。 --第一步 ...

B. android jnionload函數在哪兒

實現JNI中本地函數注冊可以兩種方式:
(1)採用默認的本地函數注冊流程。
(2)自己重寫JNI_OnLoad()函數。(本文介紹)(Android中採用這種)
java端代碼:

package com.jni;
public class JavaHello {
public static native String hello();
static {
// load library: libtest.so
try {
System.loadLibrary("test");
} catch (UnsatisfiedLinkError ule) {
System.err.println("WARNING: Could not load library!");
}
}
public static void main(String[] args) {
String s = new JavaHello().hello();
System.out.println(s);
}
}

本地C語言代碼:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <jni.h>
#include <assert.h>

JNIEXPORT jstring JNICALL native_hello(JNIEnv *env, jclass clazz)
{
printf("hello in c native code./n");
return (*env)->NewStringUTF(env, "hello world returned.");
}

#define JNIREG_CLASS "com/jni/JavaHello"//指定要注冊的類

/**
* Table of methods associated with a single class.
*/
static JNINativeMethod gMethods[] = {
{ "hello", "()Ljava/lang/String;", (void*)native_hello },//綁定
};

/*
* Register several native methods for one class.
*/
static int registerNativeMethods(JNIEnv* env, const char* className,
JNINativeMethod* gMethods, int numMethods)
{
jclass clazz;
clazz = (*env)->FindClass(env, className);
if (clazz == NULL) {
return JNI_FALSE;
}
if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0) {
return JNI_FALSE;
}

return JNI_TRUE;
}

/*
* Register native methods for all classes we know about.
*/
static int registerNatives(JNIEnv* env)
{
if (!registerNativeMethods(env, JNIREG_CLASS, gMethods,
sizeof(gMethods) / sizeof(gMethods[0])))
return JNI_FALSE;

return JNI_TRUE;
}

/*
* Set some test stuff up.
*
* Returns the JNI version on success, -1 on failure.
*/
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env = NULL;
jint result = -1;

if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
return -1;
}
assert(env != NULL);

if (!registerNatives(env)) {//注冊
return -1;
}
/* success -- return valid version number */
result = JNI_VERSION_1_4;

return result;
}

編譯及運行流程:
1 設置三個環境變數:
export JAVA_HOME:=/usr/lib/jvm/java-6-sun-1.6.0.15
export JAVA_SRC_PATH:=/home/kortide/Jackey/jni/jni_onload/com/jfo
export NATIVE_SRC_PATH:=/home/kortide/Jackey/jni/jni_onload/jni
2 編譯JavaHello.java:
javac $JAVA_SRC_PATH/JavaHello.java
3. 編譯NativeHello.c,生成共享庫
gcc -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -c -o $NATIVE_SRC_PATH/NativeHello.o $NATIVE_SRC_PATH/NativeHello.c
gcc -fPIC -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -shared -o $NATIVE_SRC_PATH/libtest.so $NATIVE_SRC_PATH/NativeHello.o
4. 運行
java com/jni/JavaHello

C. Android 中Native方法是怎樣調用的

通過jni介面調用native

步驟如下:

1.創建一個 android project, 名字叫Why

2 在工程Why中添加一個Java類,class名為Jni。這個類是一個JNI介面的Java類,文件名為Jni.java。
package com.yarin.android.Why;
public class Jni {
public native int getCInt();
public native String getCString();
}

3.將工程Why下的 "src\com\yarin\android\Why" 目錄下的Jni.java文件到「Why\bin\classes」下.
4.Generate Jni.class file via the command below:
javac jni.java
Then the Jni.class file generated to cover and replace the original Jni.class file in directory 「Why\bin\classes\com\yarin\android\Why」.
------The original Jni.class file, you must build the java project first to generate it.

5.Generate c style header file
javah –classpath C:\android-ndk-r6b\myproject\Why\bin\classes com.yarin.android.Why.Jni
com.yarin.android.Why is my package name appeared in Jni.java file.

com_yarin_android_Why_Jni.h is like below:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_yarin_android_Why_Jni */
#ifndef _Included_com_yarin_android_Why_Jni
#define _Included_com_yarin_android_Why_Jni
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_yarin_android_Why_Jni
* Method: getCInt
* Signature: ()I
*/
JNIEXPORT jint JNICALL Java_com_yarin_android_Why_Jni_getCInt
(JNIEnv *env, jobject object); ---you need to supplement the parameter name yourself
/*
* Class: com_yarin_android_Why_Jni
* Method: getCString
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_com_yarin_android_Why_Jni_getCString
(JNIEnv *env, jobject object);
#ifdef __cplusplus
}
#endif
#endif

6.Add com_yarin_android_Why_Jni.c file corresponding to the above c style header file, then add implemented code.

#include <stdio.h>
#include <stdlib.h>
#include "com_yarin_android_Why_Jni.h"

int add()
{
int x,y;
x = 111;
y = 22;
x += y;

return x;
}

JNIEXPORT jint JNICALL Java_com_yarin_android_Why_Jni_getCInt
(JNIEnv *env, jobject object)
{
return add();
}

JNIEXPORT jstring JNICALL Java_com_yarin_android_Why_Jni_getCString
(JNIEnv *env, jobject object)
{
(*env)->NewStringUTF(env, " Why is ok ^_^ ----->> ");
}

7.然後實現在工程Why下創建目錄jni,並且 com_yarin_android_Why_Jni.c /h 到jni目錄下。

8.在"Why\jni"目錄下編寫Android.mk ,在"android-ndk-r6b\jni"下編寫Application.mk , 然後在NDK環境下編譯native code,生成動態庫libWhy.so。

9.在java工程中加入調用native 動態庫的代碼:

package com.yarin.android.Why;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class WhyActivity extends Activity {
static
{
System.loadLibrary("Why");
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Jni jni = new Jni();
TextView view = new TextView(this);
view.setText(jni.getCString() + Integer.toString(jni.getCInt()));
setContentView(view);
}
}

10 編譯Why工程,然後 run as Android Application, 就能看到native code的調用結果了。

Tip:

Usage of the command javah.

javah -d <outputdir> -classpath <classpath> <fully_qualified_class>

where:

'outputdir' is the directory where to put the generated header file

'classpath' contains an absolute path to the directory containing your root package (as mentionned by Glen)

'fully_qualified_class' is the name of the class containing native methods without .class extension

-jni option is not required (set by default)

D. android jni onload 為什麼重起

實現JNI中本地函數注冊可以兩種方式:
(1)採用默認的本地函數注冊流程。
(2)自己重寫JNI_OnLoad()函數。(本文介紹)(Android中採用這種)

Java端代碼:

package com.jni;
public class JavaHello {
public static native String hello();
static {
// load library: libtest.so
try {
System.loadLibrary("test");
} catch (UnsatisfiedLinkError ule) {
System.err.println("WARNING: Could not load library!");
}
}
public static void main(String[] args) {
String s = new JavaHello().hello();
System.out.println(s);
}
}
本地C語言代碼:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <jni.h>
#include <assert.h>

JNIEXPORT jstring JNICALL native_hello(JNIEnv *env, jclass clazz)
{
printf("hello in c native code./n");
return (*env)->NewStringUTF(env, "hello world returned.");
}

#define JNIREG_CLASS "com/jni/JavaHello"//指定要注冊的類

/**
* Table of methods associated with a single class.
*/
static JNINativeMethod gMethods[] = {
{ "hello", "()Ljava/lang/String;", (void*)native_hello },//綁定
};

/*
* Register several native methods for one class.
*將此組件提供的各個本地函數(Native Function)登記到VM里,以便能加快後續呼叫本地函數的效率
*/
static int registerNativeMethods(JNIEnv* env, const char* className,
JNINativeMethod* gMethods, int numMethods)
{
jclass clazz;
clazz = (*env)->FindClass(env, className);
if (clazz == NULL) {
return JNI_FALSE;
}
if ((*env)->RegisterNatives(env, clazz, gMethods, numMethods) < 0) {
return JNI_FALSE;
}

return JNI_TRUE;
}

/*
* Register native methods for all classes we know about.
*/
static int registerNatives(JNIEnv* env)
{
if (!registerNativeMethods(env, JNIREG_CLASS, gMethods,
sizeof(gMethods) / sizeof(gMethods[0])))
return JNI_FALSE;

return JNI_TRUE;
}

/*
* Set some test stuff up.
*
* Returns the JNI version on success, -1 on failure.
*該方法是在android vm調用System.loadLibrary方法時,就立即調用該方法
* 該函數做兩件事,第一:注冊所有的方法,第二:確認JNI的版本
*/
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved)
{
JNIEnv* env = NULL;
jint result = -1;

if ((*vm)->GetEnv(vm, (void**) &env, JNI_VERSION_1_4) != JNI_OK) {
return -1;
}
assert(env != NULL);

if (!registerNatives(env)) {//注冊
return -1;
}
/* success -- return valid version number */
result = JNI_VERSION_1_4;

return result;
}
編譯及運行流程:

1 設置三個環境變數:
export JAVA_HOME:=/usr/lib/jvm/java-6-sun-1.6.0.15
export JAVA_SRC_PATH:=/home/kortide/Jackey/jni/jni_onload/com/jfo
export NATIVE_SRC_PATH:=/home/kortide/Jackey/jni/jni_onload/jni

2 編譯JavaHello.java:
javac $JAVA_SRC_PATH/JavaHello.java

3. 編譯NativeHello.c,生成共享庫
gcc -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -c -o $NATIVE_SRC_PATH/NativeHello.o $NATIVE_SRC_PATH/NativeHello.c

gcc -fPIC -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -shared -o $NATIVE_SRC_PATH/libtest.so $NATIVE_SRC_PATH/NativeHello.o

4. 運行
java com/jni/JavaHello

E. 如何在android手機上使用hackrf

JNI方面
1)將編譯好的庫導入工程
拷貝libhackrf.h、libhackrf.so和libusb1.0.so到工程目錄,創建libusb1.0.mk和libhackrf.mk
libusb1.0.mk
通過libhackrf.mk即可將libhackrf連接到工程中。
2)初始化hackrf,注冊接收函數。
JNI介面
[cpp] view plain
JNIEXPORT jstring JNICALL Java_com_pagekpang_hackrftouch_HackRFTouch_test(
JNIEnv *env, jclass cls) {
int result = HACKRF_SUCCESS;
result = hackrf_init();
if (result == HACKRF_SUCCESS) {
return env->NewStringUTF("OK!");
} else {
return env->NewStringUTF("Error!");
}
}
JNIEXPORT jstring JNICALL Java_com_pagekpang_hackrftouch_HackRFTouch_init(
JNIEnv *env, jobject thiz) {
int result = HACKRF_SUCCESS;
uint8_t board_id = BOARD_ID_INVALID;
char pbuf[2048] = { 0 };
result = hackrf_init();
if (result != HACKRF_SUCCESS) {
sprintf(pbuf, "hackrf_init() failed: %s (%d)\n",
hackrf_error_name((hackrf_error) result), result);
return env->NewStringUTF(pbuf);
}

result = hackrf_open(&device);
if (result != HACKRF_SUCCESS) {
sprintf(pbuf, "hackrf_open() failed: %s (%d)\n",
hackrf_error_name((hackrf_error) result), result);
return env->NewStringUTF(pbuf);
}

result = hackrf_board_id_read(device, &board_id);
if (result != HACKRF_SUCCESS) {
sprintf(pbuf, "hackrf_board_id_read() failed: %s (%d)\n",
hackrf_error_name((hackrf_error) result), result);
return env->NewStringUTF(pbuf);
}
sprintf(pbuf, "Board ID Number: %d (%s)\n", board_id,

hackrf_board_id_name((hackrf_board_id) board_id));
return env->NewStringUTF(pbuf);
}
JNIEXPORT jstring JNICALL Java_com_pagekpang_hackrftouch_HackRFTouch_setSampleRateManual(

JNIEnv *env, jobject thiz, jlong freq, jint divi) {
int result = HACKRF_SUCCESS;
char pbuf[2048] = { 0 };
result = hackrf_set_sample_rate_manual(device, freq, divi);
if (result != HACKRF_SUCCESS) {
sprintf(pbuf, "hackrf_set_sample_rate_manual() failed: %s (%d)\n",
hackrf_error_name((hackrf_error) result), result);
return env->NewStringUTF(pbuf);
}
return env->NewStringUTF("ok");
}
JNIEXPORT jstring JNICALL Java_com_pagekpang_hackrftouch_HackRFTouch_setVgaGain(
JNIEnv *env, jobject thiz, jint vga) {
int result = HACKRF_SUCCESS;
char pbuf[2048] = { 0 };
result = hackrf_set_vga_gain(device, vga);
if (result != HACKRF_SUCCESS) {
sprintf(pbuf, "hackrf_set_vga_gain() failed: %s (%d)\n",
hackrf_error_name((hackrf_error) result), result);
return env->NewStringUTF(pbuf);
}
return env->NewStringUTF("ok");
}
JNIEXPORT jstring JNICALL Java_com_pagekpang_hackrftouch_HackRFTouch_setLnaGain(
JNIEnv *env, jobject thiz, jint lna) {
int result = HACKRF_SUCCESS;
char pbuf[2048] = { 0 };
result = hackrf_set_lna_gain(device, lna);
if (result != HACKRF_SUCCESS) {
sprintf(pbuf, "hackrf_set_lna_gain() failed: %s (%d)\n",
hackrf_error_name((hackrf_error) result), result);
return env->NewStringUTF(pbuf);
}
return env->NewStringUTF("ok");
}
JNIEXPORT jstring JNICALL Java_com_pagekpang_hackrftouch_HackRFTouch_setFreq(
JNIEnv *env, jobject thiz, jlong freq) {
int result = HACKRF_SUCCESS;
char pbuf[2048] = { 0 };
result = hackrf_set_freq(device, freq);
if (result != HACKRF_SUCCESS) {
sprintf(pbuf, "hackrf_set_freq() failed: %s (%d)\n",
hackrf_error_name((hackrf_error) result), result);
return env->NewStringUTF(pbuf);
}
return env->NewStringUTF("ok");
}
JNIEXPORT jstring JNICALL Java_com_pagekpang_hackrftouch_HackRFTouch_setAmpEnable(

JNIEnv *env, jobject thiz, jint b) {
int result = HACKRF_SUCCESS;
char pbuf[2048] = { 0 };
result = hackrf_set_amp_enable(device, b == 0 ? false : true);
if (result != HACKRF_SUCCESS) {
sprintf(pbuf, "hackrf_set_amp_enable() failed: %s (%d)\n",
hackrf_error_name((hackrf_error) result), result);
return env->NewStringUTF(pbuf);
}
return env->NewStringUTF("ok");
}

JNIEXPORT jstring JNICALL Java_com_pagekpang_hackrftouch_HackRFTouch_startRX(
JNIEnv *env, jobject thiz) {
int result = HACKRF_SUCCESS;
char pbuf[2048] = { 0 };
result = hackrf_start_rx(device, hackrf_rx_cb, env->NewGlobalRef(thiz));
if (result != HACKRF_SUCCESS) {
sprintf(pbuf, "hackrf_start_rx() failed: %s (%d)\n",
hackrf_error_name((hackrf_error) result), result);
return env->NewStringUTF(pbuf);
}
return env->NewStringUTF("ok");
}
JNIEXPORT jstring JNICALL Java_com_pagekpang_hackrftouch_HackRFTouch_stopRX(

JNIEnv *env, jobject thiz) {
int result = HACKRF_SUCCESS;
char pbuf[2048] = { 0 };
result = hackrf_stop_rx(device);
if (result != HACKRF_SUCCESS) {
sprintf(pbuf, "hackrf_stop_rx() failed: %s (%d)\n",
hackrf_error_name((hackrf_error) result), result);
return env->NewStringUTF(pbuf);
}
return env->NewStringUTF("ok");
}
java層與JNI介面的綁定

[java] view plain
package com.pagekpang.hackrftouch;

public class HackRFTouch {

static {
System.loadLibrary("usb1.0");
System.loadLibrary("hackrf");
System.loadLibrary("HackrfTouch");
}

public static native String test();

private native String init();

private native String setSampleRateManual(long freq, int divi);

private native String setVgaGain(int g);

private native String setLnaGain(int g);

private native String setFreq(long freq);

private native String setAmpEnable(int f);

public native String startRX();

public native String stopRX();

public native float[] readRx();

private String retString = "";
private Boolean isOpen = false;

private ReadRxThread mReadRxThread = null;

public HackRFTouch() {
// TODO Auto-generated constructor stub
retString = init();
if (!retString.contains("failed")) {
isOpen = true;
mReadRxThread = new ReadRxThread(this);
}
}

class ReadRxThread extends Thread {
HackRFTouch mThisHackRFTouch = null;

public ReadRxThread(HackRFTouch t) {
// TODO Auto-generated constructor stub
mThisHackRFTouch = t;
}

@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while(true){
mThisHackRFTouch.cb(mThisHackRFTouch.readRx());
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

public Boolean isOpen() {
return isOpen;
}

public String getLastError() {
return retString;
}

public Boolean HsetSampleRateManual(long freq, int divi) {
if (!isOpen) {
return false;
}
retString = setSampleRateManual(freq, divi);
if (retString.contains("failed")) {
return false;
} else {
return true;
}
}

public Boolean HsetLnaGain(int g) {
if (!isOpen) {
return false;
}
retString = setLnaGain(g);
if (retString.contains("failed")) {
return false;
} else {
return true;
}
}

public Boolean HsetVgaGain(int g) {
if (!isOpen) {
return false;
}
retString = setVgaGain(g);
if (retString.contains("failed")) {
return false;
} else {
return true;
}
}

public Boolean HsetFreq(long freq) {
if (!isOpen) {
return false;
}
retString = setFreq(freq);
if (retString.contains("failed")) {
return false;
} else {
return true;
}
}

public Boolean HstopRX() {
if (!isOpen) {
return false;
}
retString = stopRX();
if (retString.contains("failed")) {
return false;
} else {
return true;
}
}

3)FFT運算

[cpp] view plain
if (device != NULL) {
float raw[1024];
int dalen = transfer->valid_length;
float realF, imagF, maxF;
uint8_t *pbuf = transfer->buffer;
while (dalen > 0 && runcount == 0) {
complex<double>* fdata = new complex<double> [1024];
complex<double>* fout = new complex<double> [1024];
for (int i = 0; i < 2048; i += 2) {
fdata[i / 2] = complex<double>(meanN(&pbuf[i], 100), meanN(&pbuf[i + 1], 100));
}
FFT(fdata, fout, 10);
//dft(fdata, 10, 0);
//fout = fdata;
maxF = 0.0;
for (int i = 0; i < 1024; i++) {
raw[i] = pow(pow(fout[i].real(), 2) + pow(fout[i].imag(), 2),
0.5);
if (maxF < raw[i]) {
maxF = raw[i];
}
}

for (int i = 0; i < 1024; i++) {
raw[i] = raw[i] / maxF;
}

sendBuf(raw);
//send(g_client, (char *)&raw, 4*1024, 0); //發送數據
dalen -= 2048;
pbuf += 2048;
runcount = 2;
}
runcount--;
//printf("E");
} else {
printf("O");
}

F. android stdiondk要什麼路徑

最新版的NDK集成了Cygwin,不用單獨安裝了、

注意問題:
1.在local.properties配置文件中,配置路徑中不能有空格
第一次使用了C:Program FilesAndroid總是提示錯誤
2.最好不要再activity中申明一個native方法
如果在activity中申明native方法,那麼使用javah的時候就必要要把相關引用的庫給添加上,如果是普通的java類,那麼使用就不需要考慮很多android自帶的類庫。
3.在c文件中,要NewStringUTF轉換string類型。否則編譯時會將你的字元串的數字型看成是引用類型


以下為轉載,我按照轉載的遇到了三個問題,分別記下來參考。

AndroidStudio版本:release 1.0.2

創建一個空的project。創建一個空的activity。

在該類裡面定義一個native方法。如下:


[java]view plain

();




然後makeproject一下,目的就是編譯成對應的class文件。然後根據生成的class文件,利用javah生成對應的.h頭文件。

點開androidstudio的Terminal標簽頁,默認進入到該項目的app文件夾下。如果在該目錄下輸入cd srcmain切換到main目錄下。

我的路徑為:

E:>

用javah生成c的頭文件:

javah -d jni -classpath D:androidsdkplatformsandroid-21android.jar;....uildintermediatesclassesdebug com.jnimobile.www.myjnidemo.MainActivity

javah -d (jni新建文件名) -classpath (sdk路徑);(class 路徑) (class文件名,包括包名)

就會發現在main目錄下多了一個jni文件夾,裡面有生成好的頭文件:com_jnimobile_www_myjnidemo_MainActivity.h

內容如下:


[cpp]view plain

/*DONOTEDITTHISFILE-itismachinegenerated*/

#include<jni.h>

/*Headerforclasscom_jnimobile_www_myjnidemo_MainActivity*/

#ifndef_Included_com_jnimobile_www_myjnidemo_MainActivity

#define_Included_com_jnimobile_www_myjnidemo_MainActivity

#ifdef__cplusplus

extern"C"{

#endif

#undefcom_jnimobile_www_myjnidemo_MainActivity_BIND_ABOVE_CLIENT

#definecom_jnimobile_www_myjnidemo_MainActivity_BIND_ABOVE_CLIENT8L

#undefcom_jnimobile_www_myjnidemo_MainActivity_BIND_ADJUST_WITH_ACTIVITY

#definecom_jnimobile_www_myjnidemo_MainActivity_BIND_ADJUST_WITH_ACTIVITY128L

#undefcom_jnimobile_www_myjnidemo_MainActivity_BIND_ALLOW_OOM_MANAGEMENT

#definecom_jnimobile_www_myjnidemo_MainActivity_BIND_ALLOW_OOM_MANAGEMENT16L

#undefcom_jnimobile_www_myjnidemo_MainActivity_BIND_AUTO_CREATE

#definecom_jnimobile_www_myjnidemo_MainActivity_BIND_AUTO_CREATE1L

#undefcom_jnimobile_www_myjnidemo_MainActivity_BIND_DEBUG_UNBIND

#definecom_jnimobile_www_myjnidemo_MainActivity_BIND_DEBUG_UNBIND2L

#undefcom_jnimobile_www_myjnidemo_MainActivity_BIND_IMPORTANT

#definecom_jnimobile_www_myjnidemo_MainActivity_BIND_IMPORTANT64L

#undefcom_jnimobile_www_myjnidemo_MainActivity_BIND_NOT_FOREGROUND

#definecom_jnimobile_www_myjnidemo_MainActivity_BIND_NOT_FOREGROUND4L

#undefcom_jnimobile_www_myjnidemo_MainActivity_BIND_WAIVE_PRIORITY

#definecom_jnimobile_www_myjnidemo_MainActivity_BIND_WAIVE_PRIORITY32L

#undefcom_jnimobile_www_myjnidemo_MainActivity_CONTEXT_IGNORE_SECURITY

#definecom_jnimobile_www_myjnidemo_MainActivity_CONTEXT_IGNORE_SECURITY2L

#undefcom_jnimobile_www_myjnidemo_MainActivity_CONTEXT_INCLUDE_CODE

#definecom_jnimobile_www_myjnidemo_MainActivity_CONTEXT_INCLUDE_CODE1L

#undefcom_jnimobile_www_myjnidemo_MainActivity_CONTEXT_RESTRICTED

#definecom_jnimobile_www_myjnidemo_MainActivity_CONTEXT_RESTRICTED4L

#undefcom_jnimobile_www_myjnidemo_MainActivity_MODE_APPEND

#definecom_jnimobile_www_myjnidemo_MainActivity_MODE_APPEND32768L

#undefcom_jnimobile_www_myjnidemo_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING

#definecom_jnimobile_www_myjnidemo_MainActivity_MODE_ENABLE_WRITE_AHEAD_LOGGING8L

#undefcom_jnimobile_www_myjnidemo_MainActivity_MODE_MULTI_PROCESS

#definecom_jnimobile_www_myjnidemo_MainActivity_MODE_MULTI_PROCESS4L

#undefcom_jnimobile_www_myjnidemo_MainActivity_MODE_PRIVATE

#definecom_jnimobile_www_myjnidemo_MainActivity_MODE_PRIVATE0L

#undefcom_jnimobile_www_myjnidemo_MainActivity_MODE_WORLD_READABLE

#definecom_jnimobile_www_myjnidemo_MainActivity_MODE_WORLD_READABLE1L

#undefcom_jnimobile_www_myjnidemo_MainActivity_MODE_WORLD_WRITEABLE

#definecom_jnimobile_www_myjnidemo_MainActivity_MODE_WORLD_WRITEABLE2L

#undefcom_jnimobile_www_myjnidemo_MainActivity_DEFAULT_KEYS_DIALER

#definecom_jnimobile_www_myjnidemo_MainActivity_DEFAULT_KEYS_DIALER1L

#undefcom_jnimobile_www_myjnidemo_MainActivity_DEFAULT_KEYS_DISABLE

#definecom_jnimobile_www_myjnidemo_MainActivity_DEFAULT_KEYS_DISABLE0L

#undefcom_jnimobile_www_myjnidemo_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL

#definecom_jnimobile_www_myjnidemo_MainActivity_DEFAULT_KEYS_SEARCH_GLOBAL4L

#undefcom_jnimobile_www_myjnidemo_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL

#definecom_jnimobile_www_myjnidemo_MainActivity_DEFAULT_KEYS_SEARCH_LOCAL3L

#undefcom_jnimobile_www_myjnidemo_MainActivity_DEFAULT_KEYS_SHORTCUT

#definecom_jnimobile_www_myjnidemo_MainActivity_DEFAULT_KEYS_SHORTCUT2L

#undefcom_jnimobile_www_myjnidemo_MainActivity_RESULT_CANCELED

#definecom_jnimobile_www_myjnidemo_MainActivity_RESULT_CANCELED0L

#undefcom_jnimobile_www_myjnidemo_MainActivity_RESULT_FIRST_USER

#definecom_jnimobile_www_myjnidemo_MainActivity_RESULT_FIRST_USER1L

#undefcom_jnimobile_www_myjnidemo_MainActivity_RESULT_OK

#definecom_jnimobile_www_myjnidemo_MainActivity_RESULT_OK-1L

/*

*Class:com_jnimobile_www_myjnidemo_MainActivity

*Method:getStringFromNative

*Signature:()Ljava/lang/String;

*/

JNIEXPORTjstringJNICALLJava_com_jnimobile_www_myjnidemo_MainActivity_getStringFromNative

(JNIEnv*,jobject);

#ifdef__cplusplus

}

#endif

#endif




在jni目錄下新建一個 .c文件。來實現頭文件裡面聲明的方法。我的叫main.c

內容如下:

[cpp]view plain

#include"com_jnimobile_www_myjnidemo_MainActivity.h"

/*

*Class:com_jnimobile_www_myjnidemo_MainActivity

*Method:getStringFromNative

*Signature:()Ljava/lang/String;

*/

JNIEXPORTjstringJNICALLJava_com_jnimobile_www_myjnidemo_MainActivity_getStringFromNative

(JNIEnv*env,jobjectobj){

return(*env)->NewStringUTF(env,"I'mcomesfromtoNativeFunction!");

}

在jni下面再建一個空的.c文件。要不編譯有問題,這個應該是androidstudio的一個bug。


在 local.properties文件中設置ndk的路徑:

我的是:

ndk.dir=D:\android-ndk-r10d

該文件的完整的配置信息如下:

[cpp]view plain

sdk.dir=D:\androidsdk

ndk.dir=D:\android-ndk-r10d


在app目錄下的build.gradle中設置庫文件名(生成的so文件名):

找到 defaultConfig這項,在裡面添加如下內容:

[java]view plain

ndk{

moleName"MyJni"//設置庫(so)文件名稱

}

在activity中添加一個TextView以便顯示從native方法中獲取的字元信息(修改對應的布局文件添加一個TextView,並設定其ID值)。

在activity中增加對so的載入:


[java]view plain

static{

System.loadLibrary("MyJni");

}




activity的完整代碼如下:

[java]view plain

packagecom.jnimobile.www.myjnidemo;

importandroid.app.Activity;

importandroid.os.Bundle;

importandroid.widget.TextView;

{

privateTextViewtv=null;

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

tv=(TextView)findViewById(R.id.tv);

tv.setText(getStringFromNative());

}

();

static{

System.loadLibrary("MyJni");

}

}

編譯,並運行。界面上就會顯示從native方法傳過來的值。

項目目錄截圖如下:

G. android應用是如何監聽自己是否被卸載的呢

Activity啟動時fork出C端進程輪詢目錄:

1 package main.activity;
2
3 import pym.test.uninstalledmoniter.R;
4 import android.app.Activity;
5 import android.os.Bundle;
6 import android.util.Log;
7
8 /**
9 * @author pengyiming
10 * @note 監聽此應用是否被卸載,若被卸載則彈出卸載反饋
11 *
12 */
13
14 public class UninstalledMoniterActivity extends Activity
15 {
16 /* 數據段begin */
17 private static final String TAG = "UninstalledMoniterActivity";
18 /* 數據段end */
19
20 /* 函數段begin */
21 private native void init();
22 static
23 {
24 Log.d(TAG, "load libuninstalled_moniter");
25 System.loadLibrary("uninstalled_moniter");
26 }
27
28 @Override
29 public void onCreate(Bundle savedInstanceState)
30 {
31 super.onCreate(savedInstanceState);
32 Log.d(TAG, "onCreate");
33
34 setContentView(R.layout.uninstalled_moniter_layout);
35
36 init();
37 }
38 /* 函數段end */
39 }

核心——native方法頭文件:

1 /* 頭文件begin */
2 #include <jni.h>
3 #include <stdio.h>
4 #include <string.h>
5 #include <android/log.h>
6 #include <unistd.h>
7 /* 頭文件end */
8
9 /* 宏定義begin */
10 //清0宏
11 #define MEM_ZERO(pDest, destSize) memset(pDest, 0, destSize)
12
13 //LOG宏定義
14 #define LOG_INFO(tag, msg) __android_log_write(ANDROID_LOG_INFO, tag, msg)
15 #define LOG_DEBUG(tag, msg) __android_log_write(ANDROID_LOG_DEBUG, tag, msg)
16 #define LOG_WARN(tag, msg) __android_log_write(ANDROID_LOG_WARN, tag, msg)
17 #define LOG_ERROR(tag, msg) __android_log_write(ANDROID_LOG_ERROR, tag, msg)
18 /* 宏定義end */
19
20 #ifndef _Included_main_activity_UninstalledMoniterActivity
21 #define _Included_main_activity_UninstalledMoniterActivity
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25
26 #undef main_activity_UninstalledMoniterActivity_MODE_PRIVATE
27 #define main_activity_UninstalledMoniterActivity_MODE_PRIVATE 0L
28 #undef main_activity_UninstalledMoniterActivity_MODE_WORLD_READABLE
29 #define main_activity_UninstalledMoniterActivity_MODE_WORLD_READABLE 1L
30 #undef main_activity_UninstalledMoniterActivity_MODE_WORLD_WRITEABLE
31 #define main_activity_UninstalledMoniterActivity_MODE_WORLD_WRITEABLE 2L
32 #undef main_activity_UninstalledMoniterActivity_MODE_APPEND
33 #define main_activity_UninstalledMoniterActivity_MODE_APPEND 32768L
34 #undef main_activity_UninstalledMoniterActivity_MODE_MULTI_PROCESS
35 #define main_activity_UninstalledMoniterActivity_MODE_MULTI_PROCESS 4L
36 #undef main_activity_UninstalledMoniterActivity_BIND_AUTO_CREATE
37 #define main_activity_UninstalledMoniterActivity_BIND_AUTO_CREATE 1L
38 #undef main_activity_UninstalledMoniterActivity_BIND_DEBUG_UNBIND
39 #define main_activity_UninstalledMoniterActivity_BIND_DEBUG_UNBIND 2L
40 #undef main_activity_UninstalledMoniterActivity_BIND_NOT_FOREGROUND
41 #define main_activity_UninstalledMoniterActivity_BIND_NOT_FOREGROUND 4L
42 #undef main_activity_UninstalledMoniterActivity_BIND_ABOVE_CLIENT
43 #define main_activity_UninstalledMoniterActivity_BIND_ABOVE_CLIENT 8L
44 #undef main_activity_UninstalledMoniterActivity_BIND_ALLOW_OOM_MANAGEMENT
45 #define main_activity_UninstalledMoniterActivity_BIND_ALLOW_OOM_MANAGEMENT 16L
46 #undef main_activity_UninstalledMoniterActivity_BIND_WAIVE_PRIORITY
47 #define main_activity_UninstalledMoniterActivity_BIND_WAIVE_PRIORITY 32L
48 #undef main_activity_UninstalledMoniterActivity_BIND_IMPORTANT
49 #define main_activity_UninstalledMoniterActivity_BIND_IMPORTANT 64L
50 #undef main_activity_UninstalledMoniterActivity_BIND_ADJUST_WITH_ACTIVITY
51 #define main_activity_UninstalledMoniterActivity_BIND_ADJUST_WITH_ACTIVITY 128L
52 #undef main_activity_UninstalledMoniterActivity_CONTEXT_INCLUDE_CODE
53 #define main_activity_UninstalledMoniterActivity_CONTEXT_INCLUDE_CODE 1L
54 #undef main_activity_UninstalledMoniterActivity_CONTEXT_IGNORE_SECURITY
55 #define main_activity_UninstalledMoniterActivity_CONTEXT_IGNORE_SECURITY 2L
56 #undef main_activity_UninstalledMoniterActivity_CONTEXT_RESTRICTED
57 #define main_activity_UninstalledMoniterActivity_CONTEXT_RESTRICTED 4L
58 #undef main_activity_UninstalledMoniterActivity_RESULT_CANCELED
59 #define main_activity_UninstalledMoniterActivity_RESULT_CANCELED 0L
60 #undef main_activity_UninstalledMoniterActivity_RESULT_OK
61 #define main_activity_UninstalledMoniterActivity_RESULT_OK -1L
62 #undef main_activity_UninstalledMoniterActivity_RESULT_FIRST_USER
63 #define main_activity_UninstalledMoniterActivity_RESULT_FIRST_USER 1L
64 #undef main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_DISABLE
65 #define main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_DISABLE 0L
66 #undef main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_DIALER
67 #define main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_DIALER 1L
68 #undef main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_SHORTCUT
69 #define main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_SHORTCUT 2L
70 #undef main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_SEARCH_LOCAL
71 #define main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_SEARCH_LOCAL 3L
72 #undef main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_SEARCH_GLOBAL
73 #define main_activity_UninstalledMoniterActivity_DEFAULT_KEYS_SEARCH_GLOBAL 4L
74
75 /*
76 * Class: main_activity_UninstalledMoniterActivity
77 * Method: init
78 * Signature: ()V
79 */
80 JNIEXPORT void JNICALL Java_main_activity_UninstalledMoniterActivity_init(JNIEnv *, jobject);
81
82 #ifdef __cplusplus
83 }
84 #endif
85 #endif

核心——native方法實現:

1 /* 頭文件begin */
2 #include "main_activity_UninstalledMoniterActivity.h"
3 /* 頭文件end */
4
5 #ifdef __cplusplus
6 extern "C" {
7 #endif
8
9 /* 內全局變數begin */
10 static char c_TAG[] = "UninstalledMoniterActivity.init";
11 static jboolean b_IS_COPY = JNI_TRUE;
12 /* 內全局變數 */
13
14 /*
15 * Class: main_activity_UninstalledMoniterActivity
16 * Method: init
17 * Signature: ()V
18 */
19 JNIEXPORT void JNICALL Java_main_activity_UninstalledMoniterActivity_init(JNIEnv *env, jobject obj)
20 {
21 jstring tag = (*env)->NewStringUTF(env, c_TAG);
22
23 //初始化log
24 LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY)
25 , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "init OK"), &b_IS_COPY));
26
27 //fork子進程,以執行輪詢任務
28 pid_t pid = fork();
29 if (pid < 0)
30 {
31 //出錯log
32 LOG_ERROR((*env)->GetStringUTFChars(env, tag, &b_IS_COPY)
33 , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "fork error !!!"), &b_IS_COPY));
34 }
35 else if (pid == 0)
36 {
37 //子進程輪詢"/data/data/pym.test.uninstalledmoniter"目錄是否存在,若不存在則說明已被卸載
38 while (1)
39 {
40 FILE *p_file = fopen("/data/data/pym.test.uninstalledmoniter", "r");
41 if (p_file != NULL)
42 {
43 fclose(p_file);
44
45 //目錄存在log
46 LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY)
47 , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "I'm OK !!!"), &b_IS_COPY));
48
49 sleep(1);
50 }
51 else
52 {
53 //目錄不存在log
54 LOG_DEBUG((*env)->GetStringUTFChars(env, tag, &b_IS_COPY)
55 , (*env)->GetStringUTFChars(env, (*env)->NewStringUTF(env, "I'm NOT OK !!!"), &b_IS_COPY));
56
57 //執行命令am start -a android.intent.action.VIEW -d http://shouji.360.cn/web/uninstall/uninstall.html
58 execlp("am", "am", "start", "-a", "android.intent.action.VIEW", "-d", "http://shouji.360.cn/web/uninstall/uninstall.html", (char *)NULL);
59 }
60 }
61 }
62 else
63 {
64 //父進程直接退出,使子進程被init進程領養,以避免子進程僵死
65 }
66 }
67
68 #ifdef __cplusplus
69 }
70 #endif

注1:為了調試方便,包含<android/log.h>,使得so在執行過程中也可以像Java端一樣方便得打出log。相應的mk文件需要加上以下兩句聲明
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog

H. Android用NDK和整套源碼下編譯JNI的不同

2. 注冊函數的方法是不同的。舉例說,在com/evan129/jnitest/jniutils.java有個native int foo()方法,需要在jni中實現
在ndk中,只要實現這個函數,然後函數名是以jint java_com_evan129_jnitest_jniutils_foo(jnienv* env, jobject thiz) 命名既可。也就是說,如果jni只要實現這個函數,並且功能也很簡單的話,那麼jni c/cpp文件里只需要這一個函數就完事了。
但在android源碼中編譯jni代碼是不同的,jni中的函數名無所謂。不過至少還需要加一個
jniexport jint jnicall jni_onload(javavm* vm, void* reserved)方法,這個方法可以找個現有的復制一把就行,檢查運行環境的。然後主要是這個方法中會調用(*env).registernatives函數,在這里把jni中的方法和java文件中的方法關聯起來。
3. 有個很詭異的區別,自動傳入的jnienv* env好像不是一個東西。因為在android源碼中使用這個env一般是如env->newstringutf(…),而ndk中sample里的一處是(*env)->newstringutf(…) 這env和*env差很大。但兩處函數傳入的都是jnienv* env,只能懷疑jnienv的定義是不是都是不同的。

I. Android ndk開發出現No implemetation found問題

效果圖:

閱讀全文

與androidnewstringutf相關的資料

熱點內容
古典音樂入門pdf 瀏覽:952
命令我們班 瀏覽:219
mt4雲伺服器如何 瀏覽:619
徵信解壓密碼在哪裡找 瀏覽:427
芙蓉國pdf 瀏覽:364
從哪裡能看出app的上線時間 瀏覽:27
陳丹青pdf 瀏覽:210
程序員冰兒 瀏覽:363
intellij命令行 瀏覽:574
如何學好地理用什麼app 瀏覽:345
單片機廣州塔燈光編程 瀏覽:713
什麼購物app可以用微信支付 瀏覽:104
安卓的游戲賬號怎麼登到蘋果上 瀏覽:537
網上哪個app可以考教師 瀏覽:228
大眾途觀l壓縮比 瀏覽:839
電腦系統沒有解壓軟體 瀏覽:655
apue源碼編譯 瀏覽:491
javadouble空 瀏覽:400
伺服器主機名是一般是什麼 瀏覽:367
文檔找不到文件夾 瀏覽:382