Android面试题汇总(即时更新)

当前项目中用了哪些技术(自行处理解决)

子线程中与UI线程通讯
通过handler传输,创建Handler,在子线程中创建Handler,需要Looper对象
如果不刷新UI的话可以调用Looper.prepare(),最后再调用Looper.loop();
如果刷新UI那么需要获取主线程Looper对象,Looper.getMainLooper();

AsyncTask的使用
android中子线程和主线程通讯需要使用到Handler,而在handler中进行耗时操作的话就需要创建线程,AsyncTask就是Handler和Thread的结合。
AsyncTask拥有4个回调方法
1、onPreExecute——运行在UI线程,主要目的是为后台线程的运行做准备。
2、doInBackground——运行在后台线程,他用来负责运行任务。他拥有参数Params,并且返回Result。
3、onProgressUpdate——运行在UI线程,主要目的是用来更新UI线程中显示进度的UI控件。
4、onPostExecute——运行在UI线程,doInBackground后被调用,在此方法中,就可以将Result更新到UI控件上。
AsyncTask需要在主线程中创建,execute方法也必须要主线程中调用。

类锁 对象锁 方法锁 锁的作用域
记住一个关键,锁,锁住的是对象而不是代码块,任何锁针对的都是对象,同一个对象而言,在锁的作用域内只能有一个线程获得当前的锁,其他线程只能等他锁被释放后才能获取该对象的锁。
所以一个类的不同对象间的锁是不干扰。如Test a = new Test() 和 Test b = new Test() Test内的锁对a b而言是不同的。 不同线程可以同时获取a和b的锁
类锁是指static方法或类名.class,这类锁锁住的是类本身,因为static方法 只有一个 被不同对象共享。


线程通讯
wiat 线程挂起等待,并释放当前对象的锁。notity是通知一个线程获取wait后的对象的锁,notityAll是通知所有线程去获取wait后的对象的锁,究竟是哪个一个,由JVM决定。


线程池
创建线程需要花费昂贵的资源和时间,如果任务来了才创建线程那么相应时间会变长,而且一个进程创建的线程数是有限的。为了避免这些,创建若干条线程来处理,他们被称为线程池。
线程池中有固定数目的核心线程和一定的非核心线程,不同数目和核心和非核心线程组成了常见的四种线程池
FixedThreadPool它是个线程数量固定的线程池,该线程池的线程全部为核心线程,它们没有超时机制且排队任务队列无限制,
因为全都是核心线程,所以响应较快,且不用担心线程会被回收。
CachedThreadPool它是一个数量无限多的线程池,它所有的线程都是非核心线程,
当有新任务来时如果没有空闲的线程则直接创建新的线程不会去排队而直接执行,并且超时时间都是60s,
所以此线程池适合执行大量耗时小的任务。由于设置了超时时间为60s,所以当线程空闲一定时间时就会被系统回收,所以理论上该线程池不会有占用系统资源的无用线程。
ScheduledThreadPool线程池像是上两种的合体,它有数量固定的核心线程,且有数量无限多的非核心线程,但是它的非核心线程超时时间是0s,
所以非核心线程一旦空闲立马就会被回收。这类线程池适合用于执行定时任务和固定周期的重复任务。
SingleThreadExecutor它内部只有一个核心线程,它确保所有任务进来都要排队按顺序执行。
它的意义在于,统一所有的外界任务到同一线程中,让调用者可以忽略线程同步问题。
线程池一般用法
shutDown(),关闭线程池,需要执行完已提交的任务;
shutDownNow(),关闭线程池,并尝试结束已提交的任务;
allowCoreThreadTimeOut(boolen),允许核心线程闲置超时回收;
execute(),提交任务无返回值,接收一个Runnable对象作为参数,异步执行。
submit(),提交任务有返回值


栈和堆的区别
基础数据类型、和局部变量存放在栈内,栈中互相共享内存,例如int a=0,int b=0 那么a和b的内存地址是一样的。栈内存放数据先进后出。
new出来的对象都是放在堆内存中,JVM垃圾回收机制负责回收堆中数据,常见的OOM异常说的就是堆的内存溢出。


Android四大组件
activity、service服务、BroadcastReceiver广播、contentProvider内容提供


广播有几种和使用
有序广播和无序广播,有序广播可以设置拦截。动态注册和静态注册,动态注册跟随应用周期。


