jni调试

12年的时候写过JNI但是又忘记得差不多了,现在重新写了一次,发现碰到了几个问题,写下来记录一下


第一步

应用程序java代码

package com.example.helloworld;import java.util.Calendar;import android.os.Bundle;
import android.app.Activity;
import android.app.AlarmManager;
import android.util.Log;public class AlarmTest extends Activity
{AlarmManager aManager;Calendar currentTime = Calendar.getInstance();public static final int POWER_OFF_WAKE_UP = 8;//用来设置关机启动的参数 平台这边已经设置好了@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Log.e("weiqifa", test());}public native String  test();static {try{Log.i("JNI", "Trying to load libhelloworld.so");System.loadLibrary("helloWorld");}catch(UnsatisfiedLinkError ule){Log.e("JNI", "Warning : could not load the libhelloworld.so");}}
}

编译一下,可以是eclipse编译,也可以是java命令编译

编译后有下面的代码结构和目录

weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ ls
AndroidManifest.xml  classes  classes.dex  dexedLibs  helloWorld.apk  res  resources.ap_
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$


第二步

生成共享头文件 这一步是最关键的关系到成功和失败


weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ javah -d header -classpath classes -jni com.example.helloworld.AlarmTest
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$


这个命令比较关键 javah -d header 指的是在当前目录下面生成这个头文件,-classpath是指定classes的目录就是第一步里面生成的


-jni指的是生成jni头文件 com.example.helloworld这个是包名 AlarmTest是类名 这些都不能有错


生成后如下

weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ ls
AndroidManifest.xml  classes  classes.dex  dexedLibs  header  helloWorld.apk  res  resources.ap_
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ ls header/
com_example_helloworld_AlarmTest.h
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$


weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ cat header/com_example_helloworld_AlarmTest.h 
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_example_helloworld_AlarmTest */#ifndef _Included_com_example_helloworld_AlarmTest
#define _Included_com_example_helloworld_AlarmTest
#ifdef __cplusplus
extern "C" {
#endif
#undef com_example_helloworld_AlarmTest_POWER_OFF_WAKE_UP
#define com_example_helloworld_AlarmTest_POWER_OFF_WAKE_UP 8L
/** Class:     com_example_helloworld_AlarmTest* Method:    test* Signature: ()Ljava/lang/String;*/
JNIEXPORT jstring JNICALL Java_com_example_helloworld_AlarmTest_test(JNIEnv *, jobject);#ifdef __cplusplus
}
#endif
#endif

刚开始不知道,运行经常出错如下:

weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$ javah -jni com.example.helloworld
error: cannot access com.example.helloworld
class file for com.example.helloworld not found
javadoc: error - Class com.example.helloworld not found.
Error: No classes were specified on the command line.  Try -help.
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/bin$


可以看到自动生成对应的函数:Java_com_example_helloworld_AlarmTest_test

    Java_ + 包名(com_example_helloworld+ 类名(AlarmTest) + 接口名(test):必须要按此JNI规范来操作;


第三步

通过.h来制作.c

看看我们的.c 我们只是需要.h里面那个函数名字,.h没有被引用,也没有参与编译和预编译

helloworld.c如下:

#include <string.h>
#include <jni.h>JNIEXPORT jstring JNICALL Java_com_example_helloworld_AlarmTest_test(JNIEnv *env, jobject thiz)
{return (*env)->NewStringUTF(env,"weiqifa hello for JNI");
}

第四步

生成so文件

看一下我们的mk文件

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)LOCAL_MODULE    := helloWorld
LOCAL_SRC_FILES := helloWorld.cinclude $(BUILD_SHARED_LIBRARY)

会生成如下的so文件:
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/libs/armeabi$ ls
libhelloWorld.so
weiqifa@weiqifa-Inspiron-3847:~/workspace/helloWorld/libs/armeabi$



第五步

执行验证

直接用eclipse安装 或者用 adb push 进去 用adb的话要手动安装so 文件并且改一下权限


10-20 03:06:45.241: E/weiqifa(12194): weiqifa hello for JNI
10-20 03:06:45.241: V/ActivityThread(12194): activityCreated r=ActivityRecord{41e7a890 token=android.os.BinderProxy@41e7a060 {com.example.helloworld/com.example.helloworld.AlarmTest}}


问题:

刚开始的时候,我在Android.mk里面写的LOCAL_MODULE生成的模块名称是大写W,helloWorld

LOCAL_MODULE    := helloWorld

但是在android源码里面,我写的

System.loadLibrary("helloWorld");

里面的helloworld是小写w,然后运行一直加载不成功,后面有个朋友帮我看了一下,找到原因,粗心大意啊。













本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/469352.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Pytorch神经网络理论篇】 19 循环神经网络训练语言模型:语言模型概述+NLP多项式概述

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

B. Code For 1 一个类似于线段树的东西

http://codeforces.com/contest/768/problem/B 我的做法是&#xff0c;观察到&#xff0c;只有是x % 2的情况下&#xff0c;才有可能出现0 其他的&#xff0c;都是1来的&#xff0c;所以开始的ans应该是R - L 1 那么现在就是要看那些是x % 2的&#xff0c;然后放在的位置是属于…

解码错误。‘gb2312‘ codec can‘t decode byte 0xf3 in position 307307: illegal multibyte sequence

一般在decode加errors"ignore"就可以了。例如&#xff1a; decode(gb2312,errors ignore)

常见排序算法的C#实现

排序算法常见的有直接排序、冒泡排序、快速排序、基数排序、归并排序等&#xff0c;下面是实现的代码&#xff0c;仅供参考。 #region DirectSort/// <summary>/// 直接排序./// 第一次从R[0]~R[n-1]中选取最小值&#xff0c;与R[0]交换&#xff0c;/// 第二次从R[1]~R[n…

