- View 事件分发机制:太厉害了,终于有人能把Android 事件分发机制讲的明明白白了! - AndroidAlvin - 博客园
主要是ACTION_DOWN事件流程,还有ACTION_MOVE 和 ACTION_UP,他俩的规律是如果在某个控件的dispatchTouchEvent 返回true消费终结事件,那么收到ACTION_DOWN 的函数也能收到 ACTION_MOVE和ACTION_UP;同样地,对于在onTouchEvent消费事件的情况:在哪个View的onTouchEvent 返回true,那么ACTION_MOVE和ACTION_UP的事件从上往下传到这个View后就不再往下传递了,而直接传给自己的onTouchEvent 并结束本次事件传递过程。
- 自定义 view 流程:阿里面试官: 自定义View跟绘制流程相关知识点?(标准参考解答,值得收藏) - AndroidAlvin - 博客园
- 消息机制:字节跳动一面:请谈下Android消息机制 - AndroidAlvin - 博客园;https://blog.csdn.net/vivo_tech/article/details/110467731
- 设计模式:一文说透 Android 应用架构 MVC、MVP、MVVM 和 组件化 - AndroidAlvin - 博客园;Android 架构模式如何选择-CSDN博客
- MVP中HomeContract是一个抽象的接口,相当于一层协议,用来规定指定的功能的 View 和 Presenter 分别应该具有哪些方法。通常,对于不同的功能,我们需要分别实现一个 MVP,每个 MVP 都会有一个对应的 Contract。笔者认为它的好处在于,将指定的 View 和 Presenter 的接口定义在一个接口中,更加集中。它们各自需要实现的方法也一目了然地展现在了我们面前。
public interface HomeContract {
interface IView extends BaseView {
void setFirstPage(List<HomeBean.IssueList.ItemList> itemLists);
void setNextPage(List<HomeBean.IssueList.ItemList> itemLists);
void onError(String msg);
}
interface IPresenter extends BasePresenter {
void requestFirstPage();
void requestNextPage();
}
}
用户点击按钮后,view层把事件通知给P层(负责完成View于Model间的交互),P层通知M层处理网络数据(网络请求和逻辑处理),处理后将结果数据发送给P层,P层通知view改变界面。(P是桥梁,分别和M、V双向联系)
定义一个公共接口IView,是用于给view的接口继承的,接口中包含了成功和失败的回调,这个接口Activity/Fragment要去实现,最终实现P层通知view改变。
对于面向对象设计来讲,利用接口达到解耦目的已经人尽皆知。
- 四大组件:
- Service:(1)startService->onCreate->onStartCommand->onDestroy;
(启动方和Service并没有关联,只有当Service调用stopSelf或者其他组件调用stopService服务才会终止)
(2)bindService->onCreate->onBind->onUnbind->onDestroy;
(当多次绑定同一个Service时,onBind方法只会执行一次,除非Service终止了)
(当启动方销毁时,自动unBind操作;当发现所有绑定都进行了unBind时才会销毁Service)
-
-
- intentService:需实现onHandleIntent,等待任务执行完毕自动调用stopSelf,内部Handler和HandlerThread实现
- 保证service不被杀死:前台服务、第三方推送、定时管理唤醒android:persistent和android:stopWithTaskBroadcast:系统广播(标准、有序)、本地广播
-
-
-
- 注册方式:静态注册、动态注册(优先级高,生命周期随Context)
-
不能静态:系统运行的基本事件,比如电量变化,屏幕亮灭等会极大程度的消耗系统资源
-
- Activity:onCreate->onStart->onResume->onPause->onStop->onDestroy
- 横竖屏切换:且横屏执行一次、竖屏两次,不配置android:configChanges activity会销毁重建:onPause->onStop->onSaveInstanceState->onDestroy->onCreate->onStart->onRestoreInstanceState->onResume
- 启动模式:标准、栈顶复用、栈内复用、单实例;
- Activity:onCreate->onStart->onResume->onPause->onStop->onDestroy
SingleInstance和SingleTask模式下onStop() ->onNewIntent() -> onRestart() -> onStart() -> onResume();需要在onNewIntent中setIntent获取新的intent信息。
- Activity启动流程:android源码学习- APP启动流程(android12源码)_android app启动流程-CSDN博客
- 稳定性
- Anr 案例:今日头条 ANR 优化实践系列分享 - 实例剖析集锦;干货:ANR日志分析全面解析-CSDN博客
打开data\anr\tace.txt ,观察系统负载: 在 ANR Info 中查看Load
关键字,发现系统在前 1 分钟,前 5 分钟,前 15 分钟各个时段负载,看负载加重趋势。
观察进程 CPU 分布: 进一步观察 CPU usage from 0 ms to 5599 later
关键字,看在 user,kernel 层面 CPU 占比分布,确定是系统侧还是用户侧具体哪个进程出现了耗时,然后继续分析。
超预定时间,未作出有效响应。前台服务20s,广播内容提供者10s,输入事件5s。
-
- Crash:https://blog.csdn.net/vivo_tech/article/details/114028503
- 数据存储:
- 内存泄漏:Android 性能优化之内存泄漏检测以及内存优化(中)_安卓内存泄露测试-CSDN博客,内存优化:Android 性能优化之内存泄漏检测以及内存优化(下)_安卓 占用res 800m 分析内存-CSDN博客
- 内存抖动:比较容易出现内存抖动的地方可能是 convertView 没有复用、频繁拼接小的 String 字符串、在 for 循环中创建对象等等,找到问题所在,解决内存抖动
- 性能优化:
- 布局优化,include、merge、ViewStub:
- 常见优化手段
- Merge
- 在布局文件中使用merge标记作为根视图
- 在需要时,通过include标记将该布局包含进去
- viewStub
- 在布局文件中使用viewStub标记,并将它们设置为invisible或者gone
- 需要加载布局的时候inflate
- 使用viewStub标记过的布局可以提高程序性能,减少cpu、内存开销
- 优化布局层级
- 避免过度绘制
- 移除 XML 中非必需的背景,或根据条件设置。
- 移除 Window 默认的背景。
- 按需显示占位背景图片。
- 或者使用自定义view针对复杂布局减少层级
- Merge
- 常见优化手段
- 多线程、网络
- 附加
- app 启动流程:
【流程概述:从用户手指触摸点击桌面图标到Activity启动
1, 点击桌面APP,发起进程就是Launcher所在的进程,启动远程进程,利用Binder发送消息给SystemServer进程;
2, 在SystemServer中,启动进程的操作会先调用startProcessLocked()方法,该方法内部调用Process.start(),而后通过socket通信告知Zygote进程fork子进程,即APP进程。进程创建后将ActivityThread加载进去,执行ActivityThread.main()方法;
3, 在APP进程中,main()方法会实例化ActivityThread,同时创建ApplicationThread,Looper、Handler对象,调用attach方法进行Binder通信,将thread信息告知ActivityManagerService,接着Looper启动循环;
4, 回到SystemServer中,在attachApplication()中调用bindApplication()和attachApplicationLocked()方法:
bindApplication()方法中最终走到了ActivityThread.handleBindApplication(),创建Application对象,然后绑定Context,创建完Application对象后便是调用mInstrumentation.callApplicationOnCreate()执行Application.onCreate()生命周期;
attachApplicationLocked()方法最终走到了ActivityThread.handLaunchActivity(), 创建Activity对象,然后调用activity.attach()方法,再调用mInstrumentation.callActivityOnCreate()执行Activity.onCreate()生命周期。】
【APP启动流程概览
涉及到四个进程之间的通信,分别是Launcher进程(桌面APP),SystemServer进程(AMS所属进程),Zygote英 [ˈzaɪɡəʊt] 进程(系统和所有APP的创建进程),APP进程。
APP简要的启动流程是这样的:
1.Launcher进程会通过binder的方式通知SystemServer进程。
2.然后SystemServer进程中的AMS会查询对应的Activity栈信息,如果对应APP进程不存在则会加载占位图。然后通过socket的方式通知Zygote去创建APP进程。
3.APP进程创建后会执行main方法,然后通知AMS。
4.AMS收到信息后会继续通知APP进程去创建Application然后拉起Activity。
5.APP进程依次收到通知后,会依次完成加载APK,初始化Application,执行Activity生命周期等操作。最终会把首屏展示出来。
————————————————
原文链接:https://blog.csdn.net/rzleilei/article/details/125665839】
- 安卓系统架构:
- Binder 机制:
13、Android性能工具——Systrace使用:
一般用Systrace(Android性能工具——Systrace使用_android atrace -a* app-CSDN博客)用来分析卡顿、启动时间慢等问题,还可以用来分析方法耗时等。Systrace的原理:它的思想很朴素,在系统的一些关键链路(比如System Service,虚拟机,Binder驱动)插入一些信息(我这里称之为Label),通过Label的开始和结束来确定某个核心过程的执行时间,然后把这些Label信息收集起来得到系统关键路径的运行时间信息,进而得到整个系统的运行性能信息。Android Framework里面一些重要的模块都插入了Label信息(Java层的通过android.os.Trace类完成,native层通过ATrace宏完成),用户App中可以添加自定义的Label(自定义Trace Label解决;Android SDK中提供了android.os.Trace#beginSection和android.os.Trace#endSection 这两个接口;我们可以在代码中插入这些代码来分析某个特定的过程;https://blog.csdn.net/Jason_Lee155/article/details/126691265),这样就组成了一个完成的性能分析系统。另外说明的是:Systrace对系统版本有一个要求,就是需要Android 4.1以上。系统版本越高,Android Framework中添加的系统可用Label就越多,能够支持和分析的系统模块也就越多;因此,在可能的情况下,尽可能使用高版本的Android系统来进行分析。
14、Zygote去fork进程为什么使用socket而不使用binder?
进程的fork,是拷贝一个和原进程一摸一样的进程,其中的各种内存对象自然也会被拷贝。所以用来接收消息去fork进程的binder对象自然也会被拷贝。但是这个拷贝对于APP层有用吗?那自然是没用的,所以就凭白多占用了一块无用的内存区域。
说到这你自然想问,如果通过socket的方式,不也平白无故的多占用一块Socket内存区域吗?是的,确实是,但是fork出APP进程之后,APP进程会去主动的关闭掉这个socket,从而释放这块区域。Binder的特殊性在于其是成对存在的,其分为Client端对象和Server端对象。假设我们使用binder,那么因为APP端的binder是拷贝自Zygote进程的,所以如果要释放掉APP的Server端binder引用对象,就必须释放掉AMS中的Client端binder对象,那这样就会导致AMS失去binder从而无法正常向Zygote发送消息。
————————————————
原文链接:android中AMS通知Zygote去fork进程为什么使用socket而不使用binder?_zygote为什么用socket-CSDN博客
- 单例
Android系统在每个程序运行的时候创建一个Application对象,而且只会创建一个,所以Application 是单例(singleton)模式的一个类。
面试问题一:
Presenter在什么时候完成初始化的
View绘制的流程
Handler机制
线程阻塞和死锁的含义
Android进程间通信的方式
Binder https://blog.csdn.net/u013620306/article/details/128497190
讲一下做过的内存优化
Systrace用过没有
ANR,Crash怎么处理
Exception和Error都是Throwable的子类。运行时异常RuntimeException是不检查异常,比如NullPointer和IndexOutOfBounds一般由逻辑错误引起,程序中可以选择捕获处理,也可以不处理,编译器不会检查它。除此之外是非运行时也叫编译异常,一般是语法问题,如IOException、SQLException、ClassNotFound不处理,程序就编译不过。
Error是一种严重的问题,如OutOfMemery和IOError等,是jvm不能处理的错误。
面试问题二:
四大组件之间如何通信
Fragment和Activity之间如何通信,他们的区别
消息机制
APK瘦身 Android中apk瘦身_android apk瘦身-CSDN博客
-
- 1. 对lib目录下的文件进行瘦身处理
- 2. 优化res,assets文件大小
- 3.使用图片压缩工具对图片进行压缩
- 4.尽量不要使用帧动画,参考使用lottie动画;图片使用webp、svg(不光占用小,还不区分分辨率)
- 5.使用gradle开启shrinkResources 开启混淆 移除无用资源
- 6. 然后删除一下项目中无用的框架或者重复的框架。
内存优化和线程优化最近的项目中怎么做的
ANR怎么避免
介绍一下你做的项目,是做什么的,你负责的模块,有什么技术点,遇到过什么问题
《项目一FTTR智慧助手》是一款主要提供给企业使用的光纤组网解决方案,
我负责部署模块移动设备和移动设备后的重新仿真功能、工勘模块移动点位以及在顺次连点成线围成闭合区域来表示WiFi覆盖范围、负责app升级检测(通过断点续传更新安装包,版本号判断是否强制更新)、自定义新手引导功能(做了哪些)、常用弹框组件封装(做了哪些)等。
《项目二LinkHome和WeFTTR》是一款用于精细化管理智能网关和家庭网络的应用,包括网关配置管理、WIFI设置、故障采集、家长控制、访客网络、分段测速等功能。
我负责故障信息采集上传问题(解决定时查询和界面上完成提示语只弹出一次的问题)、应用限制功能(详情页面和列表选择页面数据如何同步,流式标签的自定义实现)等。
面试问题三:
进程间如何通信
性能优化是怎么做的
SettingsProvider里面的三张表 https://blog.csdn.net/johnwang7/article/details/120216107,https://blog.csdn.net/qq_43804080/article/details/106049475
AMS,PMS的理解
ANR问题怎么处理的,遇到死锁怎么办
死锁https://blog.csdn.net/weixin_61061381/article/details/126114468
事件分发
安卓常见的七大布局:线性、相对、帧、绝对、表格、网格、约束布局https://blog.csdn.net/weixin_42022380/article/details/122773801
面试问题四:
页面A切B的生命周期变化 Android面试:ActivityA与ActivityB相互跳转对应生命周期变化_activitya跳转到b生命周期-CSDN博客
什么场景做序列化 Serialzable和Parcelable的区别?Bunder传递对象为什么需要序列化?_bundle 序列化传输-CSDN博客
-
- 一、intent传输可直接传递零零散散的数据,或者通过bundle将零零散散的数据打包传递;
- 二、 因为Intent中只支持传递基本类型的数据,以及String和数组集合。因此你如果想传递一个你自己的对象,经常要序列化才行。
- 传递对象的方式有两种:将对象转换为Json字符串或者通过Serializable,Parcelable序列化 不建议使用Android内置的抠脚Json解析器,可使用fastjson或者Gson第三方库!
- 序列化,表示将一个对象转换成可存储或可传输的状态。序列化后的对象可以在网络上进行传输,也可以存储到本地。序列化就相当于把这个对象转换成了字符串。
- 普通的由Zygote孵化而来的用户进程,所映射的Binder内存大小是不到1M的,准确说是 (1024*1024) - (4096 *2)。Binder传输数据的大小限制(内核4M 上层限制1M-8K),传输Bitmap过大就会崩溃的原因,Activity之间传输BitMap,单个Bundle不能超过50KB,Intent中Bundle里的东西有5034408bytes。整个进程内所有的bundle共享内存大小不能超过1MB。
- 两者的比较:
1)在使用内存的时候,Parcelable比Serializable性能高,所以推荐使用Parcelable。
2)Serializable在序列化的时候会产生大量的临时变量,从而引起频繁的GC。
3)Parcelable不能使用在要将数据存储在磁盘上的情况,因为Parcelable不能很好的保证数据的 持续性在外界有变化的情况下。尽管Serializable效率低点,但此时还是建议使用Serializable。
做了哪些性能优化的工作
事件分发,从点击一个按钮开始
自定义view的流程,你怎么做的
Handler用在哪里,说一下handler是怎么到主线程的
进程间通信方式 https://blog.csdn.net/lutao2599/article/details/122969128,https://www.cnblogs.com/cr330326/p/9785894.html
四大组件通信https://www.cnblogs.com/huangjialin/p/6019746.html
SettingProvider的三张表
MVVM相比MVP的好处,讲一下Jetpack 架构组件的ViewModel
软件架构设计六大原则总结下软件设计的六大原则 - 简书,
软件架构设计六大原则 - 寒小韩 - 博客园
1.开闭原则、2.依赖倒置、3.单一职责、4.接口隔离、5.迪米特、6.里氏替换(7.合成复用)
网易Bug评级为轻危,依据为:在实际业务场景中,该bug触发条件极其苛刻,概率较低,且有修复方案,暂未被触发或造成不良影响。
面试问题五:手机相机,图册相关
openCamera流程
窗口绘制流程
Handler机制,非MainLoop讲一下
字符串拼接用哪个,两个的优缺点
系统性能优化做过哪些工作
面试问题六:
项目中的技术点
Handler线程通信的原理
自定义view的流程 https://www.cnblogs.com/Android-Alvin/p/12297933.html
安卓稳定性问题中anr怎么解决的(常见的输入事件anr如何分析)
https://www.jianshu.com/p/01b69d91a3a8
Android ANR详解-CSDN博客
https://blog.csdn.net/weixin_36057741/article/details/112875392
面试问题七:
两个Activity之间跳转的生命周期
Activity怎么以窗口形式启动
Activity启动过程
缓存方式
单点登录https://authing.csdn.net/637da8249ebab8287a4f43a7.html
第一种:session广播机制实现;第二种:使用cookie + redis 实现;第三种:使用token
实现单点登录指的是同一个账户(id)不能在一个以上的设备上登录对应的用户系统(排除web端和移动端可以同时登录的情况),例如:用户m在A设备登录并保持登录状态,然后又在B设备登录,此时A应该要强制下线,m无法在A设备上继续执行用户相关的操作。https://blog.csdn.net/qq_31255289/article/details/52587709
服务端
服务端需要集成Token,每次在app登录时为app分配新的token,如果在某次http请求中app传递token不是最新的,则视为需要重新登录(或者根据自己需要后台设定token有效时间,过期视为Token失效,需要重新登录).在token失效的情况下,返回约定好的code。
Java四种引用方式 https://blog.csdn.net/sugarxxc/article/details/12706296
Service保证不被杀死
TCP/UDP基本区别
事件分发机制
安卓有几种布局https://www.cnblogs.com/tsingke/p/9007563.html
https://www.jianshu.com/p/82ecfc95924f,广播
Jetpack 架构组件:ViewModel_jetpack业务逻辑写在哪里-CSDN博客,ViewModel
https://blog.csdn.net/gmgm201024/,子线程的创建方式(三种)
https://blog.csdn.net/sinat_30474567/article/details/52176698,Android传递Bitmap的几种简单方式
https://biglead.blog.csdn.net/article/details/127533643,Serialzable和Parcelable的区别
https://blog.csdn.net/Momo_Da/article/details/119324669,apk瘦身
https://blog.csdn.net/dlutbrucezhang/article/details/8577653,四大物件
https://blog.csdn.net/u014702653/article/details/75268919,RxJava2+Retrofit2+RxLifecycle2使用MVP模式构建项目
https://blog.csdn.net/weixin_39825941/article/details/113587317,mvp关联activity生命周期_Android MVP架构从入门到精通-真枪实弹
因为创建线程是一个比较耗费资源的事,所以不能频繁创建和释放线程,因此在效率上使用线程池。