金九银十中,看看这31道Android面试题

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
云解析DNS,个人版 1个月
简介: 金九银十中,看看这31道Android面试题

阅读目录

  • 1.如何对 Android 应用进行性能分析
  • 2.什么情况下会导致内存泄露
  • 3.如何避免 OOM 异常
  • 4.Android 中如何捕获未捕获的异常
  • 5.ANR 是什么?怎样避免和解决 ANR(重要)
  • 6.Android 线程间通信有哪几种方式
  • 7.Devik 进程,linux 进程,线程的区别
  • 8.描述一下 android 的系统架构
  • 9.android 应用对内存是如何限制的?我们应该如何合理使用内存?
  • 10. 简述 android 应用程序结构是哪些
  • 11.请解释下 Android 程序运行时权限与文件系统权限的区别
  • 12.Framework 工作方式及原理,Activity 是如何生成一个 view 的,机制是什么
  • 13.多线程间通信和多进程之间通信有什么不同,分别怎么实现
  • 14.Android 屏幕适配
  • 15.什么是 AIDL 以及如何使用
  • 16.Handler 机制
  • 17.事件分发机制
  • 18.子线程发消息到主线程进行更新 UI,除了 handler 和 AsyncTask,还有什么
  • 19.子线程中能不能 new handler?为什么
  • 20.Android 中的动画有哪几类,它们的特点和区别是什么
  • 21.如何修改 Activity 进入和退出动画
  • 22.SurfaceView & View 的区别
  • 23.开发中都使用过哪些框架、平台
  • 24.使用过那些自定义View
  • 25.自定义控件:绘制圆环的实现过程
  • 26.自定义控件:摩天轮的实现过程
  • 27.GridLayout的使用
  • 28.流式布局的实现过程
  • 29.第三方登陆
  • 30.第三方支付
  • 31.进程保活

一 性能优化

1.如何对 Android 应用进行性能分析

android 性能主要之响应速度 和UI刷新速度。

可以参考博客:Android系统性能调优工具介绍

首先从函数的耗时来说,有一个工具TraceView 这是androidsdk自带的工作,用于测量函数耗时的。

UI布局的分析,可以有2块,一块就是Hierarchy Viewer 可以看到View的布局层次,以及每个View刷新加载的时间。

这样可以很快定位到那块layout & View 耗时最长。

还有就是通过自定义View来减少view的层次。

浅谈App的性能优化

Android性能优化:手把手带你全面实现内存优化

Android性能优化 (1)—— 内存溢出和内存泄漏的介绍

2.什么情况下会导致内存泄露

内存泄露是个折腾的问题。

什么时候会发生内存泄露?内存泄露的根本原因:长生命周期的对象持有短生命周期的对象。短周期对象就无法及时释放。

I. 静态集合类引起内存泄露

主要是hashmap,Vector等,如果是静态集合 这些集合没有及时setnull的话,就会一直持有这些对象。

II.remove 方法无法删除set集 Objects.hash(firstName, lastName);

经过测试,hashcode修改后,就没有办法remove了。

III. observer 我们在使用监听器的时候,往往是addxxxlistener,但是当我们不需要的时候,忘记removexxxlistener,就容易内存leak。

广播没有unregisterrecevier

IV.各种数据链接没有关闭,数据库contentprovider,io,sokect等。cursor

V.内部类:

java中的内部类(匿名内部类),会持有宿主类的强引用this。

所以如果是new Thread这种,后台线程的操作,当线程没有执行结束时,activity不会被回收。

Context的引用,当TextView 等等都会持有上下文的引用。如果有static drawable,就会导致该内存无法释放。

VI.单例

单例 是一个全局的静态对象,当持有某个复制的类A是,A无法被释放,内存leak。

3.如何避免 OOM 异常

首先OOM是什么?

当程序需要申请一段“大”内存,但是虚拟机没有办法及时的给到,即使做了GC操作以后

这就会抛出 OutOfMemoryException 也就是OOM

Android的OOM怎么样?

为了减少单个APP对整个系统的影响,android为每个app设置了一个内存上限。

public void getMemoryLimited(Activity context)   {       ActivityManager activityManager =(ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE);       System.out.println(activityManager.getMemoryClass());       System.out.println(activityManager.getLargeMemoryClass());       System.out.println(Runtime.getRuntime().maxMemory()/(1024*1024));   }

HTC M7实测,192M上限。512M 一般情况下,192M就是上限,但是由于某些特殊情况,android允许使用一个更大的RAM。

如何避免OOM

减少内存对象的占用

I.ArrayMap/SparseArray代替hashmap

II.避免在android里面使用Enum