jni的概念、jni使用
Java Native Interface,即Java本地接口,简称JNI。
JNI是java条用Native语言的一种特性,jni是属于java的,与android无关。
NDK是Android的一个工具开发包,与java无直接关系,快速开发C、C++的动态库,并自动将so和应用一起打包成apk(即可通过NDK在Android中使用JNI与本地代码交互)。
jni注册nativte函数,静态和动态两种。
静态注册首先创建java类,声明Native方法,变异成.class文件,生成.h为后缀的文件,创建.h对应的源文件,然后实现nativte方法。打包so,读取so。
动态注册通过JNINativeMethod的结构体来保持JavaNative函数和JNI函数的一一对应关系。

系统app
system/app下存放的APP就是系统APP,如果app的lib下有so文件,需要移动到system/lib目录。
需要声明系统级权限android:sharedUserId="android.uid.system",而且需要打系统签名包。否则无法安装。

前后台service
startService 默认启动的就是后台服务,前台服务通过context.startForegroundService启动。
前台service启动后会在通知栏显示一个持续存在的Notification,服务被终止的时候Notification后消失,例如音乐播放服务通知。
后台service启动后不会有通知栏展示。
Android8.0后,系统不允许后台应用创建后台服务,只能启动前台服务,启动前台服务后,必须在5秒内调用startForeground来展示通知栏,
不然会ANR,startForeground中的id不能为0,notification不能为null。从业务逻辑角度在 startCommand 中调用。
service的生命周期运行在UI线程,所以不能进行耗时操作,否则一段时间后会ANR,前台服务比后台服务的时间更短,超过就会ANR。

fragment和activity通信
设置方法,然后进行调用
采用接口回调的方式进行数据传递
广播或者使用第三方开源库EventBus。

自定义控件
1.组合控件。这种控件不需要我们自己绘制,而是使用原生控件组合成新控件,例如标题栏。
2.继承原有的控件。这种自定义控件在原生方法外可以自己添加一些方法,比如制作圆角,圆形图片。
3.完全自定义控件直接继承view或viewGroup,控件上展示的内容全部都是我们自己绘制出来。
绘制流程onMeasure(测量) -> onLayout(布局) -> onDraw(绘制)
onMeasure:测量视图大小,三种测量模式 不做任何限制 有确定的大小 自适应 int32位高两位是模式 后面是数值,如果是viewGroup还要依次递归测量子类
onLayout:布局,通过视图的四个顶点坐标确定视图的位置
onDraw:绘制,通过Canvas依次将视图绘制出来,绘制背景,保存画布图层,绘制内容,绘制子视图,还原图层,绘制滚动条。

事件分发机制
三个核心方法:View中的dispatchTouchEvent、onTouchEvent和ViewGroup中独有的onInterceptTouchEvent
正常情况下事件U型传递,即Activity->dispatchTouchEvent-> ViewGroup的dispatchTouchEvent -> ViewGroup的onInterceptTouchEvent -> 
View的dispatchTouchEvent -> View的onTouchEvent -> ViewGroup的onTouchEvent -> Activity的onTouchEvent
dispatchTouchEvent 和 onTouchEvent 返回true,意味着事件被消费,不会再继续分发。
dispatchTouchEvent 返回false,事件不再继续向下分发,并返还给上层的onTouchEvent继续处理。返回super继续向下分发。
onInterceptTouchEvent 返回true,拦截事件,并交给自己ViewGroup的onTouchEvent处理事件。返回false/super 继续向下分发。

MVP
MVP架构是在MVC的基础上进化而来,MVC是Model-数据和业务员逻辑 View-负责与用户交互 Controllor-就是Activity负责项目中的逻辑处理和Model和View之间的交互
MVC中activity作为Controllor使得activity和view的耦合越来越多,索性将activity和view放到一起,重新建立个Presenter负责Model和view之前的交互,这就是MVP。
MVP中,Model与view之间的交互由Presenter完成,Presenter与view之前的交互是通过接口的。

