目录一、Activity与Fragment二、Service1. Service 启动方法与生命周期2. Service与Activity之间通信的几种方式3.IntentService4.service保活5.service onStartCommand返回值6.JobService, JobScheduler 使用7.AIDL三、ContentProvider四、BroadcastReceiver五、一些View六、Context问题七、HandlerHandler实现原理一、Activity与FragmentActivity各种情况下的生命周期:onCreate,onStart,onResume,onRestart, onPause,onStoponDestory.Activity与Fragment之间生命周期比较Activity的四种启动模式对比模式允许同一类多个实例是否会复用旧实例复用时是否清掉上面兄弟是否可能独占/分Taskstandard✅ 允许多个❌—❌singleTop✅但top不叠✅仅当 top❌❌singleTask❌同affinity-task唯一✅✅ clear top可能受 affinity 影响singleInstance❌全局唯一✅✅其实没兄弟可清✅ 独占一个 TasksingleTask:适合App 主入口MainActivity、首页型页面你希望回到首页并把中间页清掉。SingleInstance 典型特征中断当前流程、独立完成任务、结束后回到原处。比如来电接听界面。Activity状态保存与恢复复写onSaveInstanceState和onRestoreInstanceStateonSaveInstanceState(Bundle outState)会在以下情况被调用进入后台可能被销毁不是确定会被销毁1、当用户按下HOME键时屏幕被关闭时。2、从当前activity启动一个新的activity时。3、屏幕方向切换时。Fragment状态保存startActivityForResult是哪个类的方法在什么情况下使用总结起来就是从哪里发起调用最终就会走到哪里。1.用getActivity方法发起调用只有父Activity的onActivityResult会调用Fragment中的onActivityResult不会被调用 2.直接发起startActivityForResult调用当前的Fragment的onActivityResult和父Activity的onActivityResult都会调用 3.用getParentFragment发起调用则只有父Activity和父Fragment的onActivityResult会被调用当前的Fragment的onActivityResult不会被调用。 这里2和3的前提是如果父activity中重写了onActivityResult父Activity的onActivityResult中必须添加super.onActivityResult()。如何实现Fragment的滑动ViewPagerfragment之间传递数据的方式通过所在Activity中的set, get 方法利用bundle 和setArguments进行参数传递EventBus; EventBus原理 发布订阅模式。二、Service1. Service 启动方法与生命周期1. startService启动类型的服务: onCreate()- onStartCommand()-Service running--调用context.stopService() -onDestroy() 。2. bindService 绑定类型的服务: onCreate()-onBind()-Service running--调用onUnbind() - onDestroy()2. Service与Activity之间通信的几种方式在startService 时把数据通过Intent传递过去bindservice时实现ServiceConnection注册Callback的方式3.IntentService一个继承自Service的抽象类里面封装了Handler和HandlerThread子线程运行。所有任务结束后能自动销毁。4.service保活onStartCommand 中返回START_STICKY;在onDestory中启动该服务同时开启两个进程和服务5.service onStartCommand返回值START_STICKYservice被杀后重新创建但不处理之前的intent。默认值START_STICKY_COMPATIBILITY 是其兼容版2.0一下使用。START_NOT_STICKY服务被杀后不会重新启动。START_REDELIVER_INTENT服务被杀重启后会再分发intent.6.JobService, JobScheduler 使用执行时间不精准但利于省电。Android JobScheduler 的使用-CSDN博客7.AIDL使用方法客户端与服务端挂了怎么办DeadObjectException客户端deadObject异常处理 注册死亡代理DeathRecipient当binder死亡后系统会回调binderDied方法 。服务端如何知道客户端挂了客户端在注册时把客户端的binder传给服务端并调用binder.linkToDeath注册死亡代理在服务端处理当客户端挂了时服务端就知道了。当binder断开连接后系统会回调onServiceDisconnected然后我们可以重连服务。inout,oneway等参数。常见组合示例// 1. in oneway异步传递输入参数调用方发指令不等待结果oneway void startDownload(in String url);// 2. out 同步同步获取服务端输出结果调用方等待服务端填充数据void getDownloadProgress(out Progress progress);// 3. inout 同步同步双向交互调用方传初始配置服务端更新后返回void syncSettings(inout AppSettings settings);三、ContentProviderContentProvider的原理ContentProvider原理分析_blueberry_mu的博客-CSDN博客_contentprovider原理 ,难点主要在获取ContentResolver的获取流程。ContentProvider、ContentResolver、ContentObserver 之间的关系使用ContentResolver来获取ContentProvider提供的数据同时注册ContentObserver监听Uri数据的变化ContentProvider 是如何实现数据共享的getContentResolver返回的ContentResolver是在ContextImpl 中创建一个ApplicationContentResolver对象调用增删改查方法时是调用acquireProvider(返回一个IContentProvider 对象)的增删改查方法调用ActivityManagerService.getContentProvider方法---startProcessLocked---ActivityThread.installProvider---ContentProvider.onCreate;ContentProvider的权限管理(解答读写分离权限控制-精确到表级URL控制)四、BroadcastReceiver请描述一下广播BroadcastReceiver的理解广播使用的方式和场景。BroadcastReceiver.onReceive() 中不可以开启新的线程来进行耗时的操作。在BroadcastReceiver.onReceive()方法收到广播开启一个线程接着它返回也就是执行完毕后系统会认为BroadcastReceiver不在处于活动状态。因此不在需要起托管进程(除非其他应用程序组件处于活动状态如ActivityService)。因此系统可能随时终止进程来回收内存并且这样会终止进程中运行的线程。BroadcastReceiverLocalBroadcastReceiver 区别LocalBroadcastReceiver用于内部传递消息更高效安全只能动态注册。依托LocalBroadcastManager使用。原理借助一个静态单例类LocalBroadcastManager。静态保证了他一旦创建就基本上与application一样的生命周期。他持有 所有register到他里面的broadcast的引用。因此需要利用他发广播时就可以立即拿到这个broadcast引用 调用 这个broadcast对象的onReceive方法。BroadcastReceiver与EventBus比较广播资源消耗高、需要Context能用于跨进程。EventBus调用灵活不依赖Context;使用简单Subscriber 即可。但逻辑性不是很好适合统一进程。五、一些ViewAndroid view 学习总结六、Context问题ApplicationContext和ActivityContext的区别ApplicationContext 不应该用于界面相关的地方ActivityContext 可能使得对象不能及时被释放从而引发内存泄漏。进程和 Application 的生命周期在大多数情况下每个Android应用程序都在自己的Linux进程中运行。当需要运行某些代码时将为应用程序创建此过程并且该过程将一直运行直到不再需要它为止并且 系统需要回收其内存以供其他应用程序使用。七、HandlerHandler实现原理Handler持有MessageQueue和Looper 底层利用Linux epoll 机制没有消息时会通过epoll_wait进入睡眠状态。Handler机制和底层实现:handler通过sendMessage把消息发送到MessageQueue里面enqueueMessage函数解析 参考如下boolean enqueueMessage(Message msg, long when) { //这里处理的普通消息必须是包含Handler的下面会提及一个同步屏障消息它其中不包含Handler if (msg.target null) { throw new IllegalArgumentException(Message must have a target.); } //存在已经消费过的标记不在继续添加 if (msg.isInUse()) { throw new IllegalStateException(msg This message is already in use.); } synchronized (this) { if (mQuitting) { //如果Queue已经退出则将消息recycler msg.recycle(); return false; } //标记使用状态 msg.markInUse(); //设置延迟时间 msg.when when; //mMessage是一个全局变量代表MessageQueue的头节点 Message p mMessages; //头节点为空 或者 等待时间小于头节点 那么都放在队列的前端 if (p null || when 0 || when p.when) { //给msg的上一个节点赋值这里将头节点设置为下一个当前msg为头节点 msg.next p; //给头节点赋值 mMessages msg; } else { Message prev; for (;;) { //比较时间将消息按照时间进行排列 prev p; p p.next; if (p null || when p.when) { break; } } //将消息插入合适的位置 msg.next p; //这里也就是一个排队的逻辑 prev.next msg; } } return true; } 原文链接https://blog.csdn.net/wcy0312808/article/details/90295965Looper中有个for循环不断调用queue.next读取消息nativePollOnce底层采用的是pipe/epoll机制无消息时会释放CPU从而不会导致阻塞。 最终调用Message.target.dispatchMessage 里面具体实现如下public void dispatchMessage(Message msg) { if (msg.callback ! null) { handleCallback(msg); } else { if (mCallback ! null) { if (mCallback.handleMessage(msg)) { return; } } handleMessage(msg); } }handler.post(...) //第一优先级执行post所传递的Runnable参数.run()。会被封装为message处理new Handler(callback) //第二优先级执行构造方法传来的callback匿名内部类。handleMessage(msg)//第三优先级调用Handler的handleMessage()方法public final boolean post(NonNull Runnable r) { return sendMessageDelayed(getPostMessage(r), 0); }Handler、Thread和HandlerThread的差别HandlerThread 自带消息循环的线程用于处理一系列串行的后台任务。handler发消息给子线程looper怎么启动 调用Loop.prepare() 与Loop.loop()。关于Handler在任何地方new Handler 都是什么线程下? - 不传参数时在什么线程下new就和什么线程绑定。在子线程new时要调用Loop.prepare();Loop.loop()Handler 内存泄漏原因及解决方案