III.减少bitmap的内存占用

  • inSampleSize:缩放比例,在把图片载入内存之前,我们需要先计算出一个合适的缩放比例,避免不必要的大图载入。
  • decode format:解码格式,选择ARGB_8888/RBG_565/ARGB_4444/ALPHA_8,存在很大差异。

IV.减少资源图片的大小,过大的图片可以考虑分段加载

内存对象的重复利用

大多数对象的复用,都是利用对象池的技术。

I.listview/gridview/recycleview contentview的复用

II.inBitmap 属性对于内存对象的复用ARGB_8888/RBG_565/ARGB_4444/ALPHA_8

这个方法在某些条件下非常有用,比如要加载上千张图片的时候。

III.避免在ondraw方法里面 new对象

IV.StringBuilder 代替+

4.Android 中如何捕获未捕获的异常

image

CrashHandler

关键是实现Thread.UncaughtExceptionHandler

然后是在application的oncreate里面注册。

5.ANR 是什么?怎样避免和解决 ANR(重要)

ANR->Application Not Responding

也就是在规定的时间内,没有响应。

三种类型:

1). KeyDispatchTimeout(5 seconds) —主要类型按键或触摸事件在特定时间内无响应

2). BroadcastTimeout(10 seconds) —BroadcastReceiver在特定时间内无法处理完成

3). ServiceTimeout(20 seconds) —小概率类型 Service在特定的时间内无法处理完成

为什么会超时:事件没有机会处理 & 事件处理超时

怎么避免ANR

ANR的关键

是处理超时,所以应该避免在UI线程,BroadcastReceiver 还有service主线程中,处理复杂的逻辑和计算

而交给work thread操作。

1)避免在activity里面做耗时操作,oncreate & onresume

2)避免在onReceiver里面做过多操作

3)避免在Intent Receiver里启动一个Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。

4)尽量使用handler来处理UI thread & workthread的交互。

如何解决ANR

首先定位ANR发生的log:

04-01 13:12:11.572 I/InputDispatcher( 220): Application is not responding:Window{2b263310com.android.email/com.android.email.activity.SplitScreenActivitypaused=false}.  5009.8ms since event, 5009.5ms since waitstartedCPUusage from 4361ms to 699ms ago ----CPU在ANR发生前的使用情况04-0113:12:15.872 E/ActivityManager(  220): 100%TOTAL: 4.8% user + 7.6% kernel + 87% iowait04-0113:12:15.872 E/ActivityManager(  220): CPUusage from 3697ms to 4223ms later:-- ANR后CPU的使用量

从log可以看出,cpu在做大量的io操作。

所以可以查看io操作的地方。

当然,也有可能cpu占用不高,那就是 主线程被block住了。

6.Android 线程间通信有哪几种方式

1)共享变量(内存)

2)管道

3)handle机制

runOnUiThread(Runnable)

view.post(Runnable)

7.Devik 进程,linux 进程,线程的区别

Dalvik进程。

每一个android app都会独立占用一个dvm虚拟机,运行在linux系统中。

所以dalvik进程和linux进程是可以理解为一个概念。

你真正了解Java虚拟机吗—高级开发必备《深入了解Java虚拟机》

8.描述一下 android 的系统架构

从小到上就是:

linux kernel,lib dalvik vm ,application framework, app

9.android 应用对内存是如何限制的?我们应该如何合理使用内存?

activitymanager.getMemoryClass() 获取内存限制。

关于合理使用内存,其实就是避免OOM & 内存泄露中已经说明。

10. 简述 android 应用程序结构是哪些

1)main code

2) unit test

3)mianifest

4)res->drawable,drawable-xxhdpi,layout,value,mipmap

mipmap 是一种很早就有的技术了,翻译过来就是纹理映射技术.

google建议只把启动图片放入。

5)lib

6)color

11.请解释下 Android 程序运行时权限与文件系统权限的区别

文件的系统权限是由linux系统规定的,只读,读写等。

运行时权限,是对于某个系统上的app的访问权限,允许,拒绝,询问。该功能可以防止非法的程序访问敏感的信息。

12.Framework 工作方式及原理,Activity 是如何生成一个 view 的,机制是什么

Framework是android 系统对 linux kernel,lib库等封装,提供WMS,AMS,bind机制,handler-message机制等方式,供app使用。

简单来说framework就是提供app生存的环境。

1)Activity在attch方法的时候,会创建一个phonewindow(window的子类)

2)onCreate中的setContentView方法,会创建DecorView

3)DecorView 的addview方法,会把layout中的布局加载进来。

13.多线程间通信和多进程之间通信有什么不同,分别怎么实现

线程间的通信可以参考第6点。

进程间的通信:bind机制(IPC->AIDL),linux级共享内存,boradcast,

