
Android去除无用资源给APK瘦身
无用资源文件1、Lint检查去除无用资源文件①在Analyze菜单栏中选择Run Inspection By Name...②在弹出的对话框中输入unused resources③选择会弹出如下的对话框,根据需要选择范围。对整个工程进行冗余资源的删除:④扫描完成会提示所有未使用的资源,并且可以进行选择删除。一键删除所有未使用的资源,有时候可能会出错,比如一个方法没有使用,但是这个方法引用了资源文件
Android 开发 · 共 58 篇 · 按发布时间正序排列
AOSP、Binder、Handler 到性能优化:深入 Android 系统 internals

无用资源文件1、Lint检查去除无用资源文件①在Analyze菜单栏中选择Run Inspection By Name...②在弹出的对话框中输入unused resources③选择会弹出如下的对话框,根据需要选择范围。对整个工程进行冗余资源的删除:④扫描完成会提示所有未使用的资源,并且可以进行选择删除。一键删除所有未使用的资源,有时候可能会出错,比如一个方法没有使用,但是这个方法引用了资源文件

LeakCanary导致编译冲突问题坑点:在比较旧的项目build.gradle文件中添加LeakCanary依赖准备分析内存泄露,可以sync,但是build的时候直接报错不通过:解决办法就是移除引入库中的额外重复依赖:或者降低到低版本的,没有这个问题:技巧:在代码项目路径下,运行命令检查依赖项:会检测出依赖关系:
看源码理解几种设置View背景的区别在写代码的时候给一个布局View设置背景,一开始使用的是setsetBackgroundResource()由于某种原因没有效果,换成setBackground()就可以了。很好奇,这其中的原理,虽然这些都是用来给View设置背景的,最大的不同无外乎参数不同:setBackground(Drawable background):其参数为一个Drawable对象,

Android ProGuard 代码混淆详解ProGuard 是 Android 开发中常用的代码混淆工具,它通过检测和移除未使用的类、字段、方法,优化字节码,以及用短名称混淆类名和方法名,使 APK 难以被逆向工程。本文从启用配置到混淆规则编写,全面介绍 ProGuard 的使用方法。1、ProGuard 的作用ProGuard 提供三大核心功能: • 压缩(Shrink):检测并移除未使用的

内存泄漏检测库:LeakCanaryLeakCanary是Square公司基于MAT开源的一个工具,专门为Android开发的一个工具,用起来非常方便。。Git地址:https://github.com/square/leakcanary官方地址:https://square.github.io/leakcanary/1、配置项目build.gradle在build.gradle文件中添加依赖。注

1、扫描手机存储的APK安装包废话少说直接上代码,借助ContentResolver查询系统APK的媒体类型"application/vnd.android.package-archive",通过"mime_type=\"application/vnd.android.package-archive\""筛选,即可获得手机存储的所有APK文件。2、获取APK包中的信息通过PackageManage
今天去公司上班复工的第一天,人很少。由于其它因素,拖了好久的编译问题,一直没动。正好这次解决掉这个问题。没想到一搞就是一天,心态被折磨爆炸。Android.mk编译的语法不了解,只能当场搜索,了解一下。还有一个坑点Android压缩资源文件aar的依赖引入方式和jar包不一样。写Android.mk的时候恍恍惚惚竟然有点C++的makefile内味了。有点像Qt编译文件.pro其次是Android

Android内存泄漏检测和避免 Java具有内存自动回收,但是在Android往往经常存在内存泄漏。因为Android开发中存在大量的异步任务等不了垃圾回收,还有很多JNI底层的的内存分配。1、内存泄漏检测好在Android提供了很多内存泄漏检测工具,帮助我们发现内存泄漏。还有大牛开发的库,比如:LeakCanary1.1、Android ProfileMemory Profiler 是 And

-Xlint:deprecation重新编译Build的时候打开了Build输出窗口,平时没注意看,没想到看到一句警告信息,虽然都是正常编译通过: 注: 某些输入文件使用或覆盖了已过时的 API。 注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。 注: ...\PercentLayoutActivity.java使用了未经检查或不安全的操作。 注: 有关详细信息, 请

