Android 开发艺术探索笔记(23)

函数名的格式遵循:JAVA+包名+类名+方法名,比如get方法这里就是Java_com_ryg_JniTest_get(JNIEnv *,jobject),一些参数定义如下:

这里写图片描述

  1. 实现JNI方法

这里分别用C和C++来实现JNI方法。首先在工程的主目录下创建一个子目录,名称随意,这里取名jni目录,然后将之前通过javah生成的头文件com_ryg_JniTest.h复制到jni目录下,接着创建test.cpp和test.c两个文件。

这里写图片描述

这里写图片描述

可以看出用C或C++代码类似,主要的不同时对env的处理上

  1. 编译so库并在Java中调用

so库的编译用到gcc,切换到jni目录中,对于test.cpp和test.c来说,它们的编译指令如下:

这里写图片描述

这里写图片描述

其中的/usr…amd64是本地JDK安装路径,libjni-test.so是生成so库的名字,其中lib和.so是不需要明确指出的。so库编译完之后就可以在java中调用了,这里通过Java指令来执行Java程序,切换主目录,执行如下指令:java -Djava.library.path=jni com.ryg.JniTest,其中-Djava.library.path=jni指明了so库的路径。首先采用C++产生的so库,程序运行后产生日志如下所示:

这里写图片描述

然后是C:

这里写图片描述

通过上面日志可以发现,在Java中成功的调用了C/C++代码,这就是JNI的典型工作流程。、

NDK的开发流程

NDK的开发是基于JNI的,主要有以下几个步骤:

  1. 下载并配置NDK

设置完变量后,ndk-build命令就可以使用了,可以通过它来编译so库

  1. 创建一个Android项目,并声明所需的native方法

这里写图片描述

  1. 实现Android项目中所声明的native方法

在外部创建一个名为jni的目录,然后在jni的目录下创建3个文件:test.cpp、Android.mk和Application.mk

这里写图片描述

这里写图片描述

在Android.mk中LOCAL_MODUEL表示模块的名称,LOCAL_SRC_FILES表示需要参与编译的源文件。Application.mk中常用的配置项是APP_ABI,它表示CPU架构平台的类型,目前市面上常用的架构为armeabi,x86和mips,移动端是armeabi,这也是大部分APK只包含armeabi类型的so库的原因。默认情况下NDK会编译产生各种CPU的so库,通过APP_ABI可以指定so库的CPU类型,这样NDK就只会编译armeabi平台下的so库,而all则表示编译所有CPU平台的so库。

  1. 切换到jni的父目录,然后通过ndk-build命令编译产生so库

这时候NDK会创建一个和jni目录平级的目录libs,下面放的so库的目录,然后在app/src/main中创建一个名为jniLibs的目录,将生成的so库复制到jniLibs下,然后通过Android Studio编辑运行即可。

JNI的类型签名

JNI的类型签名标识了一个特定的Java类型,这个类型既可以是类和方法,也可以是数据类型。

类的签名比较简单,就是“L+包名+类名+;”的形式,并将.替换为/,比如Ljava.lang.String替换为java/lang/String; ,类型签名的基本数据类型以及数组如下:

这里写图片描述

这里写图片描述

方法的签名为 (参数类型签名)+返回值类型签名,如下:

这里写图片描述

JNI调用Java方法的流程

JNI调用Java方法的流程是先通过类名找到类,然后根据方法名找到方法的ID,最后就可以调用这个方法了。如果调用的是Java的非静态方法,则要先构造出类的对象然后才调用它,比静态方法多这一步而已。

Android性能优化


布局优化

尽量减少布局文件的层级,因为这样布局的绘制就少了。

首先要删除布局中无用的控件和层级,其次有选择的使用性能较低的ViewGroup,比如RelativeLayout,如果布局中既可以使用LinearLayout也可以使用RelativeLayout,那就使用LinearLayout,因为RelativeLayout功能相对复杂,它的布局需要花更多时间。

布局优化的另一个手段是采用< include>标签,< merge>标签和ViewStub,< include>用于布局的重用,< merge>一般和< include>配合使用,它可以减少布局的层级,而ViewStub则提供了按需加载的功能,当需要时才会将ViewStub中的布局加载到内存,这提高了程序的初始化效率。

< include>用的比较多比较熟悉,就不讲了,而< merge>的作用是优化< include>,比如一个布局文件中用的是竖直方向的LinearLayout,里面用了一个< include>里面也包含了一个竖直方向的LinearLayout,显然,后者定义的LinearLayout是没有必要的,通过< merge>就可以去除这个多余的标签。

