Android第二次面试总结

前言:

经历了一次非常全面的面试,三个小时笔试加三轮技术面试,让我深刻的体会到了自己那些东西会哪些东西不会,能想起来的就这些问题了,最近正在逐一攻破,也算收获匪浅,又学到了很多东西,同时也证实自己还有很多知识点不会,写篇博客记录下,持续更新直到解答完每一道题…
1. Activity生命周期
onCreate、onStart、onResume、onPause、onStop、onDestroy、onRestart
2. 释放资源在哪个方法,初始化(恢复数据)在哪个方法
onDestory中释放图片等资源
onResume中初始化(如打开相机,开启动画等)
3. 广播的使用,生命周期
新建一个类继承自BroadcastReceiver
BroadcastReceiver只有一个onReceive回调方法
生命周期从onReceive接受参数开始执行开始 到 return返回结果后结束
使用方式有两种 静态注册 和 动态注册
1.静态注册
在清单文件Androidmanifest.xml中配置

<receiver android:name="包名.MyReceiver">
<intent-filter>
                <action android:name="com.test"/>
       </intent-filter>
</receiver>

静态注册无法销毁,及时应用程序已经关闭还是可以继续接受广播,比较浪费性能
2.动态注册
在代码中动态注册Receiver
MyReceiver myReceiver = new MyReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(“com.test”);
registerReceiver( myReceiver, intentFilter);
调用unregisterReceiver(myReceiver)解除,或者程序关闭后自动销毁
4. 静态注册和动态注册广播的区别
静态注册无法销毁,及时应用程序已经关闭还是可以继续接受广播,比较浪费性能。
动态注册可以调用unregisterReceiver(myReceiver)解除,或者程序关闭后自动销毁。
5. 程序的保活,收到一条通知(程序未打开)单击要跳转到一个页面怎么实现
单击的逻辑需要先判断程序是否处在进程列表中,如果存在执行跳转对应页面的逻辑,如果不存在则先启动程序再进行之后的逻辑。
6. service的使用,启动(两种)和关闭,生命周期
参考出处: https://blog.csdn.net/imxiangzi/article/details/76039978
创建service必须现在清单文件中AndroidManifest.xml声明
创建一个类继承自Service 实现onCreate onStartCommand onBind onDestory都属于回调方法且必须在主线程调用
service共有两种启动方式stratService和bindService都是先定义一个Intent作为参数传入
stratService启动:
startService(intent)启动,stopService(intent)停止;
每次启动不会重复调用onCreate,但是会重复调用onStartCommand;
bindService启动:
bindService启动是典型的client-server模式,调用者client,service则是server;
server只有一个,但client可以有多个绑定在一个server上;
可以通过IBinder获取Service实例,client可以灵活调用server的方法;
没有client和service绑定时自行销毁;
client可以通过context调用unBindService解除绑定;
销毁时先执行unBind再执行onDestory
如何保活Service:
1.在startCommand中返回START_STCKY
START_NOT_STICKY:被kill不重新创建
START_STICKY:被kill后尝试重新创建,调用startCommand,但Intent信息会丢失成为
null,适合不需要接受Intent传递参数的Service使用
START_REDELIVER_INTENT:和START_STICKY方式类似,但是保留最后一次传入的
Intent参数,Intent一定不会为空
2.提高优先级
在AndroidManifest.xml中设置androidLpriority=“1000” 1000为最高优先级,数值越小优先
级越低,同时也适用于广播。
3.提升service进程的优先级
4.在onDestory中重启service
5.系统广播监听service
6.apk安装到system/app下变为系统级应用
7. fragment的生命周期以及理解
onAttach、onCreate、onCreatView、onActivityCreated、onStart、onResume、onPause、onStop、onDestoryView、onDestory、onDetach
优势:模块化、可重用、可适配
核心类:
Fragment:基类,所有Fragment都需要继承
FragmentManager:管理维护Fragment,抽象类
FragmentTransaction:Fragment添加删除都需要通过提交事务来处理
Activity中添加Fragment的两种方式:
静态添加:在xml中添加标签。缺点:运行时不能删除。
动态添加:在xml中添加标签,运行时添加。注意!这并不是一个view。
生命周期详解:
onAttach():Fragment和Activity相关联时调用。可以通过该方法获取 Activity引用,还可以
通过getArguments()获取参数。
onCreate():Fragment被创建时调用。
onCreateView():创建Fragment的布局。
onActivityCreated():当Activity完成onCreate()时调用。
onStart():当Fragment可见时调用。
onResume():当Fragment可见且可交互时调用。
onPause():当Fragment不可交互但可见时调用。
onStop():当Fragment不可见时调用。
onDestroyView():当Fragment的UI从视图结构中移除时调用。
onDestroy():销毁Fragment时调用。
onDetach():当Fragment和Activity解除关联时调用。
8. 多线程的通信方式,多进程的通信方式
线程通信:Handler、runOnUiThread、View.post(Runnable r)、AsyncTask
进程通信:Bundle/Intent传递数据、ContentProvider
9. bundle可以传递那些数据类型
基本数据类型、Parcelable类型对象、Serializable类型对象
特别注意:Intent和bundle都无法存储Map<K,V>和List<Map<K,V>>类型,这些类型可以先定义一个bean,存储到bean的字段中,以对象的类型传输。
一般情况下,Activity中传值用Intent,Fragment中传值用Bundle
10. int和integer的区别,String、StringBuffer 、StringBuilder 的区别
int是基本数据类型,integer是int的包装类
int可以直接使用,integer必须实例化
int默认值为0,integer默认值为null
int直接存储数值,integer在new的时候其实是一个对象的引用
两个integer是不能直接比较的,如果值在-128-127这个范围内返回的是true否则返回false
String:每次对string操作都会生成新的对象开辟堆内存,效率低下浪费有限的内存
StringBuilder:每次操作不会产生新的对象,但是线程不安全,效率高于StringBuffer
StringBuffer:每次操作也不会产生新的对象,并且线程安全。
String适用与少量字符串操作
StringBuilder适用单线程下在字符缓冲区下进行大量操作的情况
StringBuffer使用多线程下在字符缓冲区进行大量操作的情况
11. ANR情况怎么处理
ANR (Application Not Responding)应用程序无响应
原因:
activity超过5秒无法响应用户输入事件
BroadcastReceiver执行超过10秒
Service执行超过20秒
CPU负荷
内存不足
避免:
耗时的io操作放在子线程(如:网络请求,访问数据库)
增大vm内存,内存优化
12. listview的item有edittext会出现数据错乱的问题怎么处理
item复用导致数据(或布局)错乱:
调用viewHolder.setIsRecyclable(false)禁止复用(性能会降低很多很多)
给bean加一个字段去判断(如多选框加一个是否选中的字段,写if else去判断)
图片加载错乱可以给控件设置setTag(设置背景前先判断是否是当前Tag)
13. listview和recyclerview的区别,recyclerview的好处
recyelerview封装了viewHolder效率跟高,支持横向,纵向滑动以及瀑布流,支持item增加和删除时的动画,侧滑功能,局部刷新等。
14. recyclerview卡顿处理,布局错乱问题
卡顿问题:onCreateViewHolder和onBindViewHolder对时间特别敏感,尽量避免里面有耗时操作(如:图片解码、加载等)
卡顿处理:
避免耗时操作,或采用第三方框架(优化好的)去加载图片等
尽量减少GPU过度绘制区域(手机开发者选项 -->调试GPU过度绘制)
尽量避免滑动时耗时操作(停止滑动再开始加载图片),添加addScrollLisenter实现里面的
onScrollStateChanged方法
item复用导致数据(或布局)错乱:
调用viewHolder.setIsRecyclable(false)禁止复用(性能会降低很多很多)
给bean加一个字段去判断(如多选框加一个是否选中的字段,写if else去判断)
图片加载错乱可以给控件设置setTag(设置背景前先判断是否是当前Tag)
15. recyclerview加载不同item的处理(图片,纯文字,视频等等)
每一种情况都写一个对应的xml布局,并且在adapter类中写出对应的viewholder,根据不同类型判断去加载不同的布局。
16. 如何完美的显示的一张UI截给你的图片
首先获取图片展示到控件上的宽度,获取图片的比例,根据宽度以及比例计算出图片的高度,动态的去设置显示图片控件的高度即可完美的展示。
17. 图片加载Glide的使用,常用的方法,怎么显示圆形图片
基础使用:Glide.with(context).load(“图片url”).into(“要显示的控件”);
常见方法:
placeholder(R.mipmap.images) 添加等待图(占位图)
error(R.mipmap.images) 失败后显示的内容
centerCorp() 拉伸填充
fitCenter() 保证图片完整可能不会充满容器
asGif() 显示gif动图
priority(Priority.HIGH) 设置优先级
skipMemoryCache(true) 跳过缓存
diskCacheStrategy() 四种缓存策略
DiskCacheStrategy.NONE 什么都不缓存
DiskCacheStrategy.SOURCE 仅仅只缓存原来的全分辨率的图像
DiskCacheStrategy.RESULT 仅仅缓存最终的图像,即降低分辨率后的(或者是转换后的)
DiskCacheStrategy.ALL 缓存所有版本的图像(默认行为)
使用技巧:
resumeRequests(),pauseRequsets()可以用来在滑动时停止加载,滑动结束后恢复
clear()可以清除所有图片加载请求
圆形圆角展示:
apply(RequestOptions.bitmapTransfrom(new CircleCrop)) 圆形展示
apply(RequsetOptions.bitmapTransfrom(new RoundedCorners(20))) 圆角展示
18. 如何处理scrollview和recyclerview滑动冲突
recyclerview设置不可滑动setNestedScrollingEnabled(false)
recyclerview设置 setHasFixedSize(true)
改用NestedScrollView布局
19. 对自定义view的理解
20. 自定义View怎么实现动画效果
21. android event事件传递机制
22. activity嵌套fragment切换时的生命周期函数执行是怎样的
当activity打开时,对应显示的fragment按顺序调用onAttach,onCreate,onCreateView,onActiviyCreated,onStart,onResume。
切换到哪个fragment也是按顺序执行onAttach,onCreate,onCreateView,onActivityCreated,onStart,onResume。
当activity关闭时,按照加载顺序先调用所有已经加载的fragment的onPause方法,然后调用全部fragmet的onStop方法,最后按照加载顺序先后调用对应fragment的onDestoryView,onDestory,onDetach。
23. activity嵌套fragment时给下面的导航按钮加一个单击图标放大的效果怎么实现
给ui控件增加动画效果(以imageview为例)先设置选中setSelected(true);
放大1.5倍,动画时间500ms
imageview.animate().scaleX(1.5f).scaleY(1.5f).setDuration(500).start();
还原大小的话把1.5改为1则变为原大小
24. tablayout+viewpager+fragment切换时生命周期函数是怎么样的
假设viewpager中有三个fragment按顺序分别是a,b,c
当activity刚打开时,a先执行onAttach,onCreate,b也执行onAttach,onCreate,接着a执行onCreateView,onActivityCreated,onStart,onResume,最后b也开始执行onCreateView,onActivityCreated,onStart,onResume,全程c是任何生命周期方法都不执行的。
当由a滑到b的时候,c开始执行onAttach,onCreate,onCreateView,onActivityCreated,onStart,onResume。
当由b滑到c的时候,a开始执行onPause,onStop,onDestoryView。
当由c滑到b的时候,a开始执行onCreateView,onActivityCreated,onStart,onResume。
当activity关闭时,按照已经加载的fragment的顺序,先调用每个fragment的onPause,然后调用每个fragment的onStop,最后按照栈中的顺序依次调用每个fragment的onDestoryView,onDestory,onDetach
总结:只会预加载相邻的fragment,可以通过setOffscreenPagerLimit(int i)设置预加载页面数量
预加载时调用onAttach,onCreate,onCreateView,onActivityCreated,onStart,onResume
移除时调用onPause,onStop,onDestoryView
25. viewpager+fragment切换到不相邻的时候数据会丢失怎么处理,保存数据最多又可以保存多少
重写onSaveInstanceState方法,在这个方法中保存数据(如用户在输入框输入的文本)bundle.putString(K,V)等等方法。在onCreateView的重载方法中找到有Bundle参数的,通过这个参数获取存储的数据,一定要做是否为null的判断,否则会出错,调用bundle.getString(K)获取存储的数据。
26. retrofit的使用,retrofit和okhttp的区别
retrofit基本使用:
1.新建serviceApi接口类,存放所有请求,用注解的方式标识请求类型以及请求的url
2.初始化retrofit对象,设置基地址(BaseUrl),设置内容转换器(addConverterFactory),初始化(build)
3.创建serviceApi对象(ServiceApi s = retrofit.create(ServiceApi.class))
4.定义请求返回数据接收的Call = s.getData();
5.调用call.enqueue执行请求,回调方法中写逻辑(成功或者失败分别有对应的回调方法)
okhttp基本使用(以post请求为例):
1.实例化okhttp对象,构建Frombody(请求的参数),构建Request
2.创建Call(okhttp包下的Call)Call call = okhttpclient.newCall(requset)
3.call.enqueue开始请求在回调方法callback中(成功或失败)添加逻辑,需要注意这是在子线程中回调,UI操作需要在主线程(如:runOnUiThread)
区别:
retrofit是基于okhttp的封装,面向开发者方便请求,以及数据处理,回调函数方便操控ui,显示数据等。
okhttp偏向于socket的优化
27. retrofit怎么添加请求头
1.写在serviceApi接口类方法的参数中,用(@Header(“K”)String V)每次都需要传入
2.同样采用@Header的方式写在请求类型注解的上面@Header(“K:V”)
3.在初始化retrofit的时候添加,先初始化okhttpclient,初始化的时候调用addInterceptor,传入new Interceptor(){},重写intercept方法,新建Request对象调用addHeader添加请求头,retrofit初始化的时候调用client方法传入okhttpclient即可。
28. 类似qq聊天功能怎么保证发出去的消息服务端一定可以收到不会丢失
29. zxing扫码包横屏问题的处理,以及改成竖屏后无法扫码条形码的问题
该问题已解决,博客中有对应的博文。
30. 自己怎么实现扫码解析功能
31. android本地存储的方式
sharedperferences、sqlite、文件存储、ContentProvider、网络存储(上传下载)
32. sharedpreferences可以存储那些数据类型,风险
sharedpreferences是一个轻量级的存储类,用来存放一些应用配置等,通常以键值对的方式存放在xml文件中,默认路径data/data/shared_prefs/
使用:
1.创建sharedpreferences对象,创建sharedpreferences.editor对象
2.通过editor对象操作数据(put存储数据get读取remove删除clear清空)
3.操作完成后一定要editor.commit提交操作
注意:
fragment中使用时必须在onAttach方法中初始化sharedpreferences否则报空指针
33. sqlite的使用(增删改查),风险
sqlite是一款轻量级的关系型数据库,占用资源少,速度快,几百K的大小,很适合移动设备存储数据。以一个文件的形式存储,默认路径data/data/包名/
基本使用:
1.新建一个工具类继承SQLiteOpenHelper,重写onCreate创建数据库(没有则创建)。
2.新建SQLiteDatabase对象(db),调用工具类的getWritDatabase方法去实例。
3.SQLiteDatabase封装了增删改查的方法直接调用即可,也可以通过执行sql语句的方法去进行操作(execSQL增删改 rawQuery查)。
4.操作大量数据时db.beginTransaction()开启事务去优化执行效率,db.setTransactionSuccessful()设置事务处理成功,db.endTransaction()结束事务。
风险:以单文件形式存储,用户在应用设置中清空存储数据数据会丢失。
34. sqlite那些方法可以修改数据库版本
onUpgrade()
35. Linearlayout和RelativeLayout相比性能上有什么区别
Linearlayout的性能更高,关键在于onMeasure方法,Relativelaoyout会测量两次,如果Linearlayout不使用weight属性则只测量一次(weight对性能有影响)
36. Intent的使用,传递数据都可以传递那些数据,最多传递多少
intent用来在窗体和应用间传值,窗体跳转,打开应用等。
可以传递基本数据类型和Serializable,Parcelable类型的对象。
最大传递数据的总和不能超过1M
有隐式和显式两种
37. 存储大量数据到本地的时候使用哪种方式存储
采用SQLite比较合适,采用事务的方式插入数据速度非常快(10W条字符串只需要5秒左右)
38. Gson和Jackson哪种好用,为什么
39. 一个文件系统,如何打印出一个文件夹下所有的文件(里面可能还有文件夹)
40. MPChart自定图表怎么使用
41. 对mvp模式的理解,mvp和mvc的区别,小项目的话使用哪种架构更合适
42. okgo网络请求框架的使用
43. 视频播放器的使用
44. 类似抖音滑动播放视频,滑动到下一个的时候,上一个视频是什么样的状态
45. recyclerview大量的item滑动到一万个以后,第一个item的状态
46. recyclerview大量item滑动卡顿的处理
47. 屏幕视频问题,刘海屏,全面屏适配问题
48. 今日头条屏幕适配方案的使用(最新的),以及他有什么风险
49. 针对不同的机型(华为小米OPPO等)推送的通知不一定直接收的到,怎么处理确保百分百能收到通知

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值