本文介绍: 5.静态View导致泄漏使用静态View可以避免每次启动Activity都去读取渲染View,但是静态View会持有Activity引用,导致无法回收解决办法是在Activity销毁的时候将静态View设置null(View一旦被加载界面中将会持有一个Context对象引用,在这个例子中,这个context对象我们的Activity声明一个静态变量引用这个View,也就引用activity)6.WebView导致的内存泄漏WebView只要使用一次内存就不会被释放,所以WebView都

5.静态View导致泄漏使用静态View可以避免每次启动Activity都去读取并渲染View,但是静态View会持有Activity引用,导致无法回收解决办法是在Activity销毁的时候将静态View设置为null(View一旦被加载到界面中将会持有一个Context对象引用,在这个例子中,这个context对象我们的Activity,声明一个静态变量引用这个View,也就引用了activity

6.WebView导致的内存泄漏WebView只要使用一次内存就不会被释放,所以WebView都存在内存泄漏的问题,通常的解决办法是为WebView单开一个进程,使用AIDL进行通信,根据业务需求在合适的时机释放掉

7.资源对象关闭导致如Cursor,File等,内部往往都使用了缓冲,会造成内存泄漏,一定要确保关闭它并将引用置为null

8.集合中的对象清理集合用于保存对象,如果集合越来越大,不进行合理的清理,尤其是入股集合是静态的

9.Bitmap导致内存泄漏bitmap比较占内存的,所以一定要在不使用的时候及时进行清理,避免静态变量持有大的bitmap对象

10.监听器未关闭很多需要register和unregister系统服务要在合适的时候进行unregister,手动添加listener需要及时移除

##如何避免OOM?

1.使用更加轻量数据结构:如使用ArrayMap/SparseArray替代HashMap,HashMap更耗内存,因为它需要额外实例对象记录Mapping操作,SparseArray更加高效,因为它避免了Key Value自动装箱,和装箱后的解箱操作

2.便面枚举的使用,可以用静态常量或者注解@IntDef替代

3.Bitmap优化:a.尺寸压缩通过InSampleSize设置合适的缩放b.颜色质量设置合适的format,ARGB_6666/RBG_545/ARGB_4444/ALPHA_6,存在很大差异c.inBitmap:使用inBitmap属性可以告知Bitmap解码器尝试使用已经存在的内存区域,新解码的Bitmap尝试去使用之前那张Bitmap在Heap中所占据的pixel data内存区域,而不是去问内存重新申请一块区域存放Bitmap利用这种特性,即使是上千张的图片,也只会仅仅只需要占用屏幕所能够显示图片数量的内存大小,但复用存在一些限制,具体体现在:在Android 4.4之前只能重用相同大小的Bitmap的内存,而Android 4.4及以后版本则只要后来的Bitmap比之前的小即可。使用inBitmap参数前,每创建一个Bitmap对象都会分配一块内存供其使用,而使用了inBitmap参数后,多个Bitmap可以复用一块内存,这样可以提高性能

4.StringBuilder替代String: 在有些时候,代码中会需要使用到大量的字符串拼接操作,这种时候有必要考虑使用StringBuilder来替代频繁的“+”

5.避免在类似onDraw这样的方法创建对象,因为它会迅速占用大量内存,引起频繁的GC甚至内存抖动

6.减少内存泄漏也是一种避免OOM的方法

##说下 Activity 的
启动模式生命周期两个 Activity 跳转生命周期,如果一个 Activity 跳转一个 Activity 再按下 Home 键在回到 Activity 的生命周期什么样的

启动模式

Standard 模式:Activity 可以有多个实例,每次启动 Activity,无论任务栈中是否已经有这个Activity的实例系统都会创建一个新的Activity实例

SingleTop模式:当一个singleTop模式的Activity已经位于任务栈的栈顶,再去启动它时,不会再创建新的实例,如果不位于栈顶,就会创建新的实例

SingleTask模式:如果Activity已经位于栈顶,系统不会创建新的Activity实例,和singleTop模式一样。但Activity已经存在但不位于栈顶时,系统就会把该Activity移到栈顶,并把它上面的activity出栈

SingleInstance模式:singleInstance 模式也是单例的,但和singleTask不同,singleTask 只是任务栈内单例系统里是可以有多个singleTask Activity实例的,而 singleInstance Activity 在整个系统里只有一个实例,启动一singleInstanceActivity 时,系统会创建一个新的任务栈,并且这个任务栈只有他一个Activity

生命周期

onCreate onStart onResume onPause onStop onDestroy

两个 Activity 跳转生命周期1.启动AonCreate – onStart – onResume

2.在A中启动BActivityA onPauseActivityB onCreateActivityB onStartActivityB onResumeActivityA onStop

3.从B中返回A(按物理硬件返回键)ActivityB onPauseActivityA onRestartActivityA onStartActivityA onResumeActivityB onStopActivityB onDestroy

4.继续返回ActivityA onPauseActivityA onStopActivityA onDestroy

##onRestart调用场景

(1)按下home键之后,然后切换回来,会调用onRestart()。(2)从本Activity跳转到另一个Activity之后,按back返回原来Activity,会调用onRestart();(3)从本Activity切换到其他的应用然后再从其他应用切换回来,会调用onRestart();

说下 Activity 的横竖屏的切换的生命周期,用那个方法保存数据,两者的区别触发什么时候在那个方法里可以获取数据等。

是否了 SurfaceView,它是什么?他的继承方式什么?他与View的区别(从源码角度,如加载绘制等)。

SurfaceView中采用了双缓冲机制,保证了UI界面的流畅性,同时 SurfaceView 不在主线程中绘制,而是另开辟一个线程绘制,所以它不妨碍UI线程

SurfaceView 继承于View,他和View主要有以下三点区别:(1)View底层没有缓冲机制,SurfaceView有;(2)view主要适用于主动更新,而SurfaceView适用与被动的更新,如频繁的刷新(3)view会在主线程中去更新UI,而SurfaceView则在子线程刷新;SurfaceView的内容不在应用窗口上,所以不能使用变换(平移、缩放、旋转等)。也难以放在ListView或者ScrollView中,不能使用UI控件的一些特性比如View.setAlpha()

View:显示视图内置画布,提供图形绘制函数、触屏事件按键事件函数等;必须在UI主线程内更新画面,速度较慢。SurfaceView:基于view视图进行拓展的视图类,更适合2D游戏开发;是view子类,类似使用双缓机制,在新的线程中更新画面所以刷新界面速度比view快,Camera预览界面使用SurfaceView。GLSurfaceView:基于SurfaceView视图再次进行拓展的视图类,专用于3D游戏开发的视图;是SurfaceView的子类openGL专用。

##如何实现进程保活

a: Service 设置成 START_STICKY kill 后会被重启(等待5秒左右),重传Intent,保持与重启前一样b: 通过 startForeground将进程设置为前台进程, 做前台服务优先级和前台应用一个级别,除非在系统内存非常缺,否则此进程不会被 killc: 双进程Service: 让2个进程互相保护对方,其中一个Service被清理后,另外没被清理的进程可以立即重启进程d: 用C编写守护进程(即子进程) : Android系统当前进程(Process)fork出来的子进程,被系统认为是两个不同的进程。当父进程被杀死的时候,子进程仍然可以存活,并不受影响(Android5.0以上的版本不可行)联系厂商加入白名单e.锁屏状态下,开启一个一像素Activity

##说下冷启动与热启动是什么区别如何优化,使用场景等。

app冷启动: 当应用启动时,后台没有应用的进程,这时系统会重新创建一个新的进程分配给该应用, 这个启动方式就叫做冷启动(后台存在应用进程)。冷启动因为系统会重新创建一个新的进程分配给它,所以会先创建和初始化Application类,再创建和初始化MainActivity类(包括一系列测量布局绘制),最后显示在界面上。

app热启动: 当应用已经被打开, 但是被按下返回键、Home键等按键时回到桌面或者是其他程序的时候,再重新打开该app时, 这个方式叫做热启动(后台已经存在该应用进程)。热启动因为会从已有的进程中来启动,所以热启动就不会走Application这步了,而是直接走MainActivity(包括一系列测量布局、绘制),所以热启动的过程只需要创建和初始化一个MainActivity就行了,而不必创建和初始化Application

冷启动的流程点击app的启动图标时,安卓系统会从Zygote进程中fork创建出一个新的进程分配给该应用,之后会依次创建和初始化Application类、创建MainActivity类、加载主题样式Theme中的windowBackground等属性设置给MainActivity以及配置Activity层级上的一些属性、再inflate布局、当onCreate/onStart/onResume方法都走完了后最后才进行contentView的measure/layout/draw显示在界面上

冷启动的生命周期简要流程:Application构造方法 –> attachBaseContext()–>onCreate –>Activity构造方法 –> onCreate() –> 配置主体中的背景操作 –>onStart() –> onResume() –> 测量、布局、绘制显示

冷启动的优化主要是视觉上的优化解决白屏问题提高用户体验,所以通过上面冷启动的过程。能做的优化如下

减少 onCreate()方法工作量

不要让 Application 参与业务的操作

不要在 Application 进行耗时操作

不要以静态变量方式在 Application 保存数据

减少布局的复杂度和层级

减少主线程耗时

为什么冷启动会有白屏黑屏问题原因在于加载主题样式Theme中的windowBackground等属性设置给MainActivity发生在inflate布局当onCreate/onStart/onResume方法之前,而windowBackground背景被设置成了白色或者黑色,所以我们进入app第一个界面的时候会造成先白屏黑屏一下再进入界面。解决思路如下

1.给他设置 windowBackground 背景跟启动页的背景相同,如果你的启动页是张图片那么可以直接给 windowBackground 这个属性设置该图片那么就不会有一闪的效果

2.采用世面的处理方法,设置背景是透明的,给人一种延迟启动的感觉。,将背景颜色设置为透明色,这样当用户点击桌面APP图片的时候,并不会”立即”进入APP,而且在桌面上停留一会,其实这时候APP已经是启动的了,只是我们心机的把Theme里的windowBackground 的颜色设置成透明的,强行把锅甩给了手机应用厂商手机反应太慢了啦)

3.以上两种方法是在视觉上显得更快,但其实只是一种表象,让应用启动的更快,有一种思路,将 Application 中的不必要的初始化动作实现懒加载,比如,在SpashActivity 显示后再发送消息到 Application,去初始化,这样可以将初始化动作放在后边,缩短应用启动到用户看到界面的时间

##Android 中的线程有那些,原理与各自特点
实现懒加载,比如,在SpashActivity 显示后再发送消息到 Application,去初始化,这样可以将初始化的动作放在后边,缩短应用启动到用户看到界面的时间

##Android 中的线程有那些,原理与各自特点

原文地址:https://blog.csdn.net/m0_66144765/article/details/122729505

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_21724.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注