①DEX加固:对DEX文件进行加壳防护,防止被静态反编译工具破解获取源码
②Unity3d脚本保护:对U3D脚本文件进行加壳保护,对DLL文件进行保护
③防调试器:防止通过使用调试器工具对应用进行非法破解
④SO加密保护:对SO里面的逻辑进行分析,保护Native代码不被逆向分析
⑤防二次打包:保护应用在被非法二次打包后不能正常运行
⑥内存防Dump保护:防止通过在内存中破解,从而获取源代码
我也遇到了楼主的问题,然后百度了一下,最近好像出现好几个这样的案例,但是没有特别好的解决办法;出现这样的问题,关闭explorerexe进程,重新载入就可以了,不过可能以后还是会出现。
android ndk location的意思是android ndk location开发包所在的路径。
Android NDK 是在SDK前面又加上了“原生”二字,即Native Development Kit,因此又被Google称为“NDK”。
众所周知,Android程序运行在Dalvik虚拟机中,NDK允许用户使用类似C / C++之类的原生代码语言执行部分程序。
NDK包括了:
从C / C++生成原生代码库所需要的工具和build files。
将一致的原生库嵌入可以在Android设备上部署的应用程序包文件(application packages files ,即apk文件)中。
支持所有未来Android平台的一系列原生系统头文件和库
Android进程间通信的几种方式 定义多进程
第一:Android应用中使用多进程只有一个办法(用NDK的fork来做除外),就是在AndroidManifestxml中声明组件时,用android:process属性来指定。
不知定process属性,则默认运行在主进程中,主进程名字为包名。
android:process = package:remote,将运行在package:remote进程中,属于全局进程,其他具有相同shareUID与签名的APP可以跑在这个进程中。
android:process = :remote ,将运行在默认包名:remote进程中,而且是APP的私有进程,不允许其他APP的组件来访问。
第二:多进程引发的问题
静态成员和单例失效:每个进程保持各自的静态成员和单例,相互独立。
线程同步机制失效:每个进程有自己的线程锁。
SharedPreferences可靠性下降:不支持并发写,会出现脏数据。
Application多次创建:不同进程跑在不同虚拟机,每个虚拟机启动会创建自己的Application,自定义Application时生命周期会混乱。
综上,不同进程拥有各自独立的虚拟机,Application,内存空间,由此引发一系列问题。
第三: 进程间通信
Bundle/Intent传递数据:
可传递基本类型,String,实现了Serializable或Parcellable接口的数据结构。Serializable是Java的序列化方法,Parcellable是Android的序列化方法,前者代码量少(仅一句),但I/O开销较大,一般用于输出到磁盘或网卡;后者实现代码多,效率高,一般用户内存间序列化和反序列化传输。
文件共享:
对同一个文件先后写读,从而实现传输,Linux机制下,可以对文件并发写,所以要注意同步。顺便一提,Windows下不支持并发读或写。
Messenger:
Messenger是基于AIDL实现的,服务端(被动方)提供一个Service来处理客户端(主动方)连接,维护一个Handler来创建Messenger,在onBind时返回Messenger的binder。
双方用Messenger来发送数据,用Handler来处理数据。Messenger处理数据依靠Handler,所以是串行的,也就是说,Handler接到多个message时,就要排队依次处理。
AIDL:
AIDL通过定义服务端暴露的接口,以提供给客户端来调用,AIDL使服务器可以并行处理,而Messenger封装了AIDL之后只能串行运行,所以Messenger一般用作消息传递。
通过编写aidl文件来设计想要暴露的接口,编译后会自动生成响应的java文件,服务器将接口的具体实现写在Stub中,用iBinder对象传递给客户端,客户端bindService的时候,用asInterface的形式将iBinder还原成接口,再调用其中的方法。
ContentProvider:
系统四大组件之一,底层也是Binder实现,主要用来为其他APP提供数据,可以说天生就是为进程通信而生的。自己实现一个ContentProvider需要实现6个方法,其中onCreate是主线程中回调的,其他方法是运行在Binder之中的。自定义的ContentProvider注册时要提供authorities属性,应用需要访问的时候将属性包装成Uriparse("content://authorities")。还可以设置permission,readPermission,writePermission来设置权限。 ContentProvider有query,delete,insert等方法,看起来貌似是一个数据库管理类,但其实可以用文件,内存数据等等一切来充当数据源,query返回的是一个Cursor,可以自定义继承AbstractCursor的类来实现。
Socket:
学过计算机网络的对Socket不陌生,所以不需要详细讲述。只需要注意,Android不允许在主线程中请求网络,而且请求网络必须要注意声明相应的permission。然后,在服务器中定义ServerSocket来监听端口,客户端使用Socket来请求端口,连通后就可以进行通信。
android ndk调用第三方的so库文件的步骤如下:
1将SO文件直接放到libs/armeabi下,然后代码中SystemloadLibrary("xxx");再public native static int xxx_xxx_xxx();接下来就可以直接调用xxx_xxx_xxx()方法;
2第二种方案,创建自己的SO文件,在自己的SO文件里调用第三方SO,再在程序中调用自己的SO,这种比较复杂,需要建java类文件,生成h文件,编写C源文件include之前生成的h文件并实现相应方法,最后用android NDK开发包中的ndk-build脚本生成对应的so共享库;
正式开始这个话题之前,先简单介绍一下什么是NDK和JNI,部分内容来自网络
Android NDK是什么,为什么我们要用NDK?
Android NDK 是在SDK前面又加上了“原生”二字,即Native Development Kit,因此又被Google称为“NDK”。众所周知,Android程序运行在Dalvik虚拟机中,NDK允许用户使用类似C / C++之类的原生代码语言执行部分程序。NDK包括了:
•从C / C++生成原生代码库所需要的工具和build files。
•将一致的原生库嵌入可以在Android设备上部署的应用程序包文件(application packages files,即apk文件)中。
•支持所有未来Android平台的一些列原生系统头文件和库
为何要用到NDK?概括来说主要分为以下几种情况:
•代码的保护,由于apk的java层代码很容易被反编译,而C/C++库反汇难度较大。
•在NDK中调用第三方C/C++库,因为大部分的开源库都是用C/C++代码编写的。
•便于移植,用C/C++写的库可以方便在其他的嵌入式平台上再次使用。
Android JNI是什么?和NDK是什么关系?
Java Native Interface(JNI)标准是java平台的一部分,它允许Java代码和其他语言写的代码进行交互。JNI是本地编程接口,它使得在 Java 虚拟机(VM) 内部运行的 Java 代码能够与用其它编程语言(如 C、C++和汇编语言)编写的应用程序和库进行交互 *** 作。
简单来说,可以认为NDK就是能够方便快捷开发so文件的工具。JNI的过程比较复杂,生成so需要大量 *** 作,而NDK就是简化了这个过程。
NDK的异常会不会导致程序Crash,NDK的常见的有哪些类型异常?
NDK编译生成的so文件作为程序的一部分,在运行发生异常时同样会造成程序崩溃。不同于Java代码异常造成的程序崩溃,在NDK的异常发生时,程序在Android设备上都会立即退出,即通常所说的闪退,而不会d出“程序xxx无响应,是否立即关闭”之类的提示框。
NDK是使用C/C++来进行开发的,熟悉C/C++的程序员都知道,指针和内存管理是最重要也是最容易出问题的地方,稍有不慎就会遇到诸如内存无效访问、无效对象、内存泄露、堆栈溢出等常见的问题,最后都是同一个结果:程序崩溃。例如我们常说的空指针错误,就是当一个内存指针被置为空(NULL)之后再次对其进行访问;另外一个经常出现的错误是,在程序的某个位置释放了某个内存空间,而后在程序的其他位置试图访问该内存地址,这就会产生一个无效地址错误。常见的错误类型如下:
•初始化错误
•访问错误
•数组索引访问越界
•指针对象访问越界
•访问空指针对象
•访问无效指针对象
•迭代器访问越界
•内存泄露
•参数错误
•堆栈溢出
•类型转换错误
•数字除0错误
NDK错误发生时,我们能拿到什么信息?
利用Android NDK开发本地应用的时候,几乎所有的程序员都遇到过程序崩溃的问题,但它的崩溃会在logcat中打印一堆看起来类似天书的堆栈信息,让人举足无措。单靠添加一行行的打印信息来定位错误代码做在的行数,无疑是一件令人崩溃的事情。在网上搜索“Android NDK崩溃”,可以搜索到很多文章来介绍如何通过Android提供的工具来查找和定位NDK的错误,但大都晦涩难懂。下面以一个实际的例子来说明,首先生成一个错误,然后演示如何通过两种不同的方法,来定位错误的函数名和代码行。
首先,看我们在hello-jni程序的代码中做了什么(有关如何创建或导入工程,此处略),看下图:在JNI_OnLoad()的函数中,即so加载时,调用willCrash()函数,而在willCrash()函数中, std::string的这种赋值方法会产生一个空指针错误。这样,在hello-jni程序加载时就会闪退。我们记一下这两个行数:在61行调用了willCrash()函数;在69行发生了崩溃。
下面来看看发生崩溃(闪退)时系统打印的logcat日志:
[plain] view plain copy
1
2 Build fingerprint: 'vivo/bbk89_cmcc_jb2/bbk89_cmcc_jb2:421/JOP40D/1372668680:user/test-keys'
3 pid: 32607, tid: 32607, name: xamplehellojni >>> comexamplehellojni <<<
4 signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000000
5 r0 00000000 r1 beb123a8 r2 80808080 r3 00000000
6 r4 5d635f68 r5 5cdc3198 r6 41efcb18 r7 5d62df44
7 r8 4121b0c0 r9 00000001 sl 00000000 fp beb1238c
8 ip 5d635f7c sp beb12380 lr 5d62ddec pc 400e7438 cpsr 60000010
9
10 backtrace:
11 #00 pc 00023438 /system/lib/libcso
12 #01 pc 00004de8 /data/app-lib/comexamplehellojni-2/libhello-jniso
13 #02 pc 000056c8 /data/app-lib/comexamplehellojni-2/libhello-jniso
14 #03 pc 00004fb4 /data/app-lib/comexamplehellojni-2/libhello-jniso
15 #04 pc 00004f58 /data/app-lib/comexamplehellojni-2/libhello-jniso
16 #05 pc 000505b9 /system/lib/libdvmso
17 #06 pc 00068005 /system/lib/libdvmso
18 #07 pc 000278a0 /system/lib/libdvmso
19 #08 pc 0002b7fc /system/lib/libdvmso
20 #09 pc 00060fe1 /system/lib/libdvmso
21 #10 pc 0006100b /system/lib/libdvmso
22 #11 pc 0006c6eb /system/lib/libdvmso
23 #12 pc 00067a1f /system/lib/libdvmso
24 #13 pc 000278a0 /system/lib/libdvmso
25 #14 pc 0002b7fc /system/lib/libdvmso
26 #15 pc 00061307 /system/lib/libdvmso
27 #16 pc 0006912d /system/lib/libdvmso
28 #17 pc 000278a0 /system/lib/libdvmso
29 #18 pc 0002b7fc /system/lib/libdvmso
30 #19 pc 00060fe1 /system/lib/libdvmso
31 #20 pc 00049ff9 /system/lib/libdvmso
32 #21 pc 0004d419 /system/lib/libandroid_runtimeso
33 #22 pc 0004e1bd /system/lib/libandroid_runtimeso
34 #23 pc 00001d37 /system/bin/app_process
35 #24 pc 0001bd98 /system/lib/libcso
36 #25 pc 00001904 /system/bin/app_process
37
38 stack:
39 beb12340 012153f8
40 beb12344 00054290
41 beb12348 00000035
42 beb1234c beb123c0 [stack]
43
44……
如果你看过logcat打印的NDK错误时的日志就会知道,我省略了后面很多的内容,很多人看到这么多密密麻麻的日志就已经头晕脑胀了,即使是很多资深的Android开发者,在面对NDK日志时也大都默默的选择了无视。
“符号化”NDK错误信息的方法
其实,只要你细心的查看,再配合Google 提供的工具,完全可以快速的准确定位出错的代码位置,这个工作我们称之为“符号化”。需要注意的是,如果要对NDK错误进行符号化的工作,需要保留编译过程中产生的包含符号表的so文件,这些文件一般保存在$PROJECT_PATH/obj/local/目录下。
第一种方法:ndk-stack
这个命令行工具包含在NDK工具的安装目录,和ndk-build和其他一些常用的NDK命令放在一起,比如在我的电脑上,其位置是/android-ndk-r9d/ndk-stack。根据Google官方文档,NDK从r6版本开始提供ndk-stack命令,如果你用的之前的版本,建议还是尽快升级至最新的版本。使用ndk –stack命令也有两种方式
使用ndk-stack实时分析日志
在运行程序的同时,使用adb获取logcat日志,并通过管道符输出给ndk-stack,同时需要指定包含符号表的so文件位置;如果你的程序包含了多种CPU架构,在这里需求根据错误发生时的手机CPU类型,选择不同的CPU架构目录
第二种方法:使用addr2line和objdump命令
这个方法适用于那些,不满足于上述ndk-stack的简单用法,而喜欢刨根问底的程序员们,这两个方法可以揭示ndk-stack命令的工作原理是什么,尽管用起来稍微麻烦一点,但是可以满足一下程序员的好奇心。
先简单说一下这两个命令,在绝大部分的linux发行版本中都能找到他们,如果你的 *** 作系统是linux,而你测试手机使用的是Intel
x86系列,那么你使用系统中自带的命令就可以了。然而,如果仅仅是这样,那么绝大多数人要绝望了,因为恰恰大部分开发者使用的是Windows,而手机很有可能是armeabi系列。
别急,在NDK中自带了适用于各个 *** 作系统和CPU架构的工具链,其中就包含了这两个命令,只不过名字稍有变化,你可以在NDK目录的toolchains目录下找到他们。以我的Mac电脑为例,如果我要找的是适用于armeabi架构的工具,那么他们分别为arm-linux-androideabi-addr2line和arm-linux-androideabi-objdump;
Googlecn上介绍NDK的说明如下;
原生开发工具包 (NDK) 是一组可让您在 Android 应用中利用 C 和 C++ 代码的工具。 可用以从您自己的源代码构建,或者利用现有的预构建库。
NDK 不适用于大多数初学的 Android 编程者,对许多类型的 Android 应用没什么价值。 因为它不可避免地会增加开发过程的复杂性,所以通常不值得使用。 但如果您需要执行以下 *** 作,它可能很有用:
从设备获取卓越性能以用于计算密集型应用,例如游戏或物理模拟。
重复使用您自己或其他开发者的 C 或 C++ 库。
照这样说,你不用c/c++就不需要,但是你用qt那肯定是用c++来开发
以上就是关于android studio里的ndk toolchains问题,请问怎么解决全部的内容,包括:android studio里的ndk toolchains问题,请问怎么解决、NDK的文件名或扩展名太长问题,怎么解决、android ndk location什么意思等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)