Activity 之间,activity & serview之间的通信,无论他们是否在一个进程内。

14.Android 屏幕适配

屏幕适配的方式:xxxdpi, wrap_content,match_parent. 获取屏幕大小,做处理。

dp来适配屏幕,sp来确定字体大小

drawable-xxdpi, values-1280*1920等 这些就是资源的适配。

wrap_content,match_parent, 这些是view的自适应

weight,这是权重的适配。

Android屏幕适配框架-(今日头条终极适配方案)

15.什么是 AIDL 以及如何使用

Android Interface Definition Language

AIDL是使用bind机制来工作。

参数:

java原生参数

String

parcelable

list & map 元素 需要支持AIDL

16.Handler 机制

参考:android 进程/线程管理(一)——消息机制的框架 这个系类。

17.事件分发机制

android 事件分发机制

带你一起探究Android事件分发机制, 让面试提问不在畏惧!

Android触摸事件分发机制完全解析《一》

18.子线程发消息到主线程进行更新 UI,除了 handler 和 AsyncTask,还有什么

EventBus,广播,view.post, runinUiThread

但是无论各种花样,本质上就2种:handler机制 + 广播

你真正了解UI线程更新的几种方式吗,面试必备之深度揭秘

19.子线程中能不能 new handler?为什么

必须可以。子线程 可以new 一个mainHandler,然后发送消息到UI Thread。

带你一步一步深入Handler源码,拿下面试官不在话下

Handler消息机制完全解析(三)—Handler解析

Handler消息机制完全解析(二)MessageQueue的队列管理

Handler消息机制完全解析(一)Message中obtain()与recycle()的来龙去脉

20.Android 中的动画有哪几类,它们的特点和区别是什么

视图动画,或者说补间动画。只是视觉上的一个效果,实际view属性没有变化,性能好,但是支持方式少。

属性动画,通过变化属性来达到动画的效果,性能略差,支持点击等事件。android 3.0

帧动画,通过drawable一帧帧画出来。

Gif动画,原理同上,canvas画出来。

具体可参考:https://i.cnblogs.com/posts?categoryid=672052

21.如何修改 Activity 进入和退出动画

overridePendingTransition

22.SurfaceView & View 的区别

view的更新必须在UI thread中进行

surfaceview会单独有一个线程做ui的更新。

surfaceview 支持open GL绘制。

二项目框架的使用

23.开发中都使用过哪些框架、平台

I.EventBus 事件分发机制,由handler实现,线程间通信

II.xUtils->DbUtils,ViewUtils,HttpUtils,BitmapUtils

III.百度地图

IV.volley

V.fastjson

VI.picciso

VII.友盟

VIII.zxing

IX.Gson

24.使用过那些自定义View

pull2RefreshListView

25.自定义控件:绘制圆环的实现过程

public class CycleView extends View {   Paint mPaint = new Paint(); public CycleView(Context context) { this(context, null);   } public CycleView(Context context, AttributeSet attrs) { super(context, attrs);       initView();   } private void initView() {       mPaint.setAntiAlias(true);       mPaint.setStyle(Paint.Style.STROKE);       mPaint.setStrokeWidth(20);   }   @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas);       canvas.drawCircle(100,100,50,mPaint);   }}

关键是canvas.drawCycle & paint.setsytle(stoken)

26.自定义控件:摩天轮的实现过程

image

参考链接

https://github.com/danylovolokh/LondonEyeLayoutManager

27.GridLayout的使用

参考链接

https://blog.csdn.net/k316378085/article/details/52316633

28.流式布局的实现过程

参考链接

https://blog.csdn.net/sz237812861/article/details/78383484?locationNum=4&fps=1

29.第三方登陆

参考链接

https://blog.csdn.net/alpha58/article/details/75210753

30.第三方支付

参考链接

https://blog.csdn.net/androidstarjack/article/details/72669394

【干货】微信支付,银联支付,支付宝支付——三大支付总结你get到了吗

31.进程保活

参考链接

2018年Android的保活方案效果统计

阅读更多

火车上编码是一种怎样的体验?

android高级页面效果集锦

做后台是选择Java 、Go ,还是 PHP?

美团面试题:Java-线程池 ThreadPool 专题详解

(Android)面试题级答案(精选版)

相信自己,没有做不到的,只有想不到的

在这里获得的不仅仅是技术!欢迎交流学习

image

