深入分析 Android Activity (十一)

文章目录

    • 深入分析 Android Activity (十一)
    • 1. Activity 的内存管理和优化
      • 1.1 内存泄漏的常见原因
      • 1.2 避免内存泄漏的方法
      • 1.3 内存泄漏检测工具
    • 2. Activity 的配置变更处理
      • 2.1 处理配置变更
      • 2.2 保存和恢复状态
      • 2.3 使用 ViewModel
    • 3. Activity 的测试
      • 3.1 单元测试
      • 3.2 UI 测试
    • 4. Activity 与 Fragment 的关系
      • 4.1 添加 Fragment
      • 4.2 处理 Fragment 生命周期
      • 4.3 Fragment 之间的通信
    • 总结

深入分析 Android Activity (十一)

1. Activity 的内存管理和优化

内存管理是 Android 开发中非常重要的一部分。内存泄漏会导致应用崩溃和性能问题,因此需要在开发过程中注意内存管理和优化。

1.1 内存泄漏的常见原因

  • 静态引用:静态变量持有 Activity 的引用会导致内存泄漏。
  • 未取消的监听器:忘记注销注册的监听器或回调会导致内存泄漏。
  • Handler 内存泄漏:匿名内部类 Handler 引用外部类实例,会导致外部类无法被回收。
  • 长时间运行的线程:线程持有 Activity 的引用,在 Activity 销毁后线程未终止,会导致内存泄漏。

1.2 避免内存泄漏的方法

  • 使用弱引用:使用 WeakReference 持有 Activity 的引用。
  • 及时取消监听器和回调:在 onDestroy 或其他适当时机取消监听器和回调。
  • 静态内部类:使用静态内部类避免持有外部类的引用。
  • 使用 Application Context:在适当场景下使用 Application Context 而非 Activity Context。
// 使用 WeakReference 避免内存泄漏
private static class MyHandler extends Handler {private final WeakReference<MyActivity> mActivity;public MyHandler(MyActivity activity) {mActivity = new WeakReference<>(activity);}@Overridepublic void handleMessage(Message msg) {MyActivity activity = mActivity.get();if (activity != null) {// Handle message}}
}

1.3 内存泄漏检测工具

