导航:首页 > 操作系统 > 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相关的资料

热点内容
堵车如何缓解压力 浏览:15
喜鹊快贷app怎么了 浏览:263
海龟编辑器积木编程怎么安装 浏览:185
程序员理发店生意怎么样 浏览:603
程序员罗技 浏览:180
软考初级程序员课程2021下载 浏览:491
杭州程序员奶奶 浏览:880
不听命令造成错误 浏览:981
kool系统源码 浏览:610
流氓app在哪里看 浏览:98
域名购买了怎么指向服务器 浏览:121
安卓手机如何让照片颜色反转 浏览:859
怎么下载卓睿安手机版 浏览:514
h3crange命令 浏览:468
php前景和python 浏览:338
php压缩图片内存大小 浏览:495
在哪里可以查看云服务器的信息 浏览:70
python读取非txt文件 浏览:799
艾莫迅用什么编程软件好 浏览:227
android文件存储读取 浏览:214