每一次去面试就是一次对自我知识的总结和审核,若是你想拿到大厂的offer.成功的经过一面二面三面四面,那么我分享的面试学习路线你能够来参考一下(PDF文档版见以下)那么面试中最常问的小知识点不懂的透彻怕是不行了android
(顺手留下GitHub连接,须要获取相关面试等内容的能够本身去找)
https://github.com/xiangjiana/Android-MSgit
1)Activity: 用户可操做的可视化界面,为用户提供一个完成操做指令的窗口。一个 Activity一般是一个单独的屏幕,Activity经过Intent来进行通讯。Android中会维持一个Activity Stack,当一个新 Activity 建立时,它就会放到栈顶,这个 Activity 就处于运行状态。
2)Service: 服务,运行在手机后台,适合执行不需和用户交互且还需长期运行的任务。
3)ContentProvider: 内容提供者,使一个应用程序的指定数据集提供给其余应用程序,其余应用可经过 ContentResolver
类从该内容提供者中获取或存入数据。它提供了一种跨进程数据共享的方式,当数据被修改后,ContentResolver
接口的 notifyChange
函数通知那些注册监控特定 URI
的 ContentObserver
对象。github
如 果 ContentProvider
和 调 用 者 在 同 一 进 程 中 , ContentProvider
的 方 法(query/insert/update/delete 等)和调用者在同一线程中;若是ContentProvider
和调用者不在同一进程,ContentProvider
方法会运行在它自身进程的一个 Binder 线程中。面试
4)Broadcast Receiver: 广播接收者,运用在应用程序间传输信息,可使用广播接收器来让应用对一个外部事件作出响应。数据库
1)Activity: onCreate()
->onStart()
->onResume()
->onPause()
->onStop()
->onDestory()
onCreate()
:为 Activity 设置布局,此时界面还不可见;onStart()
: Activity 可见但还不能与用户交互,不能得到焦点onRestart()
: 从新启动 Activity 时被回调onResume()
: Activity 可见且可与用户进行交互onPause()
: 当前 Activity 暂停,不可与用户交互,但还可见。在新 Activity 启动前被系统调用保存现有的 Activity 中的持久数据、中止动画等。onStop()
: 当 Activity 被新的 Activity 覆盖不可见时被系统调用onDestory()
: 当 Activity 被系统销毁杀掉或是因为内存不足时调用浏览器
a) onBind 方式绑定的: onCreate
->onBind
->onUnBind
->onDestory
(无论调用 bindService
几回,onCreate
只会调用一次,onStart
不会被调用,创建链接后,service 会一直运行,直到调用unBindService
或是以前调用的 bindService
的 Context 不存在了,系统会自动中止 Service,对应的 onDestory
会被调用)安全
b) startService 启动的: onCreate
->onStartCommand
->onDestory
(start 屡次,onCreate
只会被调用一次,onStart
会调用屡次,该service会在后台运行,直至被调用stopService
或是stopSelf
)网络
c) 又被启动又被绑定的服务,无论如何调用 onCreate()
只被调用一次,startService
调用多少次,onStart
就会被调用多少次,而 unbindService
不会中止服务,必须调用 stopService
或是stopSelf
来中止服务。必须unbindService
和 stopService(stopSelf)
同时都调用了才会中止服务。框架
a) 动态注册: 存活周期是在 Context.registerReceiver
和Context.unregisterReceiver
之间,BroadcastReceiver
每次收到广播都是使用注册传入的对象处理的。异步
b) 静态注册: 进程在的状况下,receiver 会正常收到广播,调用 onReceive
方法;生命周期只存活在 onReceive
函数中,此方法结束BroadcastReceiver
就销毁了。onReceive()
只有十几秒存活时间,在 onReceive()
内操做超过 10S,就会报 ANR
。
进程不存在的状况,广播相应的进程会被拉活,Application.onCreate
会被调用,再调用onReceive
。
应该和应用的生命周期同样,它属于系统应用,应用启动时,它会跟着初始化,应用关闭或被杀,它会跟着结束。
1)经过 Intent 方式传递参数跳转
2)经过广播方式
3)经过接口回调方式
4)借助类的静态变量或全局变量
5)借助 SharedPreference 或是外部存储,如数据库或本地文件
onPause(A)
->onCreate(B)
->onStart(B)
->onResume(B)
->oStop(A)
这时若是按回退键回退到 A onPause(B)
->onRestart(A)
->onStart(A)
->onResume(A)
->oStop(B)
若是在切换到 B 后调用了 A.finish(),则会走到 onDestory(A),这时点回退键会退出应用
onPause(A)
->onCreate(B)
->onStart(B)
->onResume(B)
这时若是回退到 A onPause(B)
->onResume(A)
->oStop(B)
->onDestory(B)
onPause(A)
->oStop(A)
->onRestart(A)
->onStart(A)
->onResume(A)
onSaveInstanceState
->onPause
->onStop
->onDestory
->onCreate
->onStart
->onRestoreInstanceState
->onResume
onSaveInstanceState
->onPause
->onStop
->onDestory
->onCreate
->onStart
->onRestoreInstanceState
->onResume
->onSaveInstanceState
->onPause
->onStop
->onDestory
->onCreate
->onStart
->onRestoreInstanceState
->onResume
android:configChanges="orientation"
横竖屏切换,打印的 log 同样,同 1)AndroidMainfest.xml
中 该 Activity 中的 android:configChanges="orientation|keyboardHidden"
,则只会打印onConfigurationChanged->
onAttach
->onCreate
->onCreateView
->onActivityCreated
->onStart
->onResume
->onPause
->onStop
->onDestoryView
->onDestory
->onDetach
onAttach
->onCreate
->onCreateView
->onActivityCreated
->onStart
->onResume
按下 Power 键: onPause
->onSaveInstanceState
->onStop
点亮屏幕解锁: onStart
->onRestoreInstanceState
->onResume
切换到其余 Fragment: onPause
->onStop
->onDestoryView
切回到该 Fragment: onCreateView
->onActivityCreated
->onStart
->onResume
退出应用: onPause
->onStop
->onDestoryView
->onDestory
->onDetach
AlertDialog
并不会影响Activity的生命周期,按Home键后才会使Activity走onPause
->onStop
,AlertDialog
只是一个组件,并不会使 Activity 进入后台。
前一个 Activity 的 onPause
,后一个 Activity 的 onResume
1) 前 台 切 换 到 后 台 , 会 执 行 onPause
->onStop
再 回 到 前 台 , 会 执 行onRestart
->onStart
->onResume
2) 弹出 Dialog,并不会影响 Activity 生命周期
标准启动模式(默认),每启动一次 Activity,都会建立一个实例,即便从 ActivityAstartActivity
ActivityA
,也会再次建立 A 的实例放于栈顶,当回退时,回到上一个 ActivityA
的实例。
栈顶复用模式,每次启动 Activity,若是待启动的 Activity 位于栈顶,则不会从新 创 建 Activity 的 实 例 , 即 不 会 走 onCreate
->onStart
, 会 直 接 进 入 Activity 的onPause
->onNewIntent
->onResume
方法
单一实例模式,整个手机操做系统里只有一个该 Activity 实例存在,没有
其余 Actvity,后续请求均不会建立新的 Activity。若 task 中存在实例,执行实例的onNewIntent()
。
应用场景: 闹钟、浏览器、电话
栈内复用,启动的 Activity 若是在指定的 taskAffinity
的 task 栈中存在相应的实例,则会把它上面的 Activity 都出栈,直到当前 Activity 实例位于栈顶,执行相应的onNewIntent()
方法。若是指定的 task 不存在,建立指定的taskAffinity
的 task,taskAffinity
的做用,进入指写 taskAffinity
的 task,若是指定的 task 存在,将 task 移到前台,若是指定的 task不存在,建立指定的 taskAffinity
的 task.
应用场景:应用的主页面
Activity 被主动回收时,如按下 Back 键,系统不会保存它的状态,只有被动回收时,虽然这个 Activity 实例已被销毁,但系统在新建一个 Activity 实例时,会带上先前被回收 Activity 的信息。在当前 Activity 被销毁前调用onSaveInstanceState
(onPause
和 onStop
之间保存),从新建立 Activity 后会在 onCreate
后调用onRestoreInstanceState
(onStart
和onResume
之间被调用),它们的参数 Bundle 用来数据保存和读取的。
保存 View 状态有两个前提:View 的子类必须实现了 onSaveInstanceState
; 必需要设定 Id,这个 ID 做为 Bundle 的 Key
onAttach
->onCreate
->onCreateView
->onActivityCreated
->onStart
->onResume
->onPause
->onStop
->onDestoryView
->onDestory
->onDetach
Fragment 在 Activity 中replace onPause(旧)
->onAttach
->onCreate
->onCreateView
->onActivityCreated
->onStart
->onResume
->onStop(旧)
->onDestoryView(旧)
若是添加到 backStack
中,调用 remove()方法 fragment 的方法会走到onDestoryView
,但不会执行 onDetach()
,即 fragment 自己的实例是存在的,成员变量也存在,可是 view 被销毁了。若是新替换的 Fragment 已在 BackStack
中,则不会执行 onAttach
->onCreate
在对应的 FragmentActivity.onSaveInstanceState
方法会调用FragmentController.saveAllState
,其中会对 mActive
中各个 Fragment 的实例状态和 View 状态分别进行保存.当 Activity 在作状态保存和恢复的时候, 在它其中的 fragment 天然也须要作状态保存和恢复.
若是但愿在 Fragment 的onActivityResult
接收数据,就要调用Fragment.startActivityForResult
,而 不 是 Fragment.getActivity().startActivityForResult
。Fragment.startActivityForResult
->FragmentActivitymHost.HostCallbacks.onStartActivityFromFragment
->FragmentActivity.startActivityFromFragment
。 如 果 request=-1 则 直 接 调 用FragmentActivity.startActivityForResult
,它会从新计算 requestCode
,使其大于0xfffff。
ViewPager+FragmentPagerAdapter+List<Fragment>
1) 在相应的 fragment 中编写方法,在须要回调的 fragment 里获取对应的 Fragment 实例,调用相应的方法;
2) 采用接口回调的方式进行数据传递;
a) 在Fragment1中建立一个接口及接口对应的set方法; b) 在Fragment1中调用接口的方法;
c)在 Fragment2 中实现该接口;
3) 利用第三方开源框架 EventBus
1) 经过 bindService
启动服务,能够在 ServiceConnection
的onServiceConnected
中获取到Service 的实例,这样就能够调用 service 的方法,若是 service 想调用 activity 的方法,能够在 service 中定义接口类及相应的 set 方法,在 activity 中实现相应的接口,这样 service 就能够回调接口言法;
2) 经过广播方式
ContentProvider
实现各个应用程序间数据共享,用来提供内容给别的应用操做。如联系人应用中就使用了 ContentProvider
,能够在本身应用中读取和修改联系人信息,不过须要获取相应的权限。它也只是一个中间件,真正的数据源是文件或 SQLite
等。
ContentResolver
内 容 解 析 者 , 用 于 获 取 内 容 提 供 者 提 供 的 数 据 , 通 过ContentResolver.notifyChange(uri)
发出消息
ContentObserver
内容监听者,能够监听数据的改变状态,观察特定 Uri 引发的数据库变化,继而作一些相应的处理,相似于数据库中的触发器,当 ContentObserver
所观察的 Uri 发生变化时,便会触发它。
BroadcastReceiver
是一种全局监听器,用来实现系统中不一样组件之间的通讯。有时候也会用来做为传输少许并且发送频率低的数据,可是若是数据的发送频率比较高或者数量比较大就不建议用广播接收者来接收了,由于这样的效率很很差,由于 BroadcastReceiver
接收数据的开销仍是比较大的。
1 )普通广播: 彻底异步的,能够在同一时刻(逻辑上)被全部接收者接收到,消息传递的效率比较高,而且没法中断广播的传播。
2 ) 有序广播: 发送有序广播后,广播接收者将按预先声明的优先级依次接收 Broadcast。优先级高的优先接收到广播,而在其 onReceiver()
执行过程当中,广播不会传播到下一个接收者,此时当前的广播接收者能够abortBroadcast()
来终止广播继续向下传播,也能够将 intent 中的数据进行修改设置,而后将其传播到下一个广播接收者。sendOrderedBroadcast(intent,null);//
发送有序广播
3 )粘性广播: sendStickyBroadcast()
来发送该类型的广播信息,这种的广播的最大特色是,当粘性广播发送后,最后的一个粘性广播会滞留在操做系统中。若是在粘性广播发送后的一段时间里,若是有新的符合广播的动态注册的广播接收者注册,将会收到这个广播消息,虽然这个广播是在广播接收者注册以前发送的,另一点,对于静态注册的广播接收者来讲,这个等同于普通广播。
在 AndroidManifest
中静态注册的广播接收器,通常咱们在收到该消息后,
须要作一些相应的动做,而这些动做与当前 App 的组件,好比 Activity 或者 Service 的是否运行无关,好比咱们在集成第三方 Push SDK 时,通常都会添加一个静态注册的BroadcastReceiver
来监听 Push 消息,当有 Push 消息过来时,会在后台作一些网络请求或者发送通知等等。
这种主要是在 Activity 或者 Service 中使用 registerReceiver()
动态注册的广
播接收器,由于当咱们收到一些特定的消息,好比网络链接发生变化时,咱们可能须要在当前 Activity 页面给用户一些 UI 上的提示,或者将 Service 中的网络请求任务暂停。因此这种动态注册的广播接收器适合特定组件的特定消息处理。
静态注册的广播接收者就是一个常驻在系统中的全局监听器,也就是说若是你应用中配置了一个静态的 BroadcastReceiver,并且你安装了应用而不管应用是否处于运行状态,广播接收者都是已常常驻在系统中了。
<receiver android:name=".MyBroadcastReceiver"> <intent-filter> <actionandroid:name="com.smilexie.test.intent.mybroadcastreceiver"/> </intent-filter> </receiver>
动态注册的广播接收者只有执行了registerReceiver
(receiver, filter)才会开始监听广播消息,并对广播消息做为相应的处理。
IntentFilter fiter = newIntentFilter("com.smilexie.test.intent.mybroadcastreceiver"); MyBroadcastReceiver receiver = new MyBroadcastReceiver(); registerReceiver(receiver, filter); //撤销广播接受者的动态注册unregisterReceiver(receiver);
1) LocalBroadcastReceiver
仅在本身的应用内发送接收广播,也就是只有本身的应用能收到,数据更加安全。广播只在这个程序里,并且效率更高。只能动态注册,在发送和注册的时候采用 LocalBroadcastManager
的 sendBroadcast
方法和 registerReceiver
方法。
2)全局广播: 发送的广播事件可被其余应用程序获取,也能响应其余应用程序发送的广播事件(能够经过 exported–是否监听其余应用程序发送的广播 在清单文件中控制) 全局广播既能够动态注册,也能够静态注册。
(1)Popupwindow
在显示以前必定要设置宽高,Dialog 无此限制。
(2)Popupwindow
默认不会响应物理键盘的 back,除非显示设置了 popup.setFocusable(true)
;而在点击 back 的时候,Dialog 会消失。
(3)Popupwindow
不会给页面其余的部分添加蒙层,而 Dialog 会。
(4) Popupwindow
没 有 标 题 , Dialog 默 认 有 标 题 , 可 以 通 过dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
取消标题
(5)两者显示的时候都要设置 Gravity。若是不设置,Dialog 默认是Gravity.CENTER。
(6) 二 者 都 有 默 认 的 背 景 , 都 可 以 通 过setBackgroundDrawable(newColorDrawable(android.R.color.transparent));
去掉。
(7)Popupwindow
弹出后,取得了用户操做的响应处理权限,使得其余 UI 控件不被触发。而 AlertDialog
弹出后,点击背景,AlertDialog
会消失。
1)Application Context
是伴随应用生命周期;不能够 showDialog
, startActivity
, LayoutInflation
能够startService\BindService\sendBroadcast\registerBroadcast\load Resource values
2)Activity Context
指生命周期只与当前 Activity 有关,而 Activity Context
这些操做均可以,即凡是跟 UI 相关的,都得用 Activity 作为 Context 来处理。
一个应用 Context 的数量=Activity 数量+Service 数量+1(Application 数量)
(顺手留下GitHub连接,须要获取相关面试等内容的能够本身去找)
https://github.com/xiangjiana/Android-MS