5月5日Android Studio学习笔记
一、代码优化之注解与资源管理进阶
(一)注解的深入使用
自定义注解
可以根据项目需求创建自定义注解,用于标记代码中的特定元素,如标记需要进行权限检查的函数、标记过时的类等,从而增强代码的可读性和可维护性。
定义一个简单的自定义注解 @NeedPermission ,用于标记需要申请特定权限的函数:
java
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD) // 限定注解的使用目标为方法
@Retention(RetentionPolicy.SOURCE) // 注解只保留在源码阶段
public @interface NeedPermission {
String permission(); // 注解的属性,表示所需权限
}
- 在代码中使用该注解:
java
public class ExampleActivity extends AppCompatActivity {
@NeedPermission(permission = "android.permission.CAMERA")
public void takePhoto() {
// 拍照逻辑
}
}
注解处理器(Annotation Processor)
注解处理器可以在编译时对注解进行处理,生成额外的代码或资源,进一步提高开发效率和代码质量。
例如,使用注解处理器自动生成事件绑定代码,减少手动编写事件监听器的样板代码。
(二)资源管理优化
资源分类与组织
按照资源的类型(如布局、图片、字符串、颜色等)和功能模块对资源文件进行分类存放,便于管理和查找。
例如,将与登录功能相关的布局文件、图片资源等放在一个单独的文件夹下,并在文件名前加上功能前缀,如 “login_activity.xml”“login_btn_bg.png” 等。
资源预留与占位
在开发过程中,为尚未确定最终内容的资源预留占位符,避免因资源缺失导致编译错误或应用崩溃。
可以使用占位符图片、默认字符串等,待资源准备完成后进行替换。
二、插件使用拓展
(一)Database Inspector 插件
简介
用于查看和调试应用中的数据库(如 SQLite 数据库),可以实时查看数据库结构、表数据、执行 SQL 查询等,方便进行数据库相关的开发和调试工作。
使用方法
启动应用后,在 Android Studio 的 “App Inspection” 窗口中找到 “Database Inspector” 选项卡。
连接到正在运行的应用进程,即可看到应用中的数据库列表,选择数据库后可以查看其表结构和数据内容。
可以执行自定义的 SQL 查询语句,对数据库进行查询、更新、插入等操作。
(二)Translation Editor 插件
简介
专为管理应用的多语言资源文件设计,能够方便地添加、编辑、删除不同语言的字符串资源,支持在线翻译工具集成,提高应用的本地化开发效率。
使用方法
在项目的 “res” 文件夹下创建不同语言的 “values” 文件夹,如 “values-es”(西班牙语)、“values-fr”(法语)等。
打开 Translation Editor 插件,它会自动识别所有的字符串资源文件,并以表格形式展示不同语言的翻译内容。
在插件中可以直接编辑翻译文本,也可以使用集成的在线翻译功能(如 Google 翻译)快速生成翻译内容,然后进行人工校对和修改。
三、性能分析与调试深化
(一)深入剖析 CPU Profiler
线程分析
通过 CPU Profiler 的线程视图,可以详细查看应用中各个线程的运行状态、CPU 使用率、线程堆栈等信息,帮助发现线程阻塞、线程过多等潜在问题。
例如,观察主线程的运行情况,确保耗时操作没有在主线程中执行,避免导致应用界面卡顿。
函数调用分析
利用 CPU Profiler 的 “火焰图”(Flame Chart)功能,可以直观地看到函数之间的调用关系和每个函数的执行时间占比,快速定位性能瓶颈函数。
火焰图以层次化的形式展示函数调用栈,横向表示时间轴,纵向表示函数调用的深度,颜色通常用于区分不同的函数或类。
(二)内存泄漏检测实战
常见内存泄漏场景
静态变量持有 Activity 或 View 的引用,导致 Activity 无法被垃圾回收。
内部类或匿名类未正确处理引用,如在 Handler 中使用匿名内部类导致 Activity 泄漏。
注册了广播接收者、内容观察者等但未及时注销。
使用 LeakCanary 检测内存泄漏
LeakCanary 是一款流行的内存泄漏检测库,集成到项目中后,当发生内存泄漏时会自动捕获并显示泄漏相关的诊断信息。
添加 LeakCanary 依赖:
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.10.0'
- 初始化 LeakCanary:
java
public class ExampleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
if (LeakCanary.isInDebugMode()) {
LeakCanary.createInstaller().install(this);
}
}
}
- 当应用发生内存泄漏时,LeakCanary 会弹出通知并生成详细的泄漏分析报告,包括泄漏对象的引用链、相关的代码位置等信息,方便开发者快速定位和修复内存泄漏问题。
四、布局优化之自定义 View 与动态布局加载
(一)自定义 View 优化
绘制过程优化
在自定义 View 的 onDraw 方法中,合理利用 Canvas 和 Paint 的绘图功能,减少不必要的绘图操作和资源消耗。
例如,根据 View 的可见区域(通过 getLocalVisibleRect 方法获取)进行局部绘制,避免绘制不可见区域的图形内容;合理设置 Paint 的抗锯齿(setAntiAlias)和过滤(setFilterBitmap)属性,在保证绘图质量的同时减少性能开销。
减少重绘区域
通过重写 dispatchDraw 方法并结合 getDrawingCache 和 invalidate 方法,精准控制 View 的重绘区域,避免全 View 重绘。
例如,当 View 中只有某一部分内容发生变化时,只对这部分区域进行重绘,提高绘图效率。
(二)动态布局加载
Fragment 动态加载
根据用户的操作或应用的状态,动态地添加、替换或移除 Fragment,实现灵活的界面切换和组合。
示例代码,动态替换 Fragment:
java
Fragment newFragment = new ExampleFragment();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, newFragment);
transaction.addToBackStack(null); // 可选,将操作添加到回退栈
transaction.commit();
- 其中,
fragment_container是用于承载 Fragment 的布局容器 ID。
LayoutInflater 动态加载布局
使用 LayoutInflater 类将布局文件动态加载为 View 对象,可以在运行时根据需要创建和组合不同的 UI 元素。
示例代码:
java
LayoutInflater inflater = LayoutInflater.from(context);
View dynamicView = inflater.inflate(R.layout.dynamic_layout, null);
// 将动态加载的 View 添加到父布局中
parentLayout.addView(dynamicView);
- 这种方式常用于实现列表项的自定义视图加载、动态弹窗等内容。
浙公网安备 33010602011771号