Android AOSP repo 工具下载与使用指南repo 是 Google 专为管理 Android 源码(AOSP)而开发的仓库管理工具,它建立在 Git 之上,用一个 manifest 清单把数百个 Git 仓库组织起来,实现统一同步与管理。对于需要拉取、阅读或修改 AOSP 源码的开发者,repo 是绕不开的入口工具。本文按"安装 → 初始化 → 同步 → 常用命令 → 高级用法"的顺

Android源码在线阅读阅读源码学习Android源码的精髓,了解底层实现原理。下载源码到本地阅读,参考Android源码镜像下载 。在线阅读源码很方便,而且格式友好。1、在线源码 http://androidxref.com/ http://aospxref.com/ Android社区 OS在线源码 (域名已被专卖) https://github.com/aosp-mirror2、Andro

Handler、Looper、MessageQueue消息机制原理Android消息机制是安卓开发中非常重要的,在子线程中处理完I/O、网络请求,使用Handler切回到主线程处理。1、LooperAndroid Looper设计的非常巧妙,使用ThreadLocal实现这个特性。关于ThreadLocal参考另外一篇Thread和ThreadLocal。1.1、主线程Looper一个Applic

源码颇析AsyncTask工作原理Android开发中经常会用到AsyncTask开启异步任务,后台执行耗时操作,具体用法参考《AsyncTask:异步任务》。现在从源码来看看AsyncTask的实现机制。1、AsyncTask中的线程池AsyncTask中封装了两种Executor,一个是顺序执行的SERIAL_EXECUTOR,另一个是并发执行的THREAD_POOL_EXECUTOR。1.1
HandlerThread源码的实现HandlerThread继承自Thread,和普通线程一样,只不过HandlerThread有自己的Looper,线程启动之后可以用HandlerThread中的Looper创建Handler,向Handler发送消息,将任务放到线程中执行。比如熟悉的IntentService,内部就是借助HandlerThread在子线程中执行onHandleIntent(
multiDex:分包开发的APP功能越来越多,引入的库也越来越多,很容易达到“界限”65536,因为Android中一个Dex文件最多存储65536个方法(short类型的范围)。这时候就要开启“分包”multiDex。1、Android 5.0之后分包Android 5.0也就是API 21之后ART虚拟机支持MultiDex。直接在build.gradle文件中直接配置multiDexEna

SystemServer系统服务启动SystemServer进程用来在创建系统服务,比如AMS、WMS、PMS等。熟悉一下Android系统服务的启动流程。总的启动时序图如下:接着《Zyoget进程的启动》,同样在ZygoteInit的main方法中:调用Runnable forkSystemServer(String abiList, String socketName,ZygoteServer
Android桌面Launcher3的启动SystemServer启动会在startBootstrapServices()方法中启动引导带服务,其中就包括PackageManagerService(这里判断了手机是否是工厂模式)。而包管理服务和接下来要分析的Launcher启动有很大关系。SystemServer启动流程参考《SystemServer系统服务启动》。startOtherServic
Launcher加载APP图标流程前段时间看了桌面Launcher的启动流程《安卓桌面Launcher的启动》,但是还没完,桌面也是一个安卓应用且涉及到的面很广,光是桌面这个模块就需要一个团队维护开发。AOSP Launcher源码:Launcher3大牛维护的Launcher代码:fookwood/Launcher31、Launcher.onCreate()接着Launcher的启动,通过Int

Binder线程池的启动Binder线程池在Android是一个非常重要的技术,访问其它应用ContentProvider的,应用进程和系统服务之间的通信等操作在服务端是运行在Binder线程池中的。Binder线程池是一个比较底层的概念,关于Binder的代码在native层中:../frameworks/native/libs/binder接着APP进程的启动(见:APP进程启动流程),在Zy
源码理解apply()与commit()的区别为什么SharedPreference保存数据首选apply()?commit()和apply()有什么区别?①commit()是同步的:将数据直接写入存储;apply()是异步的,先将修改提交到内存不会阻塞,之后再写入存储。②commit()有返回值标识是否成功写入;而apply()没有返回值。现在来看看源码到底是如何实现apply()和commit

熟悉Android源码目录结构开发者需要了解系统运行的机制,了解一定深度的原理,而不是仅停留在会调用系统提供的API层面。阅读源码需要对源码目录结构有所了解,不然的话可能都找不到方向,因为整个Android项目很庞大复杂。源码按照一定的架构组织起来,详见Android 开源项目简介。1、源码根目录Android源码下载下来,根目录下很多一级子目录,每个目录都对应一层架构或者一块框架。①art:AR

ANR:Application Not Responding使用Android手机有时候会遇到系统弹框“应用程序无响应”,这是因为APP在前台或者后台主线程中执行的时间太长,没有响应用户的操作。1、ANR条件系统ActivityManager和WindowManager会监控应用,如下三种条件下会产生ANR:①Activity:前台在5s内无法响应输入事件(触摸、按键);定义在:ActivityT
Android权限检测申请源码流程分析Android系统的权限开发用起来很方便,知识点不多,详见Android Permission 权限总结。但是它的系统校验检测机制比较复杂,从framework层PackageManager、PermissionManager、PermissionManagerInternal到系统服务PackageManagerService、PermissionManag

AndroidStudio创建Library并打包aar开发中常常使用第三方的库,Java开发常常使用 .jar包,而Android使用的是aar包。看看如何创建Library项目如何创建,以及aar是如何打包。不同于普通的App项目,aar是Android中的Library。1、创建Android Library项目 File > New > New Project新建项目,由于没有Androi

AsyncLayoutInflater源码颇析别看AsyncLayoutInflater源码只有233行,代码质量非常高。二百行左右的代码,值得开发者好好学习。这就是阅读源码的意义,也要写出这样优秀的代码。1、构造AsyncLayoutInflater实例传入Context构造AsyncLayoutInflater实例:初始化AsyncLayoutInflater内部这几个变量:LayoutInf

Retrofit源码流程分析距离上次了解Retrofit的使用过去很长时间,必须得抽空看看Retrofit源码,了解Retrofit到底做了哪些工作,把网络请求封装的如此便捷。按开发过程中Retrofit的使用顺序看源码。1、Retrofit的构造在开始Retrofit流程分析之前,先搞清楚Retrofit实例的构造,涉及到后面请求流程中一些关键对象的初始化。1.1、构造者模式创建Retrofit
PackageManagerService启动流程前面通过APK的构建过程和APK的组成结构两篇铺垫,准备研究Apk的安装过程之前,先需要搞清楚PackageManagerService,也就是平时经常听到的PMS,是由SystemServer进程创建的系统服务之一。用API 30的源码阅读PMS服务的初始化流程,新的源码和目前的书籍资料相差较大(普遍基于API 28),源码看起来就比较费时间,因

Apk的安装过程探究有了APK的构建过程和APK的组成结构两篇铺垫,以及PackageManagerService基础。终于到了最后阶段:Apk的安装过程。这块内容比较多,抽空断断续续的看了一个星期摸清楚。通常Apk的安装方式有三种:①手机上点击Apk文件,打开安装界面进行安装②通过代码的方式静默安装,比如手机自带的应用商店安装应用。③开发者使用adb命令安装apk文件挨个探究以上三个方式,每种方

StrictMode:严格模式的使用第一次接触使用StrictMode还是刚毕业的时候,现在再次记录一下StrictMode。本篇主要详细了解StrictMode的使用方法。关于StrictMode的实现原理详见另外一篇StrictMode原理剖析。1、StrictModeStrictMode是从Android 2.3(API 9)开始引入的调试工具。通常帮助开发者用来检测应用中出现的主线程I/O

StrictMode原理剖析在上一篇StrictMode:严格模式的使用中了解了StrictMode的使用,接下来深入源码,探索StrictMode的实现。主要涉及的源码目录如下:/frameworks/base/core/java/android/os/strictmode/libcore/dalvik/src/main/java/dalvik/system/libcore/luni/src/m

bindService绑定服务源码流程终于轮到双休,周末可以摸一下书。本次阅读的源码基于API 30,将来回头再看可能有误。1、绑定ServiceService作为四大组件之一,承担着执行后台任务的重担。有两种启动方式:①startService,②bindService。本篇跟随源码了解绑定Service的过程。绑定Service仅需简单几步:将Service的绑定过程拆分开来看,并不复杂,逻辑
一个高效的Apk提取脚本开发者如何将手机上已安装应用的安装包提取导出到电脑上呢?以前是这样做的,只需要简单三步:①利用焦点拿到当前打开的应用包名(如果已经知道需要导出的应用包名,可以跳过此步)②知道应用包名后,通过pm获取安装包路径③最后就是将apk从手机中pull出来。注意如果路径包含'/base.apk'需要加一个'/'改成'//base.apk',后面写的脚本有这一步处理。还可以更快,更高效

EventBus源码分析(一):构造及订阅通过一文EventBus初步使用,了解了EventBus的使用。光了解是不够的,深入源码才算熟悉。EventBus源码不多,适合开发者精读学习,仅代码就1800余行(使用SourceCounter统计)。1、构造EventBus实例项目开发中,一般使用EventBus类中的getDefault()静态方法获取全局总线实例。1.1、默认单例getDefaul

EventBus源码分析(二):事件分发及处理前面了解了EventBus的构造及事件订阅,接下来看看EventBus事件分发的实现原理。1、事件分发使用过EventBus的同学都应该知道,EventBus提供两个事件发送API方法:通过post(event)可以发送普通一次性事件外,另外一个方法是postSticky(event)可以发送粘性事件。所谓粘性事件其实和普通事件一样,只不过会将【粘性事

EventBus源码分析(三):Subscribe注解详解前面把EventBus源码看了一遍,回头再看一下EventBus初步使用一文中提到的Subscribe注解,就会更加理解这其中三个属性的含义及作用:1、Subscribe注解Subscribe注解定义如下:Subscribe注解只能作用在方法上;在编译后不仅被保留,在运行时获取该注解。Subscribe注解有三个属性: ①threadMod

EventBus源码分析(四):EventBus中的几种设计模式再看一下EventBus,总结一下其中几个重要的设计模式,也是最常见的几种设计模式:单例模式、建造者模式、观察者模式。多看源码的好处之一就是能从优秀的代码里活学活用。1、单例模式单例模式(Singleton Pattern)是设计模式中最简单也是最常见的设计模式。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。单例模

Choreographer源码阅读之前已经在很多地方看到过Choreographer的身影,必须要仔细的看一遍Choreographer源码以理解其实现原理。Choreographer请求和接受来自底层的VSYNC信号,给上层应用提供一个稳定的周期,去处理Input事件、动画、更新布局等。1、Choreographer构造及初始化Choreographer直译为编舞者,看完源码更能理解Choreo
MessageQueue中的同步屏障Message,最早可以翻到两年前写的一篇粗浅博客《信件:Message》。当时还不明白异步消息、同步消息,更不懂今天要写的同步屏障。同步屏障,简而言之就是让异步消息的优先级高于同步消息,优先被处理。1、同步屏障MessageQueue设置同步屏障后,会拦截对同步消息的处理,只会处理异步消息,如果没有异步消息则进入阻塞状态。若没有及时移除同步屏障,所有的同步消息
ViewStub源码剖析之前在ViewStub懒加载一文中记录了如何使用ViewStub懒加载布局,当时没有继续对ViewStub深入研究。现在回头看看ViewStub源码,只有三百多行,属实需要细细品一下。 nukc在看了ViewStub源码之后突发灵感,写了StateView库,吸收了ViewStub的一些特性,内存占用少。从ViewStub的构造函数开始看,ViewStub继承自View,所

AOSP代码在线搜索:Code Search阅读源码的时候,一个痛点就是“迷失在茫茫目录中”:找不到类文件在哪、找不到接口的实现类是哪个、找不到方法在哪实现的。比如,看Display相关源码,会发现DisplayManagerGlobal中有一个成员IDisplayManager,对源码结构不熟悉的话,一时找不到这个接口实现在哪里。在Android源码目录结构一文中对AOSP的目录有些许的了解,知

getSystemService()引起的内存泄漏通常获取系统服务通过Context的getSystemService(String name)方法,举个例子:每个系统服务都有独一无二的名称对应,其中CONNECTIVITY_SERVICE是定义在Context中的"connectivity":1、getSystemService方法getSystemService(String name)方法是
R8编译问题:Missing classes detected while running R8Android R8是一个代码混淆和压缩工具,可以将应用程序的大小和安全性优化。它引入了一些新功能,如成员内省、混淆指针、类内省等。但R8使用起来一直不友好,因为自从使用R8之后编译问题不断。主要还是和混淆相关,经常报错,最近又遇到一个:Missing classes detected while ru
ContentObserver内容观察者源码解析一定要看看ContentObserver源码内部是如何实现观察者模式观察ContentProvider内容的。用它来观察我们感兴趣的ContentProvider是很有用的(见ContentProvider笔记)。1、注册先从ContentResolver注册ContentObserver的registerContentObserver()方法开始:

获取Apk的签名信息篡改包名是常见的攻击手段,但修改签名是具有难度的。因此某些场景下对包进行签名校验,是安全的一种常规手段。1、使用keytools命令借助keytool工具可以查看Apk的签名,该工具在JDK的\jdk\bin目录下。可以查看到Apk的签名等信息:如果是未签名的Apk则是没有以上信息的,使用Android Studio编译出来的包含有默认签名。2、通过代码获取在Android中,
使用@Keep注解防止被混淆使用proguard混淆代码是对产品本身的一种保护,常见的方法就是编写projuard-rules.pro配置文件。已经有开源项目将各类混淆配置集中到一起:github/android-proguard-snippets,提供给大家参考。一个典型的Android项目混淆配置文件如下:在AndroidStudio项目中都会用到proguard-android文件,这里大家

The project is using an incompatible version (AGP 8.7.1)一直在踩坑,从未停止。clone了国外一个大神的项目,项目打开就报错:The project is using an incompatible version (AGP 8.7.1) of the Android Gradle plugin. Latest supported versi
解决 Koin 的 ScopeAlreadyCreatedException 错误在使用 Koin 进行依赖注入时,可能会遇到 ScopeAlreadyCreatedException 错误,错误信息为 "Scope with id 'session' is already created"。本文将详细介绍这个错误的原因和解决方案。1、错误原因分析这个错误表示试图创建一个已经被创建的 Koin s
深入 Android FrameMetrics:性能监控的利器1、什么是 FrameMetricsFrameMetrics 是 Android API 24(Android 7.0)引入的一个性能监控工具,用于量化应用的 UI 渲染性能。它能够详细记录每帧渲染的各个阶段耗时,帮助开发者识别和解决性能问题。核心价值: - 精确测量每帧渲染时间 - 细分为多个渲染阶段,便于定位问题 - 支持实时监控和

Jetpack Room 数据库使用完全指南Room 是 Android Jetpack 组件中的一个 SQLite ORM 库,提供了更简单的数据库访问抽象层。以下是全面且深入的 Room 使用详解。1、基础配置Gradle 依赖2、核心组件架构Room三大组件关系:Entity → Database ←→ Dao ↔ Repository ↔ ViewModel ↔ UI3、实体(Entity

Room TypeConverter 深度解析TypeConverter 是 Room 数据库中处理非原生数据类型的关键机制,它允许您在数据库中存储复杂的数据类型。下面我将详细介绍其使用方法和工作原理。1、基本概念 Room 默认支持以下原生类型: 基本类型:int, long, float, double, boolean 包装类型:Integer, Long, Float, Double, B

Toast 源码详解:从创建到显示的完整流程1、Toast 的创建与初始化1.1、makeText 方法Toast 的创建从 makeText() 方法开始:这个方法会调用内部的 makeText 方法,该方法会根据兼容性设置创建 Toast 实例:1.2、Toast 构造方法Toast 的构造方法会初始化关键成员变量:1.3、Looper 获取Toast 必须在有 Looper 的线程中创建:1

DiskLruCache 源码深度解析1、DiskLruCache 概述DiskLruCache 是一种基于 LRU(Least Recently Used)算法的磁盘缓存实现,由 Jake Wharton 开发,广泛应用于 Android 应用中。它提供了高效的文件系统缓存机制,特别适合缓存网络请求结果、图片等大型数据。核心特性: - 基于 LRU 算法,自动管理缓存大小 - 支持多线程并发操作
内存泄漏检测:Memory Analyzer(MAT)详解内存泄漏(Memory Leak)是 Java 与 Android 应用最棘手的问题之一:不再使用的对象因仍被持有引用而无法被 GC 回收,长时间累积最终耗尽内存,引发卡顿甚至 OOM 崩溃。Memory Analyzer(简称 MAT)是 Eclipse 基金会开源的堆转储分析工具,也是业界定位 Java/Android 内存泄漏的事实标