深入分析 Android Activity (五)

文章目录

      • 深入分析 Android Activity (五)
      • 1. Activity 的进程和线程模型
        • 1.1 主线程与 UI 操作
        • 1.2 使用 AsyncTask
        • 1.3 使用 Handler 和 Looper
      • 2. Activity 的内存优化
        • 2.1 避免内存泄漏
        • 2.2 使用内存分析工具
        • 2.3 优化 Bitmap 使用
      • 3. Activity 的跨进程通信(IPC)
        • 3.1 使用 AIDL
      • 4. 深入理解 Activity 的配置变化处理
        • 4.1 在 Manifest 文件中声明配置变化
        • 4.2 重写 `onConfigurationChanged` 方法
      • 5. Activity 的调试和日志记录
        • 5.1 使用 Logcat
        • 5.2 使用调试工具
      • 6. Activity 的单元测试和 UI 测试
        • 6.1 使用 JUnit 进行单元测试
        • 6.2 使用 Espresso 进行 UI 测试
      • 总结

深入分析 Android Activity (五)

1. Activity 的进程和线程模型

在 Android 中,Activity 默认在主线程(也称为 UI 线程)中运行。理解进程和线程模型对于开发响应迅速且无阻塞的应用程序至关重要。

1.1 主线程与 UI 操作

所有 UI 操作必须在主线程中执行,以避免并发问题和 UI 不一致性。长时间的操作应在工作线程中完成,并使用主线程处理结果。

// Performing a long-running operation on a background thread
new Thread(new Runnable() {
    @Override
    public void run() {
        // Long-running operation
        final String result = performOperation();
        
        // Post result back to the main thread
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                // Update UI with the result
                textView.setText(result);
            }
        });
    }
}).start();
1.2 使用 AsyncTask

AsyncTask 是一种方便的方式,可以在后台线程中执行操作,并在主线程中处理结果。不过,由于其容易导致内存泄漏和其他问题,现在更推荐使用 ExecutorServiceRxJava

private class MyAsyncTask extends AsyncTask<Void, Void, String> {
    @Override
    protected String doInBackground(Void... voids) {
        return performOperation();
    }

    @Override
    protected void onPostExecute(String result) {
        textView.setText(result);
    }
}

// Execute the AsyncTask
new MyAsyncTask().execute();
1.3 使用 Handler 和 Looper

HandlerLooper 提供了一种灵活的方法来管理线程间通信。

// Creating a Handler on the main thread
Handler handler = new Handler(Looper.getMainLooper());

// Running code on the main thread
handler.post(new Runnable() {
    @Override
    public void run() {
        // Update UI
        textView.setText("Updated from background thread");
    }
});

2. Activity 的内存优化

内存管理是 Android 开发中的一个重要方面,特别是在设备资源有限的情况下。以下是一些常见的内存优化技巧。

2.1 避免内存泄漏

使用弱引用和上下文的短生命周期对象可以避免内存泄漏。避免在 ActivityFragment 中直接引用长生命周期对象,如单例模式。

// Use WeakReference to avoid memory leaks
private static class MyHandler extends Handler {
    private final WeakReference<MyActivity> mActivity;

    MyHandler(MyActivity activity) {
        mActivity = new WeakReference<>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
        MyActivity activity = mActivity.get();
        if (activity != null) {
            // Handle message
        }
    }
}
2.2 使用内存分析工具

Android Studio 提供了内存分析工具,可以帮助检测和解决内存泄漏。

// Use Android Profiler to detect memory leaks
2.3 优化 Bitmap 使用

Bitmaps 是常见的内存消耗大户。使用适当的压缩和回收策略来优化 Bitmap 使用。

// Decode bitmap with inSampleSize to reduce memory usage
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.large_image, options);

// Recycle bitmap to free memory
bitmap.recycle();

3. Activity 的跨进程通信(IPC)

在 Android 中,跨进程通信通常使用 AIDL(Android Interface Definition Language)、Messenger 或 ContentProvider 来实现。

3.1 使用 AIDL

AIDL 提供了一种定义接口以便在不同进程之间通信的方法。

// IMyAidlInterface.aidl
interface IMyAidlInterface {
    void performAction();
}

实现 AIDL 接口:

public class MyService extends Service {
    private final IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() {
        @Override
        public void performAction() {
            // Perform action
        }
    };

    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

在客户端绑定服务:

private IMyAidlInterface mService;

private ServiceConnection mConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName className, IBinder service) {
        mService = IMyAidlInterface.Stub.asInterface(service);
    }

    @Override
    public void onServiceDisconnected(ComponentName className) {
        mService = null;
    }
};

// Bind to the service
Intent intent = new Intent(this, MyService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);

4. 深入理解 Activity 的配置变化处理

配置变化(如屏幕旋转、语言更改等)会导致 Activity 被销毁并重新创建。开发者可以通过重写 onConfigurationChanged 方法来处理特定配置变化,避免 Activity 重新创建。