Android RTC 自下往上浅析

1.首先搞清楚RTC在kernel内的作用: linux系统有两个时钟&#xff1a;一个是由主板电池驱动的“Real Time Clock”也叫做RTC或者叫CMOS时钟&#xff0c;硬件时钟。当操作系统关机的时候&#xff0c;用这个来记录时间&#xff0c;但是对于运行的系统是不用这个时间的。 另一个时间…

【Pytorch神经网络实战案例】11 循环神经网络结构训练语言模型并进行简单预测

1 语言模型步骤 简单概述&#xff1a;根据输入内容&#xff0c;继续输出后面的句子。 1.1 根据需求拆分任务 (1)先对模型输入一段文字&#xff0c;令模型输出之后的一个文字。(2)将模型预测出来的文字当成输入&#xff0c;再放到模型里&#xff0c;使模型预测出下一个文字&…

需要换个环境

感觉需要换个环境了&#xff0c;最近动力越来越小&#xff0c;会死于安乐的&#xff01; 做c/c开发&#xff0c;服务器客户端都可以&#xff0c;其他语言java、pathon多少都会一些&#xff0c; 祈求可以找到一份让自己会全力付出的工作&#xff01; 加油&#xff01;加油&#…

【Pytorch神经网络理论篇】 20 神经网络中的注意力机制

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

Android Alarm自上而下 调试浅析

1.为了创建一个新的Alarm&#xff0c;使用set方法并指定一个Alarm类型、触发时间和在Alarm触发时要调用的Intent。如果你设定的Alarm发生在过去&#xff0c;那么&#xff0c;它将立即触发。 这里有4种Alarm类型。你的选择将决定你在set方法中传递的时间值代表什么&#xff0c;是…

【Pytorch神经网络实战案例】12 利用注意力机制的神经网络实现对FashionMNIST数据集图片的分类

1、掩码模式&#xff1a;是相对于变长的循环序列而言的&#xff0c;如果输入的样本序列长度不同&#xff0c;那么会先对其进行对齐处理&#xff08;对短序列补0&#xff0c;对长序列截断&#xff09;&#xff0c;再输入模型。这样&#xff0c;模型中的部分样本中就会有大量的零…

echarts自学笔记

学习echarts的总结 一、图表的实现 (1)首先将echarts.js引入为echarts提供一个DOM容器&#xff08;具有宽高&#xff09;为echarts配置参数:第一步&#xff1a;初始化DOM容器&#xff0c;用echarts.init()函数第二步&#xff1a; 配置数据选项var option{ title:{},//图表的标…

爬虫实战学习笔记_4 网络请求urllib3模块:发送GET/POST请求实例+上传文件+IP代理+json+二进制+超时

1 urllib3模块简介 urllib3是一个第三方的网络请求模块&#xff08;单独安装该模块&#xff09;&#xff0c;在功能上比Python自带的urllib强大。 1.1了解urllib3 urllib3库功能强大&#xff0c;条理清晰的用于HTTP客户端的python库&#xff0c;提供了很多Python标准库里所没…

Android wakelock 自上而下浅析

Wake Lock是一种锁的机制, 只要有人拿着这个锁,系统就无法进入休眠,可以被用户态程序和内核获得. 这个锁可以是有超时的或者是没有超时的,超时的锁会在时间过去以后自动解锁. 如果没有锁了或者超时了, 内核就会启动休眠的那套机制来进入休眠.PowerManager.WakeLock 有加锁和解锁…

C. Jon Snow and his Favourite Number DP + 注意数值大小

http://codeforces.com/contest/768/problem/C 这题的数值大小只有1000&#xff0c;那么可以联想到&#xff0c;用数值做数组的下标&#xff0c;就是类似于计数排序那样子。。 这样就可以枚举k次操作&#xff0c;然后for (int i 0; i < 1025; i)&#xff0c;也就是O(1000 *…

【Pytorch神经网络理论篇】 21 信息熵与互信息:联合熵+条件熵+交叉熵+相对熵/KL散度/信息散度+JS散度

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

vim 设置支持鼠标

在vim模式 下 :set mousea 也可以把上面的语句去掉起始的冒号放到 .vimrc 文件中 打开一个vim 输入:echo $VIM 这里就会打印出vimrc的位置 vim的一些配置相关 http://www.cnblogs.com/ma6174/archive/2011/12/10/2283393.html

POJ 2395 Out of Hay

http://poj.org/problem?id2395 裸最小生成树 输出树中最大cost的边值 直接prim 1 #include <iostream>2 #include <stdio.h>3 #include <string.h>4 #include <queue>5 #include <algorithm>6 #define READ() freopen("in.txt", &qu…

【Pytorch神经网络理论篇】 22 自编码神经网络:概述+变分+条件变分自编码神经网络

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

Android关机闹钟实现

时间转换网站:http://tool.chinaz.com/Tools/unixtime.aspx 1、apk层 这个还是比较简单的,百度一下就可以看到apk的代码,我之前也有贴出来过还是看一下核心代码吧。 写好的apk(里面有Android.mk文件 加入system/app/下面进行编译):http://download.csdn.net/detail/…

CI开发笔记

CI中的mvc&#xff1a; 访问url使用的是passinfo//就是类似一个文件夹的方式 入口文件.php/控制器/方法&#xff08;动作&#xff09; 控制器&#xff1a; 1.不用加后缀 直接一个单词.php 文件名全部小写 2.控制器是直接或者间接的继承自CI_Controller 3.控制器中对方法的要求…