问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

android jni abifilters为什么没产生文件

发布网友 发布时间:2022-04-22 21:48

我来回答

1个回答

热心网友 时间:2023-09-28 14:59

android studio 中简单的jni开发
Let’s Go!!!
准备工作不再需要什么cgwin来编译ndk(太特么操蛋了),现在只需要你下载一下NDK的库就ok了,然后你也可以去离线下载http://www.androiddevtools.cn最新版,这里吐槽一下android studio对NDK的支持还有待提高。
效果
看下今天的效果:(安卓jni获取 apk的包名及签名信息)

必须的步骤
1.配置你的ndk路径(local.properties)
ndk.dir=E:\Android\sdk\android-ndk-r11b-windows-x86_64\android-ndk-r11b
2.grale配置使用ndk(gradle.properties)
android.useDeprecatedNdk=true
3.在mole下的build.gradle添加ndk以及jni生成目录
ndk{
moleName “JNI_ANDROID”
abiFilters “armeabi”, “armeabi-v7a”, “x86” //输出指定三种abi体系结构下的so库,目前可有可无。
}
sourceSets.main{
jniLibs.srcDirs = [‘libs’]
}
准备工作做好了开始写代码:(jni实现获取应用的包名和签名信息)
步骤1:先写要实现本地方法的类,及加载库(JNI_ANDROID也就是ndk 里面配的moleName)
?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

<code class="hljs java">package com.losileeya.getapkinfo;

/**
* User: Losileeya (847457332@qq.com)
* Date: 2016-07-16
* Time: 11:09
* 类描述:
*
* @version :
*/
public class JNIUtils {
/**
* 获取应用的签名
* @param o
* @return
*/
public static native String getSignature(Object o);

/**
* 获取应用的包名
* @param o
* @return
*/
public static native String getPackname(Object o);

/**
* 加载so库或jni库
*/
static {
System.loadLibrary("JNI_ANDROID");
}
}</code>

注意我们 的加载c方法都加了native关键字,然后要使用jni下的c/c++文件就必须使用System.loadLibrary()。
步骤2:使用javah命令生成.h(头文件)
javah -jni com.losileeya.getapkinfo.JNIUtils
执行完之后你可以在mole下文件夹app\build\intermediates\classes\debug下看见生成的 .h头文件为:
com_losileeya_getapkinfo_JNIUtils.h
?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

<code class="hljs vala">/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_losileeya_getapkinfo_JNIUtils */

#ifndef _Included_com_losileeya_getapkinfo_JNIUtils
#define _Included_com_losileeya_getapkinfo_JNIUtils
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT jstring JNICALL Java_com_losileeya_getapkinfo_JNIUtils_getPackname(JNIEnv *, jobject, jobject);
JNIEXPORT jstring JNICALL Java_com_losileeya_getapkinfo_JNIUtils_getSignature(JNIEnv *, jobject, jobject);
#ifdef __cplusplus
}
#endif
#endif</jni.h></code>

在工程的main目录下新建一个名字为jni的目录,然后将刚才的.h文件剪切过来,当然文件名字是可以修改的
步骤3:根据.h文件生成相应的c/cpp文件
?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41

<code class="hljs scala">//
// Created by Administrator on 2016/7/16.
//
#include <stdio.h>
#include <jni.h>
#include <stdlib.h>
#include "appinfo.h"
JNIEXPORT jstring JNICALL Java_com_losileeya_getapkinfo_JNIUtils_getPackname(JNIEnv *env, jobject clazz, jobject obj)
{
jclass native_class = env->GetObjectClass(obj);
jmethodID mId = env->GetMethodID(native_class, "getPackageName", "()Ljava/lang/String;");
jstring packName = static_cast<jstring>(env->CallObjectMethod(obj, mId));
return packName;
}