相关文章
|
12天前
|
Android开发
Android面试题之Activity的启动模式和flag
Android Activity的四种启动模式:standard(默认,每次启动创建新实例),singleTop(栈顶复用,不走onCreate,调用onNewIntent),singleTask(栈内唯一,清除上方Activity)和singleInstance(单独栈内唯一)。启动模式在AndroidManifest.xml中配置,Intent Flags如FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_SINGLE_TOP可实现类似功能。了解这些对于处理Activity栈管理至关重要。
14 0
|
6天前
|
安全 Android开发 Kotlin
Android经典面试题之Kotlin延迟初始化的by lazy和lateinit有什么区别?
**Kotlin中的`by lazy`和`lateinit`都是延迟初始化技术。`by lazy`用于只读属性,线程安全,首次访问时初始化;`lateinit`用于可变属性,需手动初始化,非线程安全。`by lazy`支持线程安全模式选择,而`lateinit`适用于构造函数后初始化。选择依赖于属性特性和使用场景。**
19 5
Android经典面试题之Kotlin延迟初始化的by lazy和lateinit有什么区别?
|
3天前
|
SQL 安全 Java
Android经典面试题之Kotlin中object关键字实现的是什么类型的单例模式?原理是什么?怎么实现双重检验锁单例模式?
Kotlin 单例模式概览 在 Kotlin 中,`object` 关键字轻松实现单例,提供线程安全的“饿汉式”单例。例如: 要延迟初始化,可使用 `companion object` 和 `lazy` 委托: 对于参数化的线程安全单例,结合 `@Volatile` 和 `synchronized`
14 6
|
5天前
|
XML Android开发 数据格式
Android面试题之DialogFragment中隐藏导航栏
在Android中展示全屏`DialogFragment`并隐藏状态栏和导航栏,可通过设置系统UI标志实现。 记得在布局文件中添加内容,并使用`show()`方法显示`DialogFragment`。
17 2
|
9天前
|
Android开发 Kotlin
Android面试题之kotlin中怎么限制一个函数参数的取值范围和取值类型等
在Kotlin中,限制函数参数可通过类型系统、泛型、条件检查、数据类、密封类和注解实现。例如,使用枚举限制参数为特定值,泛型约束确保参数为Number子类,条件检查如`require`确保参数在特定范围内,数据类封装可添加验证,密封类限制为一组预定义值,注解结合第三方库如Bean Validation进行校验。
22 6
|
9天前
|
Android开发
Android面试题之自定义View注意事项
在Android开发中,自定义View主要分为四类:直接继承View重写onDraw,继承ViewGroup创建布局,扩展特定View如TextView,以及继承特定ViewGroup。实现时需注意:支持wrap_content通过onMeasure处理,支持padding需在onDraw或onMeasure/onLayout中处理。避免在View中使用Handler,使用post系列方法代替。记得在onDetachedFromWindow时停止线程和动画以防止内存泄漏。处理滑动嵌套时解决滑动冲突,并避免在onDraw中大量创建临时对象。
16 4
|
7天前
|
Android开发
Android面试题之View的invalidate方法和postInvalidate方法有什么区别
本文探讨了Android自定义View中`invalidate()`和`postInvalidate()`的区别。`invalidate()`在UI线程中刷新View,而`postInvalidate()`用于非UI线程,通过消息机制切换到UI线程执行`invalidate()`。源码分析显示,`postInvalidate()`最终调用`ViewRootImpl`的`dispatchInvalidateDelayed`,通过Handler发送消息到UI线程执行刷新。
15 1
|
10天前
|
Android开发 Kotlin
Android面试题之 Kotlin中退出迭代器的方式有哪些
在Android和Kotlin中,遍历集合时可使用迭代器结合`break`提前终止循环。例如,使用`while`和迭代器,或用`forEach`配合`return@forEach`来中断遍历。若需退出外层函数,可定义自定义标签。在遍历并删除元素时,这些技巧尤其有用。
15 3
|
4天前
|
Android开发 Kotlin
Android经典面试题之Kotlin中Lambda表达式有哪些用法
Kotlin的Lambda表达式是匿名函数的简洁形式,常用于集合操作和高阶函数。基本语法是`{参数 -> 表达式}`。例如,`{a, b -> a + b}`是一个加法lambda。它们可在`map`、`filter`等函数中使用,也可作为参数传递。单参数时可使用`it`关键字,如`list.map { it * 2 }`。类型推断简化了类型声明。
8 0
|
4天前
|
Android开发 Kotlin
Android经典面试题之Kotlin中Lambda表达式和匿名函数的区别
**Kotlin中的匿名函数与Lambda表达式概述:** 匿名函数(`fun`关键字,明确返回类型,支持非局部返回)适合复杂逻辑,而Lambda(简洁语法,类型推断)常用于内联操作和高阶函数参数。两者在语法、返回类型和使用场景上有所区别,但都提供无名函数的能力。
7 0