一、Activity A 启动另一个Activity B 会调用哪些方法?如果B是透明主题的又或则是个DialogActivity呢 ?
Activity A 启动另一个Activity B,回调如下
Activity A 的onPause() → Activity B的onCreate() → onStart() → onResume() → Activity A的onStop();如果B是透明主题的又或则是个DialogActivity时:则不会回调A的onStop
二、说下onSaveInstanceState()方法的作用 ? 何时会被调用?
发生条件:异常情况下,Activity被杀死并重新创建。
1、系统会调用onSaveInstanceState来保存当前Activity的状态,此方法调用在onStop之前;
2、当Activity被重建后,系统会调用onRestoreInstanceState,调用在onStart之后;
三、什么是反射机制?反射机制的应用场景有哪些?
Java 反射机制是在运行状态中,对于任意一个类,都能够知道这个类中的所有属性和方法,对于任意一个对象,都能够调用它的任意一个方法和属性;
应用场景:
1. 逆向代码,例如反编译
2. 与注解相结合的框架,如 Retrofit
3. 单纯的反射机制应用框架,例如 EventBus(事件总线)
4. 动态生成类框架 例如Gson
四、谈一谈Java成员变量,局部变量和静态变量的创建和回收时机?
成员变量:生命周期伴随类对象,类对象回收时回收,存在堆里。
局部变量:方法调用时创建,方法结束时被标记为可回收,存在栈里
静态变量:不回收,在方法区随着类的加载而加载,随着类的消失而消失。
五、扩展:内部类都有哪些?
有四种:静态内部类、非静态内部类、局部内部类、匿名内部类
六、线程池的好处
1、线程池的重用: 线程的创建和销毁的开销是巨大的,而通过线程池的重用大大减少了这些不必要的开销,当然既然少了这么多消费内存的开销,其线程执行速度也是突飞猛进的提升。
2、控制线程池的并发数。并发数:系统同时能处理的请求数量。
七、什么是OOM?
OOM,全称“Out Of Memory”,翻译成中文就是“内存用完了”
八、android 应用对内存是如何限制的?我们应该如何合理使用内存
限制应用内存
为了维持多任务环境的正常运行,Android 会为每个应用的堆大小设置硬性上限。不同设备的确切堆大小上限取决于设备的总体可用 RAM 大小。如果应用在达到堆容量上限后尝试分配更多内存,则可能会收到
OutOfMemoryError
。合理使用内存
1、避免全局变量
2、避免在使用枚举(Enum)
3、使用弱引用
4、使用ArrayMap/SparseArray代替hashmap
5、使用分页加载数据
6、减少bitmap的内存占用
7、图片的内存管理:使用Glide等库来管理图片的加载和内存缓存
8、及时回收资源:例如Cursor、流等,使用后应及时关闭
9、使用LeakCanary检测内存泄漏
九、ANR 是什么?怎样避免和解决 ANR
ANR->Application Not Responding
也就是在规定的时间内,没有响应。
四种类型:
(1)Service Timeout: Service 在特定的时间内无法处理完成
(2)BroadcastQueue Timeout:BroadcastReceiver 在特定时间内无法处理完成
(3)ContentProvider Timeout:内容提供者执行超时
(4)inputDispatching Timeout: 按键或触摸事件在特定时间内无响应为什么会超时:事件没有机会处理 & 事件处理超时
十、怎么避免ANR
ANR的关键是处理超时,所以应该避免在UI线程,BroadcastReceiver 还有service主线程中,处理复杂的逻辑和计算而交给work thread操作。
1)避免在activity里面做耗时操作,oncreate & onresume
2)避免在onReceiver里面做过多操作
3)避免在Intent Receiver里启动一个Activity,因为它会创建一个新的画面,并从当前用户正在运行的程序上抢夺焦点。
4)尽量使用handler来处理UI thread & workthread的交互。
十一、android实现线程间通信的四种常见方式
1、通过Handler机制
2、runOnUiThread方法
3、View.post(Runnable r)
4、AsyncTask
十二、android 的系统架构
Android系统架构分为四层架构,从高到低分别是应用层,应用框架层,系统运行层和Linux内核层。
十三、请解释下 Android 程序运行时权限与文件系统权限的区别
文件的系统权限是由linux系统规定的,只读,读写等。
运行时权限,是对于某个系统上的app的访问权限,允许,拒绝,询问。该功能可以防止非法的程序访问敏感的信息。
十四、Android 中如何捕获未捕获的异常
要捕获未捕获的异常,可以使用try-catch语句块将可能抛出异常的代码包裹起来,然后在catch块中处理异常。
十五、Android 中的动画有哪几类,它们的特点和区别是什么
视图动画,或者说补间动画。只是视觉上的一个效果,实际view属性没有变化,性能好,但是支持方式少。
属性动画,通过变化属性来达到动画的效果,性能略差,支持点击等事件。android 3.0
帧动画,通过drawable一帧帧画出来。
Gif动画,原理同上,canvas画出来。
十六、SurfaceView & View 的区别
view的更新必须在UI thread中进行
surfaceview会单独有一个线程做ui的更新。
surfaceview 支持open GL绘制。
十七、 Android 开发的四大组件分别是
活动(activity):用于表现功能。
服务(service):后台运行服务,不提供界面呈现。
广播接受者(Broadcast Receive):用于接收广播。
内容提供者(Content Provider),支持多个应用中存储和读取数据,相当于数据库。
十八、Android生命周期
onCreate:当Activity第一次被运行时调用此方法,可用于加载布局视图,获取控件命名空间等一些初始化工作。
onRestart:当Activity被重新启动的时候,调用此方法onStart :表示Activity正在被启动,已经从不可见到可见状态(不是指用户可见,指Activity在后台运行,没有出现在前台),但还是无法与用户进行交互。
onResume :表Activity已经变为可见状态了,并且出现在前台工作了,也就是指用户可见了
onPause :表示Activity正在暂停,但Activity依然可见,可以执行一些轻量级操作,但一般不会进行太多操作,因为这样会影响用户体验。
onStop :表示Activity即将暂停,此时Activity工作在后台,已经不可见了,可以与onPause方法一样做一些轻量级操作,但依然不能太耗时。
onDestroy :表示活动即将被销毁。
十九、MVC、MVP、MVVM
MVC(Model View Controller)
通过controller的控制去操作model层的数据,并且返回给view层展示。
缺点:
1.View与Model之间还存在依赖关系,Controller很重很复杂,开发,测试,维护都需要花大量的精力
2.Activity即是View又是Controller,维护起来更难。
3.适合单人开发。
MVP(Model View Presenter)
view层和model层完全隔离和解耦,presenter层充当桥梁。presenter层去操作model层,并且将数据返回给view层,整个过程中view层和model层完全没有联系。
优点:
1、view层和model层完全隔离。
2、activity和fragment不再是controller层,而是纯粹的view层。
缺点:虽然是MVC模式的演变,但Presenter依旧很‘重’很复杂。
MVVM(Model View ViewModel)
view层和viewmodel层是相互绑定的关系,更新viewmodel层的数据的时候,view层会相应的变动ui。同步逻辑是交由Binder做的,Model变更View跟着变更,只需要保证Model的正确性,View就正确。
优点:
1.解决了MVP大量的手动View和Model同步的问题,提供双向绑定机制。提高了代码的可维护性。
2.ViewModle易于单元测试。
二十、说下 Activity的任务栈及四种启动模式、应用场景 ?
任务栈:具有先进后出的特性,只有在任务栈栈顶的activity才可以跟用户进行交互。
standard标准模式:每次启动一个Activity都会重新创建一个新的实例。
singleTop栈顶复用模式:如果新Activity已经位于任务栈的栈顶,那么此Activity不会被重新创建。如果新Activity实例已经存在但不在栈顶,那么Activity依然会被重新创建;singleTask栈内复用模式:只要Activity在一个任务栈中存在,那么多次启动此Activity都不会重新创建实例。如果不存在,就会重新创建一个任务栈,然后把创建好A的实例放到栈中;
singleInstance单实例模式:此模式的Activity只能单独的位于一个任务栈中,且此任务栈中只有唯一一个实例;
二十一、Android Activity 横竖屏切换的生命周期
manifest文件中不配置android:configChanges属性时:
Activity启动时: onCreate,onStart,onResume
屏幕切换的时候:onPause,onSaveInstanceState,onStop,onDestroy,onCreate,onStart,onRestoreInstanceState,onResume
配置android:configChanges属性的时:
android:configChanges=”orientation|screenSize”
调用:onConfigurationChanged
二十二、跨App启动Activity的方式,注意事项
在Android开发中,跨App启动Activity需要使用Intent的特殊标志
FLAG_ACTIVITY_NEW_TASK
以及对应的权限声明。解决方案:
(1)在启动Activity的App中,设置Intent的
FLAG_ACTIVITY_NEW_TASK
标志。(2在被启动的Activity的AndroidManifest.xml中,将
<activity>
标签的android:launchMode
属性设置为"singleTask"
,以确保启动新任务。(3)被启动App的Manifest文件中需要声明相应的权限,以允许其他App启动其组件。
注意事项:
(1)确保被启动App已经安装在设备上。
(2)被启动App需要有一个能够匹配启动Intent的
<intent-filter>
。(3)确保启动Activity的App有权限启动其他App的组件,这通常需要自定义权限并在被启动App中声明。
(4)如果被启动的App和Activity使用了更加严格的安全设置,可能需要额外的签名认证或者密码保护。
二十三、谈一谈Fragment的生命周期?
Fragment从创建到销毁整个生命周期中涉及到的方法依次为:onAttach()→onCreate()→onCreateView()→onActivityCreated()→onStart()→onResume()
→onPause()→onStop()→onDestroyView()→onDestroy()→onDetach(),其中和Activity有不少名称相同作用相似的方法,而不同的方法有:
onAttach():当Fragment和Activity建立关联时调用;
onCreateView():当fragment创建视图调用,在onCreate之后;
onActivityCreated():当与Fragment相关联的Activity完成onCreate()之后调用;
onDestroyView():在Fragment中的布局被移除时调用;
onDetach():当Fragment和Activity解除关联时调用;
二十四、谈谈Activity和Fragment的区别?
相似点:都可包含布局、可有自己的生命周期
不同点:
1、Fragment相比较于Activity多出5个生命周期,在控制操作上更灵活;
2、Fragment可以在XML文件中直接进行写入,也可以在Activity中动态添加;
3、Fragment可以使用show()/hide()或者replace()随时对Fragment进行切换,并且切换的时候不会出现明显的效果,用户体验会好;Activity虽然也可以进行切换,但是Activity之间切换会有明显的翻页或者其他的效果,在小部分内容的切换上给用户的感觉不是很好;4、Activity代表了一个具有用户界面的屏幕。而Fragment是Activity内的一个可重用部件,可以在多个Activity中重复使用,有助于构建灵活且适应不同屏幕尺寸的用户界面
二十五、Fragment中add与replace的区别(Fragment重叠)
1、add不会重新初始化fragment,replace每次都会。所以如果在fragment生命周期内获取获取数据,使用replace会重复获取;
2、添加相同的fragment时,replace不会有任何变化,add会报IllegalStateException异常;
replace先remove掉相同id的所有fragment,然后在add当前的这个fragment,而add是覆盖前一个fragment。所以如果使用add一般会伴随hide()和show(),避免布局重叠;
3、使用add,如果应用放在后台,或以其他方式被系统销毁,再打开时,hide()中引用的fragment会销毁,所以依然会出现布局重叠bug,可以使用replace或使用add时,添加一个tag参数;
二十六、getFragmentManager、getSupportFragmentManager 、getChildFragmentManager之间的区别?
getFragmentManager():所得到的是所在fragment 的父容器的管理器, getChildFragmentManager():所得到的是在fragment 里面子容器的管理器, 如果是fragment嵌套fragment,那么就需要利用getChildFragmentManager();
getSupportFragmentManager() :Android3.0以下则需要调用getSupportFragmentManager() 来间接获取;