JNIEXPORT jstring JNICALL Java_com_losileeya_getapkinfo_JNIUtils_getSignature(JNIEnv *env, jobject clazz, jobject obj)
{
jclass native_class = env->GetObjectClass(obj);
jmethodID pm_id = env->GetMethodID(native_class, "getPackageManager", "()Landroid/content/pm/PackageManager;");
jobject pm_obj = env->CallObjectMethod(obj, pm_id);
jclass pm_clazz = env->GetObjectClass(pm_obj);
// 得到 getPackageInfo 方法的 ID
jmethodID package_info_id = env->GetMethodID(pm_clazz, "getPackageInfo","(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
jstring pkg_str = Java_com_losileeya_getapkinfo_JNIUtils_getPackname(env, clazz, obj);
// 获得应用包的信息
jobject pi_obj = env->CallObjectMethod(pm_obj, package_info_id, pkg_str, 64);
// 获得 PackageInfo 类
jclass pi_clazz = env->GetObjectClass(pi_obj);
// 获得签名数组属性的 ID
jfieldID signatures_fieldId = env->GetFieldID(pi_clazz, "signatures", "[Landroid/content/pm/Signature;");
jobject signatures_obj = env->GetObjectField(pi_obj, signatures_fieldId);
jobjectArray signaturesArray = (jobjectArray)signatures_obj;
jsize size = env->GetArrayLength(signaturesArray);
jobject signature_obj = env->GetObjectArrayElement(signaturesArray, 0);
jclass signature_clazz = env->GetObjectClass(signature_obj);
jmethodID string_id = env->GetMethodID(signature_clazz, "toCharsString", "()Ljava/lang/String;");
jstring str = static_cast<jstring>(env->CallObjectMethod(signature_obj, string_id));
char *c_msg = (char*)env->GetStringUTFChars(str,0);

return str;
}</jstring></jstring></stdlib.h></jni.h></stdio.h></code>

注意:要使用前得先声明,方法名直接从h文件考过来就好了,studio目前还是很操蛋的,对于jni的支持还是不很好。
步骤4:给项目添加Android.mk和Application.mk
此步骤显然也是不必要的,如果你需要生成so库添加一下也好,为什么不呢考过去改一下就好了,如果你不写这2文件也是没有问题的,因为debug下也是有这些so库的。
好吧,勉强看一下这2货:
Android.mk
?

1
2
3
4
5

<code class="hljs ruby">LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := JNI_ANDROID
LOCAL_SRC_FILES =: appinfo.cpp
include $(BUILD_SHARED_LIBRARY)</code>

Application.mk
?

1
2

<code class="hljs makefile">APP_MODULES := JNI_ANDROID
APP_ABI := all</code>

android studio下External Tools的高级配置NDK一键javah,ndk生成so库
eclipse开发ndk的时候你可能就配置过javah,所以android studio也可以配置,是不是很兴奋:
Settings—>Tools—->External Tools就可以配置我们的终端命令了,别急一个一个来:
javah -jni 命令的配置(一键生成h文件)

我们先来看参数的配置:
1.Program:JDKPath\bin\javah.exe 这里配置的是javah.exe的路径(基本一致)
2.Parametes: -classpath . -jni -d MoleFileDir/src/main/jni FileClass这里指的是定位在Mole的jni文件你指定的文件执行jni指令<喎�"/kf/ware/vc/" target="_blank" class="keylink">vcD4NCgk8cD4zLldvcmtpbmc6PG5vYnI+TW9kdWxlRmlsZURpcjwvbm9icj5cc3JjXG1haW5camF2YTwvcD4NCjwvYmxvY2txdW90ZT4NCm5kay1idWlsZCjSu7z8yfqzyXNvv+IpDQo8cD48aW1nIGFsdD0="" src="/uploadfile/Collfiles/20160718/201607181017581505.png" title="\" />
我们同样来看参数的配置:
1.Program:E:\Android\sdk\android-ndk-r11b-windows-x86_64\android-ndk-r11b\ndk-build.cmd 这里配置的是ndk下的ndk-build.cmd的路径(自己去找下)
2.Working:MoleFileDir\src\main\
javap-s(此命令用于c掉java方法时方法的签名)

我们同样来看参数的配置:
1.Program:JDKPath\bin\javap.exe 这里配置的是javap.exe的路径(基本一致)
2.Parametes: -classpathMoleFileDir/build/intermediates/classes/debug -s FileClass 这里指的是定位到build的debug目录下执行 javap -s class文件
3.Working:MoleFileDir
这里介绍最常用的3个命令,对你的帮助应该还是很大的来看一下怎么使用:
javah -jni的使用:选中native文件—>右键—>External Tools—>javah -jni
效果如下:

是不是自动生成了包名.类名的.h文件。
ndk-build的使用:选中jni文件—>右键—>External Tools—>ndk-build
效果如下:

是不是一键生成了7种so库,你还想去debug目录下面去找吗
javap-s的使用:选中native文件—>右键—>External Tools—>javap-s
效果如下:

看见了每个方法下的descriptor属性的值就是你所要的方法签名。
3种一键生成的命令讲完了,以后你用到了什么命令都可以这样设置,是不是很给力。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
挖掘机上的字母标志是什么牌子的挖机 中国市场上挖掘机那国技术占优 微信个人标签经典短句最精辟的微信个性签名 肚子总是不消化,吃完东西不想上厕所。涨涨的 最近老是肚子疼,但疼一会儿就不疼了,就是不想上厕所,有时候五六天都没... ...但是不疼几乎每天早上都会不舒服,也不想上厕所,就是弄的你睡不着觉... 我的肚子老疼,但不是很想上厕所,最近有点拉肚子,可是一吃凉的东西肚子... 因为节目结缘却最终分开,姚沐希彭措的分手,暗示了娱乐圈什么问题? x79支持什么显卡 四叶草是不是三叶草? 帮了一两次小忙,同学老是要请客吃饭怎么办? 应不应该拒绝 android bionic 在ndk中吗 同学请我帮陪客人吃饭我应怎么做? android studio中怎么打包.so库文件 如何处理同学间互相请客吃饭的问题? 如何更新android studio中的ndk 同学请客吃饭就我没去,我要怎么办 为什么android studio 打包的程序进程不识别 同学请客吃饭的时候,我如果每次大家都去了就我不去的话会怎样呢? android 怎么把多个so文件编译成jar 同学请我吃饭的时候我如果每次都不去的话会怎样呢? build gradle中ndk怎么创建多个modulename 同学请客吃饭不去应该怎么回答? android studio nd开发到底要不要自己配置.mk文件 同学请客吃饭提议应该说些什么 android jni cmake和 mk的不同 同学请客我该怎么办? 如何为Android NDK的gradle构建文件中指定NDK 同学请我去吃饭的时候我如果直接不去的话会怎样呢? 如何提高android.mk的编译速度 android studio 怎么生成so 现在用androidstudio进行NDK开发成熟吗 迁移一个eclipse工程到AndroidStudio有哪些坑 Android studio 编译的时候gc overhead limit exceeded 如何引用android ndk自带的iconv Android Studio 为什么老是加载不起.so文件? 华为手机CPU构架32位的如何运行只支持64位的游戏? 请问为什么vivoz5x充电的时候现在变成了普通充电而不是闪充呢???_百度... 手机浏览器下载的缓存视频,怎么导出 vivo z5的充电口是什么接口? 我vivoz5手机充三小时才充满 才买了三周就 要充这么久是怎么回事?_百 ... vivoz5快充协议 怎样可以让vivoZ5手机充电变得很快? 手机里缓存的那些视频,怎样放到本地? VIVOz5是什么充电接口? 安卓手机的uc浏览器里的缓存视频,导出到电脑里,该怎么做? vivoz5可不可以用55w的充电器? 如何将手机里缓存的B站视频导出到电脑? vivoz5怎么快充? vivoz5能不能用z6的充电器?