4.1 在 Manifest 文件中声明配置变化
<activity android:name=".MyActivity"
    android:configChanges="orientation|screenSize|keyboardHidden">
</activity>
4.2 重写 onConfigurationChanged 方法
@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Handle configuration changes
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        // Handle landscape orientation
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        // Handle portrait orientation
    }
}

5. Activity 的调试和日志记录

5.1 使用 Logcat

Logcat 是 Android 提供的日志记录工具,开发者可以使用 Log 类来记录调试信息。

// Log debug information
Log.d("MyActivity", "Debug message");

// Log error information
Log.e("MyActivity", "Error message", throwable);
5.2 使用调试工具

Android Studio 提供了强大的调试工具,包括断点调试、内存分析、性能分析等。

// Use breakpoints to debug the application

6. Activity 的单元测试和 UI 测试

测试是确保应用程序质量的关键环节,Android 提供了多种测试框架和工具来进行单元测试和 UI 测试。

6.1 使用 JUnit 进行单元测试

JUnit 是一个常用的 Java 单元测试框架,Android 提供了对 JUnit 的支持。

// Example unit test
public class MyActivityTest {
    @Test
    public void addition_isCorrect() {
        assertEquals(4, 2 + 2);
    }
}
6.2 使用 Espresso 进行 UI 测试

Espresso 是一个用于编写 UI 测试的框架。

// Example UI test
@RunWith(AndroidJUnit4.class)
public class MyActivityTest {
    @Rule
    public ActivityTestRule<MyActivity> activityRule =
            new ActivityTestRule<>(MyActivity.class);

    @Test
    public void ensureTextChangesWork() {
        onView(withId(R.id.editText))
                .perform(typeText("Hello"), closeSoftKeyboard());
        onView(withId(R.id.changeTextButton)).perform(click());
        onView(withId(R.id.textView)).check(matches(withText("Hello")));
    }
}

总结

深入理解和掌握 Activity 的各个方面,包括其生命周期、内存管理、进程和线程模型、配置变化处理、调试和测试,对于开发高效、稳定和用户友好的 Android 应用程序至关重要。通过不断学习和实践,可以提升应用程序的性能和用户体验,满足不断变化的用户需求。

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

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何修改WordPress网站的域名

我的网站用的是Hostease的虚拟主机&#xff0c;但是域名是之前在其他平台买的&#xff0c;而且已经快到期了&#xff0c;因为主机和域名在不同的平台上&#xff0c;管理不太方便&#xff0c;所以我又在Hostease重新注册了一个域名&#xff0c;然后把网站换成了新的域名&#xf…

配置环境变量

配置环境变量$(xxxx)&#xff0c;代表宏 32位操作系统&#xff0c;请自觉将文中路径中所有的x64换成x86。 %符号表示引用系统环境变量或用户自定义的环境变量 如果你想将某个文件夹添加到Visual Studio的路径中&#xff0c;你可以在环境变量中添加%FolderName%&#xff0c;其…

