文章目录
-
- 什么是ANR,如何避免
-
- 主线程中的Looper.loop()一直无限循环为什么不会造成ANR/li>
- ListView原理与优化
- ContentProvider实现原理
- 如何使用ContentProvider进行批量操作/li>
- 为什么要使用通过`ContentResolver`类从而与`ContentProvider`类进行交互,而不直接访问`ContentProvider`类/li>
- 介绍Binder机制
- 如何自定义View,如果要实现一个转盘圆形的View,需要重写View中的哪些方法/li>
- Android事件分发机制
- 如何加载大图片
- 布局文件中,layout_gravity 和 gravity 以及 weight的作用。
- ListView里的ViewType机制
- TextView怎么改变局部颜色
- Activity A 跳转到 Activity B,生命周期的执行过程是啥/li>
- Android中Handler声明非静态对象会发出警告,为什么非得是静态的/li>
- ListView使用过程中是否可以调用addView
- 属性动画(Property Animation)和补间动画(Tween Animation)的区别,为什么在3.0之后引入属性动画
- 有没有使用过EventBus或者Otto框架,主要用来解决什么问题,内部原理
- Android里的LRU(Least Recently Used 最近最少使用)算法原理
- Service onBindService 和startService 启动的区别
- invalidate()和postInvalidate() 的区别
- 导入外部数据库
- Parcelable和Serializable区别
- 在两个 Activity 之间传递对象还需要注意什么呢/li>
- Android里跨进程传递数据的几种方案
- 匿名共享内存,使用场景
- Application类的作用
- 广播注册后不解除注册会有什么问题内存泄露)
- 属性动画(Property Animation)和补间动画(Tween Animation)的区别
- BrocastReceive里面可不可以执行耗时操作/li>
- Android优化工具
-
- TraceView
- Systrace
- Android动态权限/li>
- ViewPager如何判断左右滑动/li>
- ListView与RecyclerView
- SpannableString
- APK安装过程
- 描述一下Android手机启动过程和App启动过程/li>
-
- Android手机启动过程
- App启动过程
- Include、Merge、ViewStub的作用
- Asset目录与res目录的区别
- System.gc && Runtime.gc
- Application 在多进程下会多次调用 onCreate() 么/li>
- Theme && Style
- SQLiteOpenHelper.onCreate() 调用时机/li>
- Removecallback 失效/li>
- Toast 如果会短时间内频繁显示怎么优化/li>
- Notification 如何优化/li>
- 应用怎么判断自己是处于前台还是后台/li>
- FragmentPagerAdapter 和 FragmentStateAdapter 的区别/li>
- Bitmap的本质/li>
- SurfaceView && View && GLSurfaceView
- 请简述一下你对fragment的理解/li>
- 请简述一下Fragment的生命周期/li>
-
- LayoutInflater,LayoutInflater.inflate()这两个是什么意思/li>
- Android的多渠道打包你了解吗
- 如何对APK瘦身/li>
- Android当前应用跳转到三方应用
- JVM、ART、Dalvik的区别和联系
- Android中的classLoader相比java中的classLoader有什么区别/li>
- Socket和LocalSocket
- HttpClient和URLConnection的区别,怎么使用https
- 设计一个 络请求框架(可以参考Volley框架)
- 络图片加载框架(可以参考BitmapFun)
- 字节跳动Android岗面试题
-
- java的classloader工作原理
- 开发过程中常见的内存泄漏都有哪些
- 关于JVM内存管理的一些建议
- LeakCanary的工作原理,java gc是如何回收对象的,可以作为gc根节点的对象有哪些/li>
-
- LeakCanary原理
- java gc是如何回收对象的
- 可以作为gc根节点的对象有哪些
- 既然有GC机制,为什么还会有内存泄露的情
- jvm的内存模型是什么样的何理解java的虚函数表/li>
- 如何从一百万个数里面找到最小的一百个数,考虑算法的时间复杂度和空间复杂度。
- 安卓的app加固如何做。
- mvp和mvc的主要区别是什么什么mvp要比mvc好。
- 安卓的混淆原理是什么/li>
- 如何设计一个安卓的画图库,做到对扩展开放,对修改封闭,同时又保持独立性。
- 络优化的方案
- APP的性能优化经验
-
- 布局优化
- 图片的优化
- 其他优化
- 死锁的概念,怎么避免死锁
- App启动崩溃异常捕捉
- new Message和obtainMessage的区别
- ReentrantLock 、synchronized和volatile(n面)
- 用到的一些开源框架,介绍一个看过源码的,内部实现过程。
- 消息机制实现
- ReentrantLock的内部实现
- 断点续传的实现&设计一个下载器
- TreeMap具体实现
- Android的多点触控如何传递
- onTouchEvent()、onTouch()、onClick()、onLongClick()的先后顺序
- 前台切换到后台,然后再回到前台,Activity生命周期回调方法。弹出Dialog,生命值周期回调方法。
- 企业级产品中apk的大小至关重要,请提出不少于5个方案,如何缩减apk包大小
- SDK设计
- 简述Activity、Window、WindowManager、WindowManagerImpl、View、ViewRootImpl的作用和相互之间的关系。
- APP路由设计
- 列表卡顿怎么优化先卡顿怎么量化;其次怎么发现造成卡顿的原因;针对可能发现的问题,又如何解决设计一套方案。
- 插件化 组件化 热修复
- 为什么android中方法数最多只能有64k=65532个/li>
- 接口和抽象类的区别
- 怎样做系统调度。
- 简述Android的View绘制流程,Android的wrap_content是如何计算的。
- 数组实现队列。
- HashMap
- singleTask启动模式
- 集合的接口和具体实现类,介绍
- synchronized与ReentrantLock
- 重要:手写生产者/消费者模式、单例模式
- 逻辑地址与物理地址,为什么使用逻辑地址
- 一个无序,不重复数组,输出N个元素,使得N个元素的和相加为M,给出时间复杂度、空间复杂度。手写算法
- Android进程分类
- Activity的启动模式
-
- 有了解过注解么了解过,注释是给人看的,注解给机器看的,override,压制警告之类的)
- 自定义注解@interface) 具体的实现原理(不知道) 源代码阶段还是编译时还是运行时(我说编译时,好像不对
- 消息机制实现
- ReentrantLock的内部实现
- 二叉树,给出根节点和目标节点,找出从根节点到目标节点的路径。手写算法
- 断点续传的实现
- 逻辑地址与物理地址,为什么使用逻辑地址
- 前台切换到后台,然后再回到前台,Activity生命周期回调方法。弹出Dialog,生命值周期回调方法。
- AIDL的基本流程(如何实现AIDL),不用AIDL是否可以实现进程间通讯,用什么,如何实现
- 19年面试真题
-
-
- Thread、Process的区别(字节跳动-抖音-一面)
- singleThreadpool什么场景下使用,只有一个线程为什么不直接使用new Thread()(字节跳动-抖音-一面)
- TCP三次握手、四次挥手(字节跳动-抖音-一面、二面)
-
- 三次握手
- 四次挥手
- 计算机 络为什么是三次握手不是两次握手求方式(post、get)是放在哪个部分发送出去的(考察http协议的格式)(字节跳动-抖音-一面)/li>
-
- HTTP协议的格式
-
- HTTP请求
- HTTP响应
- 【算法】二叉树中序遍历(字节跳动-抖音-一面)
- 【算法】判断平衡二叉树(字节跳动-抖音-二面)
- Px、dp、sp的区别(字节跳动-抖音-二面)
-
- **DP**
- dip:
- px:
- sp:
- 为啥 标准dpi = 160
- java中有哪几种变量修饰符,有什么区别,protected是否是包级可见的(字节跳动-抖音-二面)
- synchronized对普通方法、静态方法加锁有什么区别(字节跳动-抖音-二面)
- Activity启动模式的解释(字节跳动-抖音-二面)
- java中保持线程同步的方式(考察锁)(字节跳动-抖音-二面)
- java的四种引用(字节跳动-抖音-二面)
- kotlin和java比的异同点(字节跳动-抖音-二面)
- okHttp源码理解(字节跳动-抖音-二面,腾讯-微信-一面)
- 数据库索引、事物的概念(字节跳动-抖音-三面Leader面)
- 关系型数据库中的主键是什么(字节跳动-抖音-三面Leader面)
- SQL语句的基本结构(字节跳动-抖音-三面Leader面)
- java里面有没有类似c 的析构函数的东西(字节跳动-抖音-三面Leader面)
- c 中参数传递有哪几种方式ava呢字节跳动-抖音-三面Leader面)
- c 和java有什么区别字节跳动-抖音-三面Leader面)
- Android中除了线程池还有哪些多线程的实现方式字节跳动-抖音-三面Leader面)
- AsyncTask是否可以异步什么没有看过AsyncTask的源码字节跳动-抖音-三面Leader面)
- 介绍一下http协议(字节跳动-抖音-三面Leader面)
- http各个状态码的意义(字节跳动-抖音-三面Leader面)
- 计算机 络中的重定向是什么(字节跳动-抖音-三面Leader面)
- 【算法】DFS考察
- android中如何计算当前view的子view的数量字节跳动-抖音-四面)
- okhttp中连接池的最大数量,连接池的实现原理(腾讯-微信-一面)
- 有两个View:view1和view2,view2在view1上面且比view1小,如何判断点击view1之内的屏幕是应该由view1处理事件还是由view2处理(腾讯-微信-一面)
- NDK是否可以加载任意目录下的so文件,so文件有几种加载方式(腾讯-微信-一面)
- ndk加载so时如何考虑32位和64位的不同,如何考虑不同的arm平台(腾讯-微信-一面)
- 自定义view的方法,为什么在ondraw中绘制即可产生相应效果,什么时候使用自定义view什么时候使用原生view(腾讯-微信-一面)
- sqlite是不是线程同步的(腾讯-微信-一面)
- 有没有对比过flutter和其他跨平台方案有什么异同点(腾讯-微信-一面)
- Android中如何自己实现跨线程的通信(蚂蚁金服-支付宝-一面)
- Android中的synchronized和reentrantLock有什么区别(蚂蚁金服-支付宝-一面)
- 一个线程中可以有几个handler个Looper个messageQueue蚂蚁金服-支付宝-一面)
- Handler机制介绍(蚂蚁金服-支付宝-一面)
- AsyncTask原理介绍,其实串行的还是并行的何进行并行操作蚂蚁金服-支付宝-一面)
- 数据库如何短时间高效批量插入数据蚂蚁金服-支付宝-一面)
- java静态方法是否可以被重写(蚂蚁金服-支付宝-一面)
- 静态内部类和非静态内部类的区别(蚂蚁金服-支付宝-一面)
- 使用fragment有什么好处蚂蚁金服-支付宝-一面)
- 有没有使用过嵌套Fragment蚂蚁金服-支付宝-一面)
- handler.postDelayed中的run是工作在主线程还是子线程(蚂蚁金服-支付宝-一面)
- Android中的内存管理(蚂蚁金服-支付宝-一面)
-
- 分配机制
- 回收机制
- 为什么App要符合内存管理机制/li>
- 如何编写符合Android内存管理机制的App/li>
- 开发时,应该如何注意App的内存管理呢/li>
- ArrayList和LinkedList的区别自的使用场景蚂蚁金服-支付宝-一面)
- Java gc机制介绍(蚂蚁金服-支付宝-一面)
- 如何对APK瘦身腾讯-音视频实验室-一面)
- java和c/c 在编译运行上有什么异同点腾讯-音视频实验室-一面)
- String类为什么具有不可变性如何实现不可变性的/li>
- String是object的子类,那么String[]是不是Object的子类什么/li>
- 自定义View的流程/li>
- 屏幕上有view1 view2 view3,其绘制流程量传参的形式是什么/li>
- 如何实现一个圆,其下四分之一加上蒙层的效果path)
- 在AThread中调用BThread.sleep(),休眠的是哪个线程/li>
- java中类的某些成员变量没有被用到,是否可以随意删除/li>
- NDK中的局部变量如果不手动释放一定没问题吗/li>
- 链表的反转
- 20亿个qq 码,如何判断其中是否存在某一个/li>
- ndk中的external c有什么用/li>
- ndk中的attachCurrentThread有什么用/li>
- invalidate()和postInvalidate() 以及requestLayout()的区别
-
什么是ANR,如何避免
ANR的全称是,即我们俗称的应用无响应。
要想知道如何避免ANR,就有必要了解哪些情况下会导致ANR
发生ANR的原因:
- 当前的事件没有机会得到处理(即主线程正在处理前一个事件,没有及时的完成或者looper被某种原因阻塞住了)
- 当前的事件正在处理,但没有及时完成
常见的以下几种情况都会导致ANR:
- 主线程中被IO操作(从Android4.0以后不允许 络IO操作在主线程中)
- 主线程中存在耗时操作
- 主线程中存在错误操作,比如Thread.wait或者Thread.sleep
Android系统会监控程序的响应情况,一旦出现以下三种情况就会弹出ANR对话框:
- View的点击事件或者触摸事件在5s内无法得到响应。
- BroadcastReceiver的onReceive()函数运行在主线程中,在10s内无法完成处理。
- Service的各个生命周期函数在20s内无法完成处理。
那么对应的避免ANR的基本思路就是避免IO操作在主线程中,避免在主线程中进行耗时操作,避免主线程中的错误操作等,具体的方法有如下几种:
- 使用AsyncTask处理耗时IO操作
- 使用Handler处理线程处理结果,而不是使用Thread.sleep或者Thread.wait来堵塞线程
- Activity的onCreat和onResume方法中尽量避免进行耗时操作
- BroadcastReceiver中的onReceive中也应该避免耗时操作,建议使用intentService处理
主线程中的Looper.loop()一直无限循环为什么不会造成ANR/h3>
ActivityThread.java 是主线程入口的类,这里你可以看到写Java程序中司空见惯的main方法,而main方法正是整个Java程序的入口:
Looper.loop()方法:
显而易见的,如果main方法中没有looper进行循环,那么主线程一运行完毕就会退出。
所以ActivityThread的main方法主要就是做消息循环,一旦退出消息循环,那么你的应用也就退出了。
因为Android 的是由事件驱动的,looper.loop() 不断地接收事件、处理事件,每一个点击触摸或者说Activity的生命周期都是运行在 Looper.loop() 的控制之下,如果它停止了,应用也就停止了。只能是某一个消息或者说对消息的处理阻塞了 Looper.loop(),而不是 Looper.loop() 阻塞它。
也就说我们的代码其实就是在这个循环里面去执行的,当然不会阻塞了。
handleMessage方法部分源码:
public void handleMessage(Message msg) {if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " codeToString(msg.what));switch (msg.what) { case LAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityStart"); final ActivityClientRecord r = (ActivityClientRecord) msg.obj; r.packageInfo = getPackageInfoNoCheck(r.activityInfo.applicationInfo, r.compatInfo); handleLaunchActivity(r, null); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case RELAUNCH_ACTIVITY: { Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityRestart"); ActivityClientRecord r = (ActivityClientRecord) msg.obj; handleRelaunchActivity(r); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); } break; case PAUSE_ACTIVITY: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); handlePauseActivity((IBinder) msg.obj, false, (msg.arg1 & 1) != 0, msg.arg2, (msg.arg1 & 2) != 0); maybeSnapshot(); Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); break; case PAUSE_ACTIVITY_FINISHING: Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "activityPause"); handlePauseActivity((IBinder) msg.obj, true, (msg.arg1 & 1) != 0, msg.arg2, (msg.arg1 & 1) != 0); Trace声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!