进程间通信使用、binder的理解
IPC有以下几种:Bundle(通过Intent发送)、Messenger(一对多串行通信,数据通过Message传输,底层实现是AIDL)、
AIDL(一对多并行通讯)、ContentProvider、广播、socket、文件共享。Messenger、AIDL、ContentProvider的底层实现都是Binder
AIDL实现过程:
创建AIDL文件,定义方法,系统自动根据AIDL文件生成java文件。
服务器通过AIDL自动生成的java文件调用Stup获取Binder对象。
binder对象通过onBind返回给客户端、
客户端绑定服务,通过asInterface获取的Binder转换成客户端需要的AIDL接口类型的对象
客户端通过AIDL对象调用定义的方法,实现通讯。
Binder是Android的一个类,实现了IBinder接口,从IPC角度说,Binder是Android跨进程通讯的一种方式。
同时还可以理解为一种虚拟的物理设备,它的设备驱动是/dev/binder/。从framework角度说,binder是serviceManager的桥梁。
从应用层来说,Binder是客户端和服务端通信的媒介。可以理解为是一个管道,通信的数据通过binder传输。
binder中DESCRIPTOR,是binder的唯一标识,在创建binder对象的时候,在自动创建的AIDL文件中获取,就是AIDL文件的类名。
asInterface(android.os.IBinder obj) ,将服务端的binder对象转换成客户端所需的AIDL接口类型的对象,这种转换区分进程的
如果客户端和服务端位于同一个进程,那么这个方法返回的是服务端的stub对象本身,否则返回的是系统封装后的Stub.proxy对象。
asBinder,返回当前的Binder对象。
onTransact:该方法运行在服务端的Binder线程池中,当客户端发起通信时,请求通过系统底层封装后交给该方法处理,服务端通过Code值确实请求目标方法是哪个。
Binder注意一些问题,当客户端发起请求时,由于当前线程会被挂起,直到服务返回数据,如果这个方法很耗时,那么不能在UI线程中发起请求。

相机调用流程
申请权限,有申请就得有检查权限,获取相机对象,创建预览界面和操作界面,预览由于是视频,对刷新要求很高需要使用surfaceview,对焦,拍照,录像,保存至图库。
相机是liunx层,肯定需要跨进程通讯,那就需要binder,相机跟性能相关估计会有so,有native c/c++代码,那就还会有jni的调用。但估计这些都是底层封装好了,可以直接调用。
视频数据很大,不是直接跨进程发送,会将视频缓存地址发过来,客户端根据地址进行预览。


性能优化、内存泄露、功耗优化
布局优化:减少布局嵌套,扁平化避免堆叠,背景被覆盖就不设置背景,遮挡部分可以做裁剪不进行绘制,保证绘制在3层以内。尽量使用线性布局和帧布局,线性布局中不适用权重,
使用权重会导致绘制两次,可以使用约束布局。重复布局的多次引用可以使用include和merge的方式。
onDraw中不进行耗时操作,超过16ms的绘制会导致应用降帧,无法保证每秒60帧。
启动APP时设置个背景图,参考微信启动时会展示月球图片,避免使用默认的黑色或白色背景,给人卡顿的感觉。
Application的onCreate中避免非必要的初始化,非必要的初始化可以异步操作。
非静态内部类默认持有外部的类的引用,尽量避免使用非静态内部类,有其handler,如果handler需要context对象可以采用弱引用或软引用。
生命周期结束后将集合、监听、订阅、注册、打开等操作置空避免无法回收。
像listview这种,可以创建viewHolder,进行view复用,避免重复创建view,设置tag的方式避免视图乱串
UI线程内不进行任何耗时操作,耗时操作异步完成
图片资源尽量放置在高分辨率文件下,分辨率越小导致需要内容越大,图片内存取决于长宽和像素内质量,图片默认是ARGB8888占用8个字节,可以使用RGB等占用4个字节。
功耗优化:优化网络请求,使用缓存避免重复多次请求,GPS定位即时关闭,Gzip压缩。

trace文件分析
文件在/data/anr/traces.txt,文件中显示进程id、ANR发生时间点、ANR发生进程包名,根据日志定位发生ANR原因和位置。


多行文本垂直居中的方法
android:gravity="center_vertical"

跨域
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
webView.getSettings().setAllowUniversalAccessFromFileURLs(true);

react和vue的区别
web前端的东西,两者都是JS的UI框架,允许开发者在JavaScript中书写HTML,提供了不同的解决方案

框架和jQuery的区别
和上个问题一样都是web和HTML相关的东西


如何使webpack进打包工具,对项目进行构建与优化
还是web的东西


如何使用使gitlab+docker+k8s+ngnix 进行自动化部署
完全不是android的东西

怎么使echarts展示埋点数据的可视化
JS的东西


视频编码器编码流程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值