摘要:开发中针对的书籍很少,也是出版的比较早的一本书,有些内容可能对现在的开发并不适用。但是书中介绍的内容比较全面,难度也不是很大,对于开发有很大帮助,特别是在开发的配置和代码规范上。
0x02 深入了解 Android NDKAndroid 开发中针对 NDK 的书籍很少,《Pro Android C++ with the NDK》也是出版的比较早的一本书,有些内容可能对现在的开发并不适用。但是书中介绍的内容比较全面,难度也不是很大,对于 NDK 开发有很大帮助,特别是在 NDK 开发的配置和代码规范上。
创建项目时 Android.mk 文件的构建:Android.mk配置参数
ndk-build 脚本参数
#NDK 项目位置 ndk-build -C /path/to/the/project #强制重构所有代码 ndk-build -B #清除生成的二进制文件和目标文件 ndk-build clean #并行构建命令 ndk-build -j 40x03 用 JNI 实现与原生代码通信
jni 的开发基础知识,参考:
NDK开发 - JNI开发流程
NDK开发 - JNI数据类型与Java数据类型映射关系
NDK开发 - JNI基本数据和字符串处理
NDK开发 - JNI数组数据处理
NDK开发 - C/C++ 访问 Java 变量和方法
NDK开发-JNI 局部引用、全局引用和弱全局引用
0x05 日志、调试及故障处理 5.1 原生日志 API//头文件 #include5.2 重定向 Android 日志//Android.mk LOCAL_LALIBS += -llog _android_log_write(ANDROID_LOG_DEBUG, "hello-jni", "debug log.") //多参数封装 static void logMessage(JNIEnv *env, jobject obj, const char *format, ...) { static jmethodID methodID = NULL; if (NULL == methodID) { jclass clazz = env->GetObjectClass(obj); methodID = env->GetMethodID(clazz, "logMessage", "(Ljava/lang/String;)V"); env->DeleteLocalRef(clazz); } if(methodID != NULL) { char buffer[MAX_LOG_MSG_LENGTH]; va_list ap; va_start(ap, format); //指向 format 后可变参数的地址 vsnprintf(buffer, MAX_LOG_MSG_LENGTH, format, ap); va_end(ap); jstring message = env->NewStringUTF(buffer); if (message != NULL) { env->CallVoidMethod(obj, methodID, message); env->DeleteLocalRef(message); } } }
adb shell stop adb shell setprop log.redirect-stdio true adb shell start5.3 故障处理
1.堆栈分析
#ndk-stack adb logcat | ndk-stack -sym obj/local/armeabi #arm-linux-androideabi-addr2line arm-linux-androideabi-addr2line -e obj/local/armeabi-v7a/libtongdun.so 0002197e
2.启用 CheckJNI:
adb shell setprop debug.checkjni 15.4 内存问题
1.打开 libc 调试模式
adb shell setprop libc.debug.malloc 1 adb shell stop adb shell start
2.strace 工具
#获取进程 adb shell ps | grep packagename #附加进程 adb shell strace -v -p0x07 原生线程
源码地址: ndk-pro/threads
1.POSIX 线程返回结果
//1.线程句柄 2.返回值指针 int pthread_join(pthread_t thread, void** ret_val);
2.POSIX 线程同步
static pthread_mutex_t mutex; //初始化 int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexarrt_t* attr); //锁定 int pthread_mutex_lock(pthread_mutex_t* mutex); //解锁 int pthread_mutex_unlock(pthread_mutex_t* mutex); //销毁 int pthread_mutex_destroy(pthread_mutex_t* mutex);
3.使用信号量同步 POSIX 线程
//头文件 #include0x08/09/10 POSIX Socket API//初始化 extern int sem_init(sem_t* sem, int pshared, unsigned int value); //锁定信号 extern int sem_wait(sem_t* sem); //解锁 extern int sem_post(sem_t* sem); //销毁 extern int sem_destroy(sem_t* sem);
TCP && UDP
源码地址: pro-ndk/echo
0x11 支持 C++ 11.1 支持的 C++ 运行库C++系统运行库 不支持:C++标准库、 异常支持库、 RTTI 支持
GAbi++、 STLport、 GUN STL
//Application.mk APP_STL := system //默认 APP_STL := gabi++_static APP_STL := gabi++_shared APP_STL := stlport_static APP_STL := stlport_shared APP_STL := gunstl_static APP_STL := gunstl_shared //1.项目只有一个单一的原生模块时支持静态库 //2.项目中包含多个原生模块时使用动态库 //3.动态库使用时需要先加载 System.loadLibrary(“strport_shared”)11.4 C++支持异常
//单个模块 Android.mk LOCAL_CPP_FEATURES += exceptions //支持所有原生模块 Application.mk APP_CPPFLAGS += -fexceptions11.5 C++ RTTI 支持(Run-Time Type Information)
在运行库展示对象类型信息,只要用于执行安全类型转化。
//单个模块 Android.mk LOCAL_CPP_FEATURES += rtti //支持所有原生模块 Application.mk APP_CPPFLAGS += -frtti11.6 C++ 标准库
容器
序列
vector 支持随机访问,末尾常量插入删除 其他线性
deque 与 vector支持随机访问 选择实现队列的基础
list 双向列表
slist 单项链表
关联容器
排序关联容器 操作复杂度不超过对数阶
set 已排序,不重复
map 键值对,不重复
multiset 已排序,多重关联,允许重复
multimap 对拥有相同键值的元素数量不限制
哈希关联容器 查询时间快
hashed_set 不重复
hash_map
hash_multiset 允许重复
hash_multimap 允许重复
适配器
stack 堆栈 LIFO (Last In First Out)
queue 队列 FIFO (First In First Out)
String
迭代器
11.8 C++ 运行库调试模式//GUN STL 调试模式 LOCAL_CFLAGS += -D_GLIBCXX_DEBUG //STLport 调试模式 LOCAL_CFLAGS += -D_STLP_DEBUG //日志重定向到 Android 日志 LOCAL_CFLAGS += -D_STLP_DEBUG LOCAL_CFLAGS += -D_STLP_DEBUG_MESSAGE LOCAL_LDLIBS += —llog void __stl_debug_message(const char* format_str, …){ va_list ap; va_start(ap, format_str); __android_log_vprint(ANDROID_LOG_FATAL, “STLport”, format_str, ap); va_end(ap); }0x12 原生图形 API
源码地址: ndk-pro/abiplayer
0x14 程序概要分析和 NEON 优化android-ndk-profiler
NEON 指令:并不是所有基于 ARM-V7a 的设备都支持 NEON 指令
原文地址:NDK 高级编程(笔记)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/13823.html
摘要:其实,这种时候,需要做的是马上买空气净化器,任何一款都好,哪怕是净化能力差一点的,也能解决当前的主要问题,更好的净化器带给你的净化效果的提升,不过是多一点边际收益。 前言 说到底,是自己的选择问题。 三百六十行,哪行容易? 但关键是自己的心态,如果工作成了你的负担和困扰,你得有跳出来的...
摘要:昨天有个小学弟给我发来微信,说他现在有点后悔选择开发了,月月光不说,还加班特别严重,平时也没有属于自己的时间去学习,问我刚毕业的时候是不是这样。每天回到出租屋都是倒头就睡,非常累,也没有其他时间提升自己的技术。 昨天有个小学弟给我发来微信,说他现在有点后悔选择Android开发了,月月光不说...
摘要:所以当我们访问声明的对象时,如果对象还没有初始化,就会返回一个异常。所以对于编译后的代码,并不会对性能和运行结果产生影响。 如下图所示,通过提取编译后的代码,「可以看到 playerAnimation 其实被转变成了 Animation? 的可空对象」,而当 playerAnimation 被调用时,通过 ge...
摘要:在舒伯的生涯阶段里有个确立阶段,岁岁。知识技术安卓程序员需要掌握编程语言应用框架开发工具等这些具体的知识和技术。技术能力与阅历对安卓程序员来讲,知识技术是一方面,是容易习得的,是较浅的层面。 大龄程序员的界定 老早网上有人说,安卓开发干不过30岁,后来又有人说干不过35岁,后来又有人说干不过...
摘要:从邮件内容来看,估计和权限知识学习笔记掘金最近在项目上因为运行时权限吃了亏,发现之前对运行时权限的理解不足,决定回炉重造,重新学习一下。 浅谈 Android Service - 掘金前言:本文所写的是博主的个人见解,如有错误或者不恰当之处,欢迎私信博主,加以改正!原文链接 ,demo链接 Serviec(服务)简述 什么是ServiceService 是一个可以在后台执行长时间运行操...
阅读 440·2023-04-26 02:03
阅读 830·2021-11-23 09:51
阅读 812·2021-10-14 09:42
阅读 1525·2021-09-13 10:23
阅读 760·2021-08-27 13:12
阅读 716·2019-08-30 11:21
阅读 892·2019-08-30 11:14
阅读 787·2019-08-30 11:09