安卓APP实战(二):Activity管理,内存回收及LeakCanary监测

每一个Activity组件都是一个单独的界面,承载着与用户交互的任务。也是应用最基本的功能之一,在不同界面之间切换,并实现不同的功能。
每一个程序必须要有一个Activity作为入口(Manifest文件中将其<category>标签设置为LAUNCHER),然后通过界面控制到达其他的界面。

Activity是具有生命周期的,在不同生命周期会执行其中回调方法。所有的方法在自己的Activity中可以进行重写。安卓中添加新的Activity可以通过AS进行选择新建不同的类型,以减少部分代码量。

下面的文章中对Activity做了不错的介绍。并通过简单的LOG打印日志可以清晰看到各执行Activity和切换Activity的执行顺序。
参考:https://www.cnblogs.com/caobotao/p/4987015.html

配合下面官方给的生命周期图,对Activity做一个初步的理解。
1.当我们打开一个Activity,执行onCreated方法,进入created(已创建)状态,这时候大概会去内存中将Activity类需要的资源全部申请成功。
2.第二步会接着执行onStart方法,进入started(已启动)状态。这时候我们便可以看到这个界面,但是是无法进行操作的,这时候整个界面已经渲染完成。
3.第三步执行onResume方法,进入resumed(Resume有重新开始,继续的意思,然而在第一次创建时并没有继续,重新,所以个人认为用focused(已获取焦点)或running(运行中)似乎更恰当)状态,此时获取了应用的焦点,我们才能对界面进行操作,至此Activity才算是正常的启动并提供服务了,若没有其他操作应用将保持此状态。

以上三步是Activity创建后固定顺序执行的步骤对应三个状态。在图片中有个状态转换需要调用的方法名,可以认为调用控制Activity的生命状态。
4.paused(暂停)状态。官方定义是partially visible(部分可见)。即界面被遮挡了,并且未全部遮挡,比如一些弹框等。此时遮挡界面将会获得应用的焦点,而原本的界面失去焦点无法操作,此时界面显示的渲染依然都在。
5.stopped(停止)状态。官方定义是hidden(隐藏的)。当界面被完全覆盖时,前台渲染已经销毁了,只有内存中Activity的对象等还存在。
6.Destroyed(已销毁的)状态。销毁的执行大致有三种情况:1.系统内存不足时自动销毁停止,暂停状态的Activity. 2.调用finish()方法。销毁时会根据当前状态顺序执行 onPause()->onStop->onDestroy(),如处于stopped状态就只调用onDestroy。

对于Activity的生命周期必须进行管理,否则很容易发生OOM(Out of memory)的异常。比如频繁切换(startActivity()方法),10次左右就会发生OOM,导致程序奔溃(模拟器会停止运行,使用真机调试会报错,到不影响程序运行)。

在这里插入图片描述

Activity界面切换使用方法startActivity (Intent intent)。
基本的写法就是 startActivity(new Intent(ActivityBefore.this, ActivityAfter.class)); ActivityBefore就是切换前的Activity类,ActivityAfter是切换后的目标Activity类。

在进行Activity切换时需要对Activity生命周期进行管理避免造成OOM。在不再需要使用的Activity中调用finish函数,销毁并收回占用的内存及资源。

需求中数字选择界面可以选择1到9,选择进入书写界面,书写界面有返回按钮,点击后调用startActivity切换回数字选择界面。此时若进入数字1书写界面,然后返回数字选择界面,然后重复选择剩余数字切换界面,在切换第九个数字时便会出现OOM异常。内存情况如下。每次新点开一个数字书写界面,内存会不断被占用而不被释放,最终导致内存溢出。
在这里插入图片描述

因为从数字书写界面返回后,我们可以认为此界面不会再被使用,因为此界面没有任何信息需要储存,重新选择进入时我们只需要重新创建即可,此时避免Activity切换造成的内存溢出可以做两种处理:

1.在调用startActivity进行切换后,调用finish()函数,将不需要使用的Activity销毁,此时会根据Activity当前状态去选择执行pause,stop,destroy函数,如处于stopped状态就只调用onDestroy。。
2.若使用手机自带返回事件,如返回键,触发后会顺序执行pause,stop,destroy三个函数,对Activity进行销毁。

安卓使用任务栈管理Activity,startActivity的作用是将另一个Activity放置到栈顶,当前Activity并未销毁,而是位于栈顶第二位,此时按下返回键便可以重回栈顶。而使用finish(),则会将其移出栈,按下返回键也无法返回。

参考:https://www.cnblogs.com/whieenz/p/8047139.html

管理Activity时,还需要注意Activity中对象的回收,如bitmap,thread,handler等等,避免Activity无法被正常回收。
此部分内容还未细究
可参考:https://blog.csdn.net/chen825919148/article/details/23843049

为了很好的监测内存溢出的情况,使用LeakCanary进行监测。而其使用也非常简单。

1.在Module的build.gradle文件中增加依赖包,此时要重新build项目。

	dependencies {
		.......//其他依赖包
		debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.4'
   	 	releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4'
   	 }

2.自定义Application类。
若LeakCanary引用有问题,则build发生异常,尝试重新build即可,使用就只要在1中添加依赖就可以,不需要其他任何操作。自定义Application类后,在Manifest文件中<application>标签中的 android:name 属性 更改为自定义类,如 android:name=“com.example.wangjy.application.App”

import com.squareup.leakcanary.LeakCanary;
import com.squareup.leakcanary.RefWatcher;

	public class App extends Application {

    private RefWatcher refWatcher;

    @Override
    public void onCreate() {
        // 程序创建的时候执行
        super.onCreate();
        refWatcher = LeakCanary.install(this);
    }
   
    public static RefWatcher getRefWatcher(Context context){
        App application = (App)context.getApplicationContext();
        return application.refWatcher;
    }
}

3.进行调用
在需要监测的Activity中增加

RefWatcher refWatcher = App.getRefWatcher(this);
        refWatcher.watch(this);

为了方便使用,可以使用继承,在父类中进行监测。

最后关于Activity之间的参数传递。
最常用最基本的就是基本数据类型的传递。
使用intent传递即可。
在调用startActivity之前,先使用intent.putExtra(key,value)设置传递的参数。key是参数名,value是参数值。如(“what”,“abcd”)
在接收参数时,调用getIntent().get + 数据类型+ Extra(key)
如:
SelectActivity(跳转前,发送方)中

Intent goWrite = new Intent(SelectActivity.this, WriteActivity.class);
            goWrite.putExtra("num", num);
            startActivity(goWrite);

WriteActivity(跳转后,接收方)中

num = getIntent().getIntExtra("num", -1);

参考:https://www.cnblogs.com/icyhusky/p/5964756.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值