- 博客(201)
- 资源 (19)
- 收藏
- 关注
原创 Android includeFontPadding属性
Android的includeFontPadding属性控制文本是否包含顶部/底部额外空白,默认开启以兼容特殊字符。可通过XML或代码设置为false来消除空白,也可通过主题样式全局配置。对于中文优化有限,需注意低版本兼容性。开发者可自定义TextView基类自动关闭该属性,但需权衡特殊字符显示需求与布局空间节省。
2025-07-03 10:05:12
391
原创 Android Camera2 + OpenGL离屏渲染示例
本文介绍了在Android中使用EGL环境初始化GL线程并创建SurfaceTexture的方法。首先通过GLThread类初始化EGL显示、配置和上下文,创建离屏渲染的虚拟Surface。然后在GL线程中生成纹理ID并创建SurfaceTexture,设置帧可用监听器处理图像数据。最后将SurfaceTexture转换为Surface用于相机输出配置。关键注意事项包括:SurfaceTexture操作必须在同一线程完成,updateTexImage()需在创建线程调用,以及资源释放时需销毁EGL上下文。该
2025-07-03 10:05:10
1362
原创 Android OpenGL图像绘制支持多格式
本文介绍了一种基于OpenGL ES 3.0的Android图像绘制实现方案,支持灰度图、RGB、YUV420和YUYV格式。方案通过多纹理绑定和着色器转换实现高效GPU渲染,主要步骤包括:创建GLSurfaceView作为渲染容器,自定义Renderer接口实现,多纹理管理(根据格式创建1-3个纹理),以及在片段着色器中完成格式转换。核心代码展示了顶点/纹理坐标缓冲区的初始化、着色器编译、纹理创建与绑定等关键实现,通过统一着色器处理多种格式转换,简化了绘制流程。
2025-07-02 14:38:36
543
原创 Kotlin Data包含ByteArray类型
摘要:在Kotlin中使用包含ByteArray的数据类时,需特别注意自动生成方法的行为差异。由于默认的equals()和hashCode()会基于数组引用而非内容进行比较,需要手动重写这三个方法:使用contentEquals()比较数组内容,contentHashCode()生成哈希值,contentToString()输出可读字符串。这种处理确保了数据类能正确比较和显示ByteArray的实际内容。
2025-07-02 14:38:30
295
原创 Android开发通过ViewModel实现两个Activity之间的数据传递
在Android开发中,通过Kotlin实现跨Activity数据共享需要借助全局ViewModel。关键步骤包括:1)创建Application级别的ViewModelStore,使其生命周期与Application一致;2)定义共享ViewModel类,使用LiveData管理数据;3)各Activity通过Application获取同一ViewModel实例进行数据交互。这种方法突破了ViewModel默认的Activity作用域限制,实现了全局数据共享,同时保持了ViewModel的生命周期管理优势
2025-07-01 13:54:48
599
原创 Android开发渠道包配置指定jniLibs目录
Android开发中可以通过Gradle配置为不同渠道包指定专属jniLibs目录。在项目结构中为每个渠道(如flavorA、flavorB)创建单独的jniLibs目录,然后在build.gradle中通过sourceSets配置对应路径。编译时系统会优先使用渠道包目录的so文件,若存在相同ABI则覆盖main目录的文件,未指定的仍使用main目录资源。这种方式实现了渠道包原生库的差异化配置,同时保持代码结构清晰。
2025-07-01 13:54:45
123
原创 Linux环境编译Android App
摘要:本文介绍了在Linux环境下编译Android项目的完整流程。首先需要安装JDK和配置Android SDK(包括设置镜像源和环境变量),然后使用gradlew命令进行项目编译。针对常见的Gradle下载失败问题,提供了手动下载并替换缓存文件的解决方案。最后建议在构建失败时清理缓存并重启构建。整个过程包含详细的命令行操作和常见错误处理方法,适用于Linux系统下的Android开发环境搭建。
2025-06-30 10:56:20
1002
原创 灰度图转YUV420格式
摘要:灰度图转换为YUV420格式的关键在于处理缺失的色度分量。灰度图仅含亮度(Y),需补充分辨率减半的中性U/V值(128)。YUV420格式中Y保留原分辨率,U/V为1/4大小。转换步骤包括:1)直接使用灰度数据作为Y平面;2)创建填充128的U/V平面;3)按I420(Y+U+V)或NV21(Y+VU交替)格式合并数据。代码示例展示了通过ByteBuffer高效合并YUV分量的方法,适用于实时视频处理场景。
2025-06-30 10:56:15
232
原创 Android开发中使用LeakCanary
LeakCanary 是 Android 开发中用于检测内存泄漏的强大工具,能够帮助开发者快速定位和修复资源泄漏问题。从版本 2.0 开始,LeakCanary 支持自动集成,只需在 build.gradle 中添加依赖即可。它默认监控常见对象(如 Activity、Fragment 等)的泄漏情况,并支持手动监控自定义对象。开发者可以通过模拟内存泄漏来验证 LeakCanary 的功能,检测到泄漏后,LeakCanary 会生成详细的泄漏路径报告,帮助快速定位问题。此外,LeakCanary 还支持自定义
2025-05-15 09:52:29
1113
原创 Kotlin将异常信息转换为包含完整调用栈信息的字符串
在Kotlin中,将Exception转换为包含完整调用栈信息的字符串,可以通过两种方法实现。第一种方法是使用StringWriter和PrintWriter组合,通过内存字符流捕获异常堆栈信息,适用于所有Throwable类型。代码示例如下: fun exceptionToString(e: Exception): String { val sw = StringWriter() val pw = PrintWriter(sw) e.printStackTrace(pw) // 将堆栈信息写入流 retu
2025-05-15 09:51:42
262
原创 Kotlin通过反射随机测试目标类的静态方法
文章摘要:本文介绍了使用反射机制动态调用类方法的实现步骤。首先,通过反射获取类的所有公共静态方法,并过滤出符合条件的集合。接着,随机选择其中一个方法,并根据其参数类型动态生成参数值,包括基本类型、接口类型等。对于接口类型,使用动态代理生成空实现对象,避免空指针异常。最后,通过反射调用选定的方法,并处理可能的异常。文章还提供了完整的Kotlin示例代码,展示了如何实现这些功能,包括随机生成字符串、枚举值、数组等复杂类型的参数。
2025-05-14 11:04:14
694
原创 Android TextView实现垂直滚动
本文介绍了如何在 Android 应用中实现动态追加文本并自动滚动到底部的功能。首先,在 XML 布局文件中,将 TextView 包裹在 ScrollView 中,并设置 TextView 的高度为 wrap_content 以允许内容扩展。接着,在 Activity 或 Fragment 中初始化控件,并通过 textView.append() 方法动态追加文本。为了确保自动滚动到底部,使用 scrollView.fullScroll(ScrollView.FOCUS_DOWN) 方法,并通过 post
2025-05-14 11:03:48
518
原创 Android 使用libYUV垂直翻转RGB数据
本文介绍了如何使用libYUV库中的CopyPlane函数实现图像的垂直翻转。首先,需要明确输入图像的RGB格式(如RGB24)及其参数(宽度、高度和行跨度)。接着,分配与源数据大小相同的目标缓冲区。通过设置负步长(Negative Stride),将源数据从最后一行开始反向复制到目标缓冲区,从而实现垂直翻转。代码示例展示了如何调用CopyPlane函数,并详细说明了参数设置,包括源数据指针、步长、目标起始位置等。该方法简单高效,适用于图像处理中的垂直翻转需求。
2025-05-13 09:52:53
256
原创 Android OpenGL从帧缓冲区读取像素数据
OpenGL ES 2.0 中的 GLES20.glReadPixels 函数用于从帧缓冲区读取像素数据,支持多种像素格式和数据类型。其主要应用场景包括截图保存、图像处理分析和机器学习数据提取等。函数原型包括读取区域的坐标、宽高、像素格式、数据类型和目标缓冲区。使用步骤包括分配缓冲区、调用函数读取数据以及进行数据后处理,如将数据转换为 Bitmap 并进行垂直翻转。该函数在图形渲染和图像处理中具有重要作用。
2025-05-13 09:52:16
363
原创 Android 使用OpenCV解码视频
本文介绍了如何在Android平台上使用OpenCV 4.11实现视频解码的完整代码步骤。首先,通过VideoCapture类加载视频文件,并逐帧读取视频数据。每帧数据被转换为YUV420格式,并存储在字节数组中。为了保持视频播放的流畅性,代码还实现了帧率控制,确保每帧之间的延迟符合25帧/秒的要求。最后,释放所有资源,完成视频解码过程。该代码适用于需要实时处理视频帧的Android应用场景。
2025-05-12 09:36:06
122
原创 jsoncpp 生成的 JSON 字符串换行符问题
jsoncpp 生成的 JSON 字符串默认包含换行符和缩进,以提高可读性。使用 toStyledString() 方法时,自动添加这些格式化字符。若需生成紧凑的 JSON 字符串,可以使用 Json::FastWriter 或 Json::StreamWriterBuilder 来禁用换行符和缩进。Json::FastWriter 直接生成紧凑格式,而 Json::StreamWriterBuilder 通过设置 "indentation" 为空字符串来实现。换行符在调试和日志输出中有
2025-05-12 09:35:40
440
原创 JNI开发使用jsoncpp
在 Android JNI 开发中,如果使用 jsoncpp 库来生成和解析 JSON 数据,可以通过以下步骤进行集成。jsoncpp 是一个流行的 C++ JSON 库,可以方便地用于处理 JSON 数据。2.1. src\lib_json目录copy到项目main/cpp目录。2.2. include\json目录copy到项目main/cpp目录。在 JNI 中使用 jsoncpp 生成和解析 JSON 数据。手动将 jsoncpp 源代码文件加入到项目。修改 CMakeLists.txt。
2025-01-15 10:04:38
1071
原创 taskset命令
taskset 是 Linux 系统中的一个命令,用于设置或获取进程的 CPU 亲和性(CPU affinity)。CPU 亲和性决定了进程可以在哪些 CPU 核心上运行,通常用于优化性能,避免多个进程在同一核心上竞争资源。在 Android 系统中,由于它是基于 Linux 内核的,因此 taskset 命令也可以使用,但需要确保设备已经启用了 taskset 工具,并且你的设备具备了 root 权限,或者你正在使用开发者选项中的 ADB 工具。
2025-01-15 10:04:13
670
原创 Constructor of inner class ... can be called only with receiver of containing class
内类 (inner class) 必须通过外部类的实例来创建,因为它持有外部类的引用。确保你先实例化外部类,再通过外部类的实例来实例化内部类。
2025-01-14 14:42:44
362
原创 CSV文件对包含逗号的
使用 field.replace(“”“, “””") 处理字符串中的双引号,将每个双引号替换为两个双引号(这是 CSV 标准要求的做法)。在保存数据到 CSV 文件时,如果数据中包含逗号,应该对包含逗号的数据进行处理,以避免它被误认为是字段分隔符。将每个字段写入文件,并加上逗号分隔符。field.contains(“”") 检查数据是否包含双引号。field.contains(“,”) 检查数据是否包含逗号。如果数据中包含逗号或双引号,使用双引号将数据包裹起来。将每个字段通过逗号分隔写入 CSV 文件。
2025-01-14 14:42:00
761
原创 Android App获取root权限
在 Android 中,获取 root 权限通常意味着你需要通过 su(superuser)命令来执行具有更高权限的操作。对于系统应用(System App)来说,由于它们具有一定的系统权限,可以访问一些普通应用无法访问的资源,但它们通常并不能直接获得 root 权限,除非设备已经被 root 过。要执行带有 root 权限的命令,只需要调用上述方法并传递想要执行的命令。例如,删除一个只读文件或写入受保护的目录。
2024-12-02 09:49:02
1189
原创 Android 输入事件拦截机制
doInterceptKeyBeforeDispatchingLockedInterruptible调用Java层的interceptKeyBeforeDispatching做拦截操作,然后根据返回结果设置 key event的interceptKeyResult, 如果没有拦截,设置interceptKeyResult为INTERCEPT_KEY_RESULT_CONTINUE, 否则设置为INTERCEPT_KEY_RESULT_SKIP或TRY_AGAIN.
2024-11-30 23:01:49
1019
原创 android WakeLock简介
以下代码为WakeLock申请释放示例,要申请WakeLock,必须有PowerManager实例,如下。如果是通过acquire(long timeout)方法申请的超时锁,则会在到达时间后自动去释放,如果是通过acquire()方法申请的永久锁,则必须进行显式的释放,否则由于系统一直持有wakelock锁,将导致无法进入休眠状态,从而导致耗电过快等功耗问题。根据作用时间,WakeLock可以分为永久锁和超时锁,永久锁表示只要获取了WakeLock锁,必须显式的进行释放,否则系统会一直持有该锁;
2024-11-30 23:01:20
1218
原创 Android开发获取目录空间
在 Android 中,totalSpace 返回的是存储设备的总空间(以字节为单位)。该值表示该存储设备的总容量,不同于 freeSpace 和 usableSpace,后者分别表示可用的空间和当前系统可以使用的空间。
2024-11-29 09:44:32
233
原创 Android监听USB设备并获取挂载路径
在 Android 开发中,如果你想要监听 USB 设备的连接和断开事件,通常会使用 UsbManager 类来管理和处理 USB 设备的连接。Android 提供了 BroadcastReceiver 来接收系统广播,监听 USB 设备的插拔。通过创建一个 BroadcastReceiver 来监听系统发送的与 USB 设备连接相关的广播事件。首先,你需要在 AndroidManifest.xml 文件中声明 USB 权限和设备特性。动态注册 BroadcastReceiver。
2024-11-29 09:44:21
1473
原创 Android使用UVCCamera打开USBCamera-预览
获取TextureView的Surface,开启预览。写一个管理类封装UVCCamera相关API。导入libuvccamera.aar。
2024-11-28 09:29:36
1507
原创 Android使用UVCCamera打开USBCamera-编译
直接删除下面引用,后面根据编译报错删除HandlerThreadHandler和BuildCheck相关API的调用,不影响后面使用。执行后生成libuvccamera\build\outputs\aar\libuvccamera-release.aar。NDK版本过高,我这边使用r12版本,下载地址。在local.properties文件后添加。修改build.gradle文件。libcommon库问题。
2024-11-27 09:44:10
1202
原创 Android 设备上使用 tcpdump 抓包
在 Android 设备上使用 tcpdump 抓包是一个比较常见的网络调试操作,尤其对于开发者和安全研究人员来说。tcpdump 是一个强大的网络抓包工具,可以捕获传输的数据包,并且支持过滤和分析网络流量。这条命令会抓取所有接口上的所有数据包,-s 0 表示捕获整个包,-w 后面跟的是输出文件的路径。将 .pcap 文件导入 Wireshark 或其他网络分析工具中进行详细分析。抓取指定 IP 的流量。下载 tcpdump。
2024-11-27 09:42:48
1664
1
原创 Android HandlerThread 和 Handler区别
HandlerThread 和 Handler 都是 Android 中用于处理线程间通信和异步任务的工具,但它们的使用场景和功能有所不同。下面是它们的主要区别和各自的使用方法。
2024-11-26 09:28:12
587
原创 Android开发实现悬浮窗
在 Android 开发中,实现悬浮窗功能通常需要使用 System Alert Window 权限以及通过 WindowManager 来动态添加视图。悬浮窗是一种常见的 UI 元素,可以在应用界面上方显示,用于显示浮动的按钮、聊天小窗等内容。在 Android 6.0(API 23)及更高版本,SYSTEM_ALERT_WINDOW 权限是运行时权限,需要通过代码动态请求。首先,应用需要请求 SYSTEM_ALERT_WINDOW 权限,该权限允许应用创建悬浮窗并显示在其他应用之上。
2024-11-26 09:27:58
1231
原创 [CXX1300] CMake ‘3.13.4‘ was not found in SDK, PATH, or by cmake.dir property.
SDK目录下没有当前版本Cmake,需要前往。
2024-11-25 11:02:42
296
原创 Android 使用libyuv-缩放
在 Java 中调用 scaleI420 方法,传入原始 YUV 数据和目标宽高。封装一个 JNI 方法来调用 libyuv 的 I420Scale 函数。编写一个 C++ 文件,使用 libyuv 的 I420Scale 方法。
2024-10-31 09:36:08
716
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人