ViewStub继承了View,它非常轻量级且宽高都为0,因此它本身不参与任何布局和绘制过程,它的意义在于按需加载所需的布局文件,在实际开发中,很多布局文件在正常情况下不会显示,比如网络异常,这个时候就没有必要在整个界面初始化的时候就将其加载进来,而是使用ViewStub,有需要的时候再加载。下面是一个示例:

这里写图片描述

inflatedId是这个ViewStub的根ID,当需要加载的时候,用下面两个方法来加载:

这里写图片描述或者

这里写图片描述

绘制优化

首先在onDraw中不要创建新的局部对象,这是因为onDraw会被频繁调用,就会在一瞬间产生大量对象,导致执行效率大大降低。

另一方面,不要再onDraw中做耗时操作,也不能执行成千上万次的循环操作。

ListView和Bitmap的优化

ListView的优化就是采用ViewHolder并避免在getView中做太多耗时操作;根据滑动速率涞开启和关闭异步任务;开启硬件加速。

Bitmap就是之前讲的一些缓存策略什么的。

线程优化

线程优化就是采用线程池,避免内存中存在大量的Thread。

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助

因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
*

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 10
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
本书是一本Android进阶类书籍,采用理论、源码和实践相结合的方式来阐述高水准的Android应用开发要点。本书从三个方面来组织内容。第一,介绍Android开发者不容易掌握的一些知识点;第二,结合Android源代码和应用层开发过程,融会贯通,介绍一些比较深入的知识点;第三,介绍一些核心技术和Android的性能优化思想。 第1章 Activity的生命周期和启动模式 1 1.1 Activity的生命周期全面分析 1 1.1.1 典型情况下的生命周期分析 2 1.1.2 异常情况下的生命周期分析 8 1.2 Activity的启动模式 16 1.2.1 Activity的LaunchMode 16 1.2.2 Activity的Flags 27 1.3 IntentFilter的匹配规则 28 第2章 IPC机制 35 2.1 Android IPC简介 35 2.2 Android中的多进程模式 36 2.2.1 开启多进程模式 36 2.2.2 多进程模式的运行机制 39 2.3 IPC基础概念介绍 42 2.3.1 Serializable接口 42 2.3.2 Parcelable接口 45 2.3.3 Binder 47 2.4 Android中的IPC方式 61 2.4.1 使用Bundle 61 2.4.2 使用文件共享 62 2.4.3 使用Messenger 65 2.4.4 使用AIDL 71 2.4.5 使用ContentProvider 91 2.4.6 使用Socket 103 2.5 Binder连接池 112 2.6 选用合适的IPC方式 121 第3章 View的事件体系 122 3.1 View基础知识 122 3.1.1 什么是View 123 3.1.2 View的位置参数 123 3.1.3 MotionEvent和TouchSlop 125 3.1.4 VelocityTracker、GestureDetector和Scroller 126 3.2 View的滑动 129 3.2.1 使用scrollTo/scrollBy 129 3.2.2 使用动画 131 3.2.3 改变布局参数 133 3.2.4 各种滑动方式的对比 133 3.3 弹性滑动 135 3.3.1 使用Scroller 136 3.3.2 通过动画 138 3.3.3 使用延时策略 139 3.4 View的事件分发机制 140 3.4.1 点击事件的传递规则 140 3.4.2 事件分发的源码解析 144 3.5 View的滑动冲突 154 3.5.1 常见的滑动冲突场景 155 3.5.2 滑动冲突的处理规则 156 3.5.3 滑动冲突的解决方式 157 第4章 View的工作原理 174 4.1 初识ViewRoot和DecorView 174 4.2 理解MeasureSpec 177 4.2.1 MeasureSpec 177 4.2.2 MeasureSpec和LayoutParams的对应关系 178 4.3 View的工作流程 183 4.3.1 measure过程 183 4.3.2 layout过程 193 4.3.3 draw过程 197 4.4 自定义View 199 4.4.1 自定义View的分类 200 4.4.2 自定义View须知 201 4.4.3 自定义View示例 202 4.4.4 自定义View的思想 217 第5章 理解RemoteViews 218 5.1 RemoteViews的应用 218 5.1.1 RemoteViews在通知栏上的应用 219 5.1.2 RemoteViews在桌面小部件上的应用 221 5.1.3 PendingIntent概述 228 5.2 RemoteViews的内部机制 230 5.3 RemoteViews的意义 239 第6章 Android的Drawable 243 6.1 Drawable简介 243 6.2 Drawable的分类 244 6.2.1 BitmapDrawable 244 6.2.2 ShapeDrawable 247 6.2.3 LayerDrawable 251 6.2.4 StateListDrawable 253 6.2.5 LevelListDrawable 255 6.2.6 TransitionDrawable 256 6.2.7 Ins

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值