  • LeakCanary:一个内存泄漏检测工具,可以帮助检测内存泄漏。
// 在 Application 类中初始化 LeakCanary
public class MyApplication extends Application {@Overridepublic void onCreate() {super.onCreate();if (LeakCanary.isInAnalyzerProcess(this)) {return;}LeakCanary.install(this);}
}

2. Activity 的配置变更处理

配置变更(如屏幕旋转、语言切换)会导致 Activity 被销毁和重建,需要妥善处理以保存和恢复数据。

2.1 处理配置变更

可以在 AndroidManifest.xml 中通过 android:configChanges 属性指定处理配置变更。

<activity android:name=".MyActivity"android:configChanges="orientation|screenSize|keyboardHidden"/>

在 Activity 中重写 onConfigurationChanged 方法。

@Override
public void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {// Handle orientation change to landscape} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {// Handle orientation change to portrait}
}

2.2 保存和恢复状态

在配置变更时,可以通过 onSaveInstanceStateonRestoreInstanceState 方法保存和恢复数据。

@Override
protected void onSaveInstanceState(Bundle outState) {super.onSaveInstanceState(outState);outState.putString("key", "value");
}@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {super.onRestoreInstanceState(savedInstanceState);if (savedInstanceState != null) {String value = savedInstanceState.getString("key");}
}

2.3 使用 ViewModel

可以使用 ViewModel 在配置变更期间保存 UI 相关数据。

public class MyViewModel extends ViewModel {private MutableLiveData<String> data;public LiveData<String> getData() {if (data == null) {data = new MutableLiveData<>();loadData();}return data;}private void loadData() {// Load data asynchronously}
}// 在 Activity 中使用 ViewModel
MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class);
viewModel.getData().observe(this, new Observer<String>() {@Overridepublic void onChanged(String s) {// Update UI}
});

3. Activity 的测试

测试是确保应用质量的重要步骤,包括单元测试和 UI 测试。

3.1 单元测试

可以使用 JUnit 进行单元测试。

// 使用 JUnit 测试 Activity 中的方法
@RunWith(AndroidJUnit4.class)
public class MyActivityTest {@Testpublic void testActivityMethod() {Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();assertEquals("com.example.myapp", appContext.getPackageName());}
}

3.2 UI 测试

可以使用 Espresso 进行 UI 测试。

// 使用 Espresso 进行 UI 测试
@RunWith(AndroidJUnit4.class)
public class MyActivityUITest {@Rulepublic ActivityScenarioRule<MyActivity> activityScenarioRule = new ActivityScenarioRule<>(MyActivity.class);@Testpublic void testButtonClick() {onView(withId(R.id.my_button)).perform(click());onView(withId(R.id.my_text_view)).check(matches(withText("Button clicked")));}
}

4. Activity 与 Fragment 的关系

Fragment 是在 Activity 中的可重用组件,用于实现灵活的 UI 设计。

4.1 添加 Fragment

可以在 XML 布局文件中添加 Fragment,也可以在代码中动态添加。

<!-- 在 XML 布局文件中添加 Fragment -->
<fragmentandroid:id="@+id/my_fragment"android:name="com.example.MyFragment"android:layout_width="match_parent"android:layout_height="match_parent"/>
// 在代码中动态添加 Fragment
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
MyFragment fragment = new MyFragment();
fragmentTransaction.add(R.id.fragment_container, fragment);
fragmentTransaction.commit();

4.2 处理 Fragment 生命周期

Fragment 的生命周期与 Activity 类似,但有自己独特的生命周期方法。

public class MyFragment extends Fragment {@Overridepublic void onAttach(Context context) {super.onAttach(context);// Fragment 被添加到 Activity 时调用}@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// Fragment 初始化时调用}@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {// 为 Fragment 创建视图时调用return inflater.inflate(R.layout.fragment_my, container, false);}@Overridepublic void onActivityCreated(Bundle savedInstanceState) {super.onActivityCreated(savedInstanceState);// Activity 的 onCreate 方法返回时调用}@Overridepublic void onStart() {super.onStart();// Fragment 可见时调用}@Overridepublic void onResume() {super.onResume();// Fragment 交互时调用}@Overridepublic void onPause() {super.onPause();// Fragment 不可见时调用}@Overridepublic void onStop() {super.onStop();// Fragment 停止时调用}@Overridepublic void onDestroyView() {super.onDestroyView();// Fragment 视图被销毁时调用}@Overridepublic void onDestroy() {super.onDestroy();// Fragment 被销毁时调用}@Overridepublic void onDetach() {super.onDetach();// Fragment 从 Activity 中分离时调用}
}

4.3 Fragment 之间的通信

可以使用接口在 Fragment 之间进行通信。

// 定义接口
public interface OnFragmentInteractionListener {void onFragmentInteraction(String data);
}// 在 Fragment 中实现接口
public class MyFragment extends Fragment {private OnFragmentInteractionListener mListener;@Overridepublic void onAttach(Context context) {super.onAttach(context);if (context instanceof OnFragmentInteractionListener) {mListener = (OnFragmentInteractionListener) context;} else {throw new RuntimeException(context.toString() + " must implement OnFragmentInteractionListener");}}public void someMethod() {if (mListener != null) {mListener.onFragmentInteraction("Some data");}}
}// 在 Activity 中实现接口
public class MyActivity extends AppCompatActivity implements OnFragmentInteractionListener {@Overridepublic void onFragmentInteraction(String data) {// Handle the data from the fragment}
}

总结

通过对 Android Activity 的深入理解和灵活应用,可以实现丰富的用户体验和高效的应用程序。理解其生命周期、权限管理、数据传递、动画效果、导航和返回栈管理、资源管理、配置变更处理、视图层次结构、性能优化、内存管理、测试、Service 交互、BroadcastReceiver

欢迎点赞|关注|收藏|评论,您的肯定是我创作的动力

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/18637.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

质量工具系列之Dependency-Track

项目开发中依赖了很多第三方开源工具&#xff0c;对于其版本&#xff0c;漏洞等因为时间或者是数量太多而无法关注到&#xff0c;Dependency-Track解决这些问题。 Dependency-Track 是一个开源组件分析平台&#xff0c;是开放网络应用安全项目&#xff08;OWASP&#xff09;的一…

web自动化-数据驱动与失败用例截图、失败重新运行

因为只有失败的用例需要截图&#xff0c;那么问题就是&#xff1a; 什么时候用例会失败&#xff1f; 数据驱动测试 我们前面覆盖到的用例都是正常的用例&#xff0c;如果要测试异常的用例呢&#xff1f; 我们来写一下登录的异常 场景&#xff1a;【login_page】 # 用户输入框…

LAMP集群分布式实验报告

前景&#xff1a; 1.技术成熟度和稳定性&#xff1a; LAMP架构&#xff08;Linux、Apache、MySQL、PHP&#xff09;自1998年提出以来&#xff0c;经过长时间的发展和完善&#xff0c;已经成为非常成熟和稳定的Web开发平台。其中&#xff0c;Linux操作系统因其高度的灵活性和稳…

【XR806开发板试用】基础篇,从零开始搭建一个LCD彩屏时钟(ST7735S驱动)

本文从搭建环境开始&#xff0c;step by step教大家使用XR806实现驱动SPI屏幕&#xff08;ST7735S驱动&#xff09;&#xff0c;并连接WiFi实现ntp对时&#xff0c;最终实现把时间显示到屏幕上。 #1. 搭建开发环境 1. 安装编译环境所需的依赖包 基于ubuntu 20.04&#xff0c;按…

UI自动化测试最佳设计模式POM

当使用Selenium进行UI自动化测试时&#xff0c;Page Object Model&#xff08;POM&#xff09;是一种最佳实践的设计模式。POM的核心思想是通过将页面封装成对象&#xff0c;使得测试代码更加清晰、可维护和可重用。 POM的主要组成部分包括页面对象类、元素定位方式和操作方法…

LabVIEW车轮动平衡检测系统

LabVIEW车轮动平衡检测系统 随着汽车行业的快速发展&#xff0c;车轮动平衡问题对乘坐舒适性、操控稳定性及安全性的影响日益凸显&#xff0c;成为了提高汽车性能的一个关键环节。传统的检测系统因精度低、成本高、操作复杂等问题&#xff0c;难以满足现代汽车行业的需求。开发…

行车安全:UWB模块的智能化在车辆安全系统中的作用

随着交通车辆数量的不断增加和道路交通拥堵的加剧&#xff0c;车辆安全问题日益引起人们的关注。在这种背景下&#xff0c;超宽带&#xff08;UWB&#xff09;技术作为一种新兴的定位技术&#xff0c;正逐渐应用于车辆安全系统中&#xff0c;为提高车辆行车安全性提供了新的解决…

Django配置

后端开发&#xff1a; python 解释器、 pycharm 社区版、 navicate 、 mysql(phpstudy) 前段开发&#xff1a; vs code 、 google 浏览器 django 项目配置 配置项目启动方式 创建模型 创建一个应用 在应用中创建模型类 根据模型类生成数据表 创建应用 创建模型类 …

智能除螨—wtn6040-8s语音芯片方案引领除螨仪新时代

语音螨仪开发背景&#xff1a; 随着物联网技术的快速发展&#xff0c;除螨仪作为家庭清洁的重要工具&#xff0c;其智能化、人性化的设计成为提升市场竞争力的关键。置入语音芯片的除螨仪&#xff0c;通过开机提示、工作状态反馈、操作指引、故障提醒等内容。用户可以更加直观…

邦注科技三机一体除湿干燥机在工业中的应用

三机一体除湿干燥机在工业中的应用广泛且重要&#xff0c;其结合了传统除湿机、冷凝器和加热器的功能&#xff0c;具有节能、环保、方便等特点。以下是关于三机一体除湿干燥机在工业中应用的详细解析&#xff1a; 一、应用领域 电子制造行业&#xff1a;在半导体、集成电路和…

大模型中的Tokenizer

在使用GPT 、BERT模型输入词语常常会先进行tokenize 。 tokenize的目标是把输入的文本流&#xff0c;切分成一个个子串&#xff0c;每个子串相对有完整的语义&#xff0c;便于学习embedding表达和后续模型的使用。 一、粒度 三种粒度&#xff1a;word/subword/char word词&a…

【云原生】Kubernetes----POD调度策略

目录 引言 一、Pod调度策略 &#xff08;一&#xff09;基本概述 &#xff08;二&#xff09;调度原则 &#xff08;三&#xff09;Predicate常见算法 &#xff08;四&#xff09;优先级排序 &#xff08;五&#xff09;调度过程 1.过滤阶段 2.优先级排序 3.选择最优…

大模型部署推理应用技术浅析

大模型完成预训练后不是就万事大吉了&#xff0c;离推理应用还有很大距离&#xff0c;需要经过微调、部署等一系列工程化工作。尤其是在2B的行业大模型应用中&#xff0c;为解决大模型的幻觉、时效性和推理成本问题&#xff0c;需要建立单一模型之上的体系。模型部署中的技术大…

Windows找出权限维持的后门

Windows权限维持主要包含活动隐藏、自启动等技术。 隐藏文件 利用文件属性 最简单的一种隐藏文件的方式&#xff0c;文件右键属性&#xff0c;勾选隐藏&#xff0c;点击确定后&#xff0c;在这个文件里看不到刚刚的文件了。 如果要让文件显示出来&#xff0c;就点击查看&…

matplotlib ---词云图

词云图是一种直观的方式来展示文本数据&#xff0c;可以体现出一个文本中词频的使用情况&#xff0c;有利于文本分析&#xff0c;通过词频可以抓住一篇文章的重点 本文通过处理一篇关于分析影响洋流流向的文章&#xff0c;分析影响洋流流向的主要因素都有哪些 文本在文末结尾 …

着色器技术在AI去衣中的魔法般的作用

引言&#xff1a; 在数字图像处理的世界中&#xff0c;AI去衣技术正逐步成为研究的前沿。它利用人工智能的强大能力&#xff0c;实现对图像中衣物的智能识别与处理。在这一过程中&#xff0c;着色器&#xff08;Shader&#xff09;技术扮演了至关重要的角色。本文将深入探讨着色…

【VTKExamples::Utilities】第十五期 ShepardMethod

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 公众号:VTK忠粉 前言 本文分享VTK样例ShepardMethod,并解析接口vtkShepardMethod,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ…

没有可用软件包 docker-ce。 错误:无须任何处理

特么的各种百度查看&#xff0c;全是一些废话&#xff01;&#xff01;&#xff01;centos7安装不上docker&#xff0c;都是老的代码了&#xff1a; yum install docker-ce 解决方案&#xff1a; # CentOS yum install docker-io

深度学习之CNN卷积神经网络

一.卷积神经网络 1. 导入资源包 import numpy as np import pandas as pd import matplotlib.pyplot as plt import sklearn import tensorflow as tf from tensorflow import keras注&#xff1a;from tensorflow import keras&#xff1a;从TensorFlow库中导入Keras模块&am…

【Unity之FGUI】白仙章Fairy GUI控件详解二

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;元宇宙-秩沅 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 秩沅 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a;就业…