java项目之高校教师科研管理系统源码(springboot+vue+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的高校教师科研管理系统源码。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 高校教师科研管…

关于python中屏蔽输出

python中屏蔽输出包含屏蔽标准输出&#xff08;比如打印出来的内容&#xff09;、屏蔽标准错误&#xff08;错误信息&#xff09;还有屏蔽logging信息等。 屏蔽标准输出 import contextlib import oswith open(os.devnull, "w") as devnull:with contextlib.redire…

100个 Unity小游戏系列四 -Unity 抽奖游戏专题二 水果机游戏

一、演示效果 二、知识点 2.1 布局 private void CreateItems(){for (int i 0; i < rewardDatas.Length; i){var reward_data rewardDatas[i];GameObject fruitOjb;if (i < itemRoot.childCount){fruitOjb itemRoot.GetChild(i).gameObject;}else{fruitOjb Instant…

大屏表格实现无限滚动效果

实现效果 实现思路 首先固定最外层的高度&#xff0c;并且设置超出高度后隐藏设置每一行的高度为固定35PX&#xff0c;默认显示10行&#xff0c;所以最外层高度就是 35 * 10 表头的高度遍历时克隆一份表格数据&#xff0c;用于视差效果显示设置滚动动画&#xff0c;让表格行所…

VMware vSphere Distributed Services Engine 和利用 DPU 实现网络加速

VMware相关学习专栏&#xff1a;虚拟化技术 vSphere 8.0 通过加速数据处理单元 (DPU) 上的网络功能实现了突破性的工作负载性能。 vSphere 8.0 通过加速 DPU 上的网络功能实现了突破性工作负载性能&#xff0c;从而满足现代分布式工作负载的吞吐量和延迟需求。借助 vSphere Dis…

GIGE 协议摘录

系列文章目录 GIGE 学习笔记 GIGE 协议摘录 文章目录 系列文章目录引言第 1 章 设备发现1.1 链路选择1.1.1 单链路配置1.1.2 多链路配置1.1.3 链路聚合组配置 LAG 1.2 IP配置1.2.1 协议选择1.2.2 静态IP1.2.3 DHCP1.2.4 链接本地地址 LLA 1.3 设备枚举1.3.1 GVCP设备发现 引言 …

4个月赚20万!一张图赚7500!多种变现方式,一个被忽视的暴力项目

大家好&#xff0c;今天给大家带来一个被很多人忽视&#xff0c;不起眼确很暴力的项目。 大胆放心干 课程获取&#xff1a; https://hsgww.com/https://hsgww.com/

停车场变综合楼,结构分析助力低碳设计

PLAXIS 和 RAM 助力确定更有效的结构设计并大幅降低施工成本 总部和周边区域 桑坦德银行位于英国的新总部将现有的四个英国办事处合并到米尔顿凯恩斯的一个中心枢纽&#xff0c;位于伦敦以北 50 英里。 Unity Place 将作为桑坦德银行约 5,000 名员工的办公场所。该项目总投资 …

SpringBoot——整合RabbitMQ收发消息

目录 RabbitMQ消息队列 项目总结 新建一个SpringBoot项目 pom.xml application.properties配置文件 index.html前端页面 RabbitMQConfig配置类 RabbitMQProducer生产者 RabbitMQConsumer消费者 IndexController控制器 SpringbootRabbitmqApplication启动类 测试 Ra…

Linux 删除SSH密钥(id_ed25519),重新生成

在Linux系统中&#xff0c;重新生成SSH密钥&#xff08;比如id_ed25519&#xff09;的过程包括删除现有的密钥文件并生成一个新的。 以下是具体的步骤&#xff1a; 0. 查看下是否有密钥 1. 删除原有的id_ed25519密钥 默认情况下&#xff0c;SSH密钥存储在用户的主目录下的 .…

【Pandas】深入解析`pd.read_sql()`函数

【Pandas】深入解析pd.read_sql()函数 &#x1f308; 欢迎莅临我的个人主页&#x1f448;这里是我深耕Python编程、机器学习和自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;并乐于分享知识与经验的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#xf…

一机实现All in one,NAS如何玩转虚拟机!

常言道&#xff0c;中年男人玩具有三宝 充电器、路由器、NAS 你问我NAS的魔力在哪里&#xff1f; 一机实现All in one洒洒水啦 那NAS又如何玩转虚拟机呢? 跟我来 0基础也能轻松get! NAS如何玩转虚拟机 铁威马NAS的VirtualBox的简单易用&#xff0c;可虚拟的系统包括Win…

基础8 探索JAVA图形编程桌面:邮件操作组件详解

在一个静谧的午后&#xff0c;卧龙和凤雏相邀来到一家古朴典雅的茶馆。茶馆内环境清幽&#xff0c;袅袅的茶香与悠扬的古筝声交织在一起&#xff0c;营造出一种宁静而祥和的氛围。 卧龙和凤雏坐在茶馆的一角&#xff0c;面前的桌子上摆放着一套精致的茶具。茶香四溢&#xff0c…

【机器学习】探究DQN通过训练来解决AI序列决策问题

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好&#xff0c;我是xiaoxie.希望你看完之后,有不足之处请多多谅解&#xff0c;让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …

白酒:不同产地白酒的风格特点与比较

云仓酒庄豪迈白酒&#xff0c;作为中国白酒的一部分&#xff0c;其风格特点深受产区的影响。不同产地的白酒&#xff0c;由于自然环境、酿造工艺等因素的差异&#xff0c;形成了各自与众不同的风味和特点。下面让云仓酒庄豪迈白酒来比较一下不同产地白酒的风格特点。 首先&…

iPhone“已删除”照片被恢复,苹果到底有没有后门?

继微软本周推出的Windows“回忆”功能引发隐私焦虑&#xff0c;遭马斯克和安全大咖们猛烈抨击后&#xff0c;苹果iPhone手机近日也曝出了类似的“记忆门”。 删除十几年的iPhone照片被恢复 近日&#xff0c;有苹果手机用户更新了苹果上周发布的iOS 17.5系统后&#xff0c;意外…

大数据开发面试题【ClickHouse篇】

170、clickhouse介绍以及架构 clickhouse一个分布式列式存储数据库&#xff0c;主要用于在线分析查询 171、列式存储和行式存储有什么区别&#xff1f; 行式存储&#xff1a; 1、数据是按行存储的 2、没有建立索引的查询消耗很大的IO 3、建立索引和视图花费一定的物理空间和…

摩尔投票法——代码实现及注释(力扣169题:找出列表中多数元素)

题源&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 目录 一、摩尔投票法 1.1 关键思想 1.2 时空复杂度 1.3 算法详细步骤 1.4 代码 1.5 算法理解 一、摩尔投票法 摩尔投票法&#xff08;Boyer–Moore Majority Vote Algorithm&#xff09;&#xff0c;也被称为…