news 2026/7/31 17:40:29

Android基础知识总结

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Android基础知识总结

目录

一、Activity与Fragment

二、Service

1. Service 启动方法与生命周期

2. Service与Activity之间通信的几种方式

3.IntentService

4.service保活

5.service onStartCommand返回值

6.JobService, JobScheduler 使用

7.AIDL

三、ContentProvider

四、BroadcastReceiver

五、一些View

六、Context问题

七、Handler

Handler实现原理


一、Activity与Fragment

  1. Activity各种情况下的生命周期:onCreate,onStart,onResume,onRestart, onPause,onStop,onDestory.
  2. Activity与Fragment之间生命周期比较
  3. Activity的四种启动模式对比

    模式

    允许同一类多个实例?

    是否会复用旧实例?

    复用时是否清掉上面兄弟?

    是否可能独占/分Task

    standard

    ✅ 允许多个

    singleTop

    ✅(但top不叠)

    ✅(仅当 top)

    singleTask

    ❌(同affinity-task唯一)

    ✅ clear top

    可能(受 affinity 影响)

    singleInstance

    ❌(全局唯一)

    ✅(其实没兄弟可清)

    ✅ 独占一个 Task

    singleTask:适合:App 主入口(MainActivity)、首页型页面(你希望回到首页并把中间页清掉)。SingleInstance 典型特征:中断当前流程、独立完成任务、结束后回到原处。比如来电接听界面。
  4. Activity状态保存与恢复:复写onSaveInstanceState和onRestoreInstanceState

onSaveInstanceState(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()。
  1. 如何实现Fragment的滑动:ViewPager
  2. fragment之间传递数据的方式?
    1. 通过所在Activity中的set, get 方法;
    2. 利用bundle 和setArguments进行参数传递;
    3. EventBus; EventBus原理 发布订阅模式。

二、Service

1. Service 启动方法与生命周期

1. startService启动类型的服务: onCreate()- >onStartCommand()->Service running--调用context.stopService() ->onDestroy() 。

2. bindService 绑定类型的服务: onCreate()->onBind()->Service running--调用>onUnbind() -> onDestroy()

2. Service与Activity之间通信的几种方式

  1. 在startService 时,把数据通过Intent传递过去;
  2. bindservice时,实现ServiceConnection;
  3. 注册Callback的方式;

3.IntentService

一个继承自Service的抽象类,里面封装了Handler和HandlerThread,子线程运行。所有任务结束后能自动销毁。

4.service保活

  1. onStartCommand 中返回START_STICKY;
  2. 在onDestory中启动该服务;
  3. 同时开启两个进程和服务;

5.service onStartCommand返回值

START_STICKY:service被杀后重新创建,但不处理之前的intent。(默认值)START_STICKY_COMPATIBILITY 是其兼容版,2.0一下使用。

START_NOT_STICKY:服务被杀后不会重新启动。

START_REDELIVER_INTENT:服务被杀重启后会再分发intent.

6.JobService, JobScheduler 使用

执行时间不精准,但利于省电。

Android JobScheduler 的使用-CSDN博客

7.AIDL

  1. 使用方法;
  2. 客户端与服务端挂了怎么办?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);

三、ContentProvider

  1. ContentProvider的原理:ContentProvider原理分析_blueberry_mu的博客-CSDN博客_contentprovider原理 ,难点主要在获取ContentResolver的获取流程。
  2. ContentProvider、ContentResolver、ContentObserver 之间的关系:使用ContentResolver来获取ContentProvider提供的数据,同时注册ContentObserver监听Uri数据的变化
  3. ContentProvider 是如何实现数据共享的?
    1. getContentResolver:返回的ContentResolver是在ContextImpl 中创建,一个ApplicationContentResolver对象;
    2. 调用增删改查方法时,是调用acquireProvider(返回一个IContentProvider 对象)的增删改查方法;
    3. 调用ActivityManagerService.getContentProvider方法---startProcessLocked---ActivityThread.installProvider---ContentProvider.onCreate;
  4. ContentProvider的权限管理(解答:读写分离,权限控制-精确到表级,URL控制)

四、BroadcastReceiver

  1. 请描述一下广播BroadcastReceiver的理解,广播使用的方式和场景。
  2. BroadcastReceiver.onReceive() 中不可以开启新的线程来进行耗时的操作。在BroadcastReceiver.onReceive()方法收到广播,开启一个线程,接着它返回也就是执行完毕后,系统会认为BroadcastReceiver不在处于活动状态。因此不在需要起托管进程(除非其他应用程序组件处于活动状态,如Activity,Service)。因此系统可能随时终止进程来回收内存,并且这样会终止进程中运行的线程。
  3. BroadcastReceiver,LocalBroadcastReceiver 区别:LocalBroadcastReceiver用于内部传递消息,更高效安全,只能动态注册。依托LocalBroadcastManager使用。原理:借助一个静态单例类LocalBroadcastManager。静态保证了他一旦创建就基本上与application一样的生命周期。他持有 所有register到他里面的broadcast的引用。因此需要利用他发广播时,就可以立即拿到这个broadcast引用 调用 这个broadcast对象的onReceive方法。
  4. BroadcastReceiver与EventBus比较:广播资源消耗高、需要Context,能用于跨进程。EventBus调用灵活,不依赖Context;使用简单,Subscriber 即可。但逻辑性不是很好,适合统一进程。

五、一些View

Android view 学习总结

六、Context问题

ApplicationContext和ActivityContext的区别:ApplicationContext 不应该用于界面相关的地方,ActivityContext 可能使得对象不能及时被释放,从而引发内存泄漏。

进程和 Application 的生命周期:

在大多数情况下,每个Android应用程序都在自己的Linux进程中运行。当需要运行某些代码时,将为应用程序创建此过程,并且该过程将一直运行,直到不再需要它为止,并且 系统需要回收其内存以供其他应用程序使用。

七、Handler

Handler实现原理

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/90295965

Looper中有个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); }
  1. Handler、Thread和HandlerThread的差别:HandlerThread 自带消息循环的线程,用于处理一系列串行的后台任务。
  2. handler发消息给子线程,looper怎么启动? 调用Loop.prepare() 与Loop.loop()。
  3. 关于Handler,在任何地方new Handler 都是什么线程下? - 不传参数时,在什么线程下new,就和什么线程绑定。在子线程new时,要调用Loop.prepare();Loop.loop()
  4. Handler 内存泄漏原因及解决方案
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/31 17:37:35

Python学习复盘:四步提升编程效率

1. 新手学习复盘的价值与意义 刚接触一个新领域时&#xff0c;我们常常会陷入"学了很多却记不住"的困境。上周我指导的一位编程新人就遇到了这种情况&#xff1a;他花了两个月学习Python基础语法&#xff0c;但在实际写代码时却连最基本的循环结构都用不利索。这种现…

作者头像 李华
网站建设 2026/7/31 17:35:15

G-Helper终极指南:释放华硕笔记本隐藏性能的免费轻量级工具

G-Helper终极指南&#xff1a;释放华硕笔记本隐藏性能的免费轻量级工具 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook, Zenboo…

作者头像 李华
网站建设 2026/7/31 17:34:07

STM32 SPI通信从原理到实战:高速串行总线配置与FLASH驱动开发

1. 从零开始理解SPI&#xff1a;为什么它比UART和I2C更“快”&#xff1f; 如果你刚开始玩STM32&#xff0c;搞定了GPIO点灯&#xff0c;也调通了UART串口打印&#xff0c;那恭喜你&#xff0c;已经迈出了嵌入式世界的第一步。接下来&#xff0c;你大概率会听到两个高频词&…

作者头像 李华