其实核心是**创建一块共享区域,然后2个进程同时把这片区域 mmap 到本进程,然后读写就像本进程的内存一样。**这里要解释下第3步,为什么要倒腾 fd,因为在 linux 中 fd 只是对本进程是唯一的,在 Proc A 中打开一个文件得到一个 fd,但是把这个打开的 fd 直接放到 Proc B 中,Proc B 是无法直接使用的呀。可是文件是唯一的,也就是说一个文件(file)可以被多次打开,每打开一次就有一个 fd(文件描述符),所以对于同一个文件而言,需要某种转化,把 Proc A 中的 fd 转化成 Proc B 中的 fd。这样 Proc B 才能通过 fd mmap 同样的共享内存文件。
使用场景:进程间大量数据传输
6.ContentProvider实现原理
ContentProvider 有以下两个特点:
- 封装:对数据进行封装,提供统一的接口,使用者完全不必关心这些数据是在DB,XML、Preferences或者网络请求来的。当项目需求要改变数据来源时,使用我们的地方完全不需要修改。
- 提供一种跨进程数据共享的方式。
Content Provider组件在不同应用程序之间传输数据是基于匿名共享内存机制来实现的。其主要的调用过程:
①通过ContentResolver先查找对应给定Uri的ContentProvider,返回对应的BinderProxy
-
如果该Provider尚未被调用进程使用过:
-
通过ServiceManager查找activity service得到ActivityManagerService对应BinderProxy
-
调用BinderProxy的transcat方法发送GET_CONTENT_PROVIDER_TRANSACTION命令,得到对应ContentProvider的BinderProxy。
-
如果该Provider已被调用进程使用过,则调用进程会保留使用过provider的HashMap。此时直接从此表查询即得。
②调用BinderProxy的query()
7.如何使用ContentProvider进行批量操作?
通常进行数据的批量操作我们都会使用“事务”,但是ContentProvider如何进行批量操作呢?创建 ContentProviderOperation 对象数组,然后使用 ContentResolver.applyBatch() 将其分派给内容提供程序。您需将内容提供程序的授权传递给此方法,而不是特定内容 URI。这样可使数组中的每个 ContentProviderOperation 对象都能适用于其他表。调用 ContentResolver.applyBatch() 会返回结果数组。
同时我们还可以通过ContentObserver对数据进行观察:
- 创建我们特定的ContentObserver派生类,必须重载onChange()方法去处理回调后的功能实现
- 利用context.getContentResolover()获得ContentResolove对象,接着调用registerContentObserver()方法去注册内容观察者,为指定的Uri注册一个ContentObserver派生类实例,当给定的Uri发生改变时,回调该实例对象去处理。
- 由于ContentObserver的生命周期不同步于Activity和Service等,因此,在不需要时,需要手动的调用unregisterContentObserver()去取消注册。
8.广播注册后不解除注册会有什么问题?(内存泄露)
我们可以通过两种方式注册BroadcastReceiver,一是在Activity启动过程中通过代码动态注册,二是在AndroidManifest.xml文件中利用标签进行静态注册。
- 对于第一种方法,我们需要养成一个良好的习惯:在Activity进入停止或者销毁状态的时候使用unregisterReceiver方法将注册的BroadcastReceiver注销掉。
- 对于标签进行注册的,那么该对象的实例在onReceive被调用之后就会在任意时间内被销毁。
9.属性动画(Property Animation)和补间动画(Tween Animation)的区别
10.BrocastReceive里面可不可以执行耗时操作?
11.Android优化工具:TraceView和Systrace
12.Dalvik与ART的区别?
13.Android动态权限?
14.ViewPager如何判断左右滑动?
实现OnPageChangeListener并重写onPageScrolled方法,通过参数进行判断。
15.ListView与RecyclerView
16.描述一下Android手机启动过程和App启动过程?
Android手机启动过程
当我们开机时,首先是启动Linux内核,在Linux内核中首先启动的是init进程,这个进程会去读取配置文件system\core\rootdir\init.rc
配置文件,这个文件中配置了Android系统中第一个进程Zygote进程。
启动Zygote进程 --> 创建AppRuntime(Android运行环境) --> 启动虚拟机 --> 在虚拟机中注册JNI方法 --> 初始化进程通信使用的Socket(用于接收AMS的请求) --> 启动系统服务进程 --> 初始化时区、键盘布局等通用信息 --> 启动Binder线程池 --> 初始化系统服务(包括PMS,AMS等等) --> 启动Launcher
App启动过程
- 应用的启动是从其他应用调用startActivity开始的。通过代理请求AMS启动Activity。
- AMS创建进程,并进入ActivityThread的main入口。在main入口,主线程初始化,并loop起来。主线程初始化,主要是实例化ActivityThread和ApplicationThread,以及MainLooper的创建。ActivityThread和ApplicationThread实例用于与AMS进程通信。
- 应用进程将实例化的ApplicationThread,Binder传递给AMS,这样AMS就可以通过代理对应用进程进行访问。
- AMS通过代理,请求启动Activity。ApplicationThread通知主线程执行该请求。然后,ActivityThread执行Activity的启动。
- Activity的启动包括,Activity的实例化,Application的实例化,以及Activity的启动流程:create、start、resume。
可以看到 **入口Activity其实是先于Application实例化,只是onCreate之类的流程,先于Activity的流程。**另外需要scheduleLaunchActivity,在ApplicationThreaad中,对应AMS管理Activity生命周期的方法都以scheduleXXXActivity,ApplicationThread在Binder线程中,它会向主线程发送消息,ActivityThread的Handler会调用相应的handleXXXActivity方法,然后会执行performXXXActivity方法,最终调用Activity的onXXX方法
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
最后
都说三年是程序员的一个坎,能否晋升或者提高自己的核心竞争力,这几年就十分关键。
技术发展的这么快,从哪些方面开始学习,才能达到高级工程师水平,最后进阶到Android架构师/技术专家?我总结了这 5大块;
我搜集整理过这几年阿里,以及腾讯,字节跳动,华为,小米等公司的面试题,把面试的要求和技术点梳理成一份大而全的“ Android架构师”面试 Xmind(实际上比预期多花了不少精力),包含知识脉络 + 分支细节。
《Android架构视频+BAT面试专题PDF+学习笔记》
网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望**这份系统化的技术体系**对大家有一个方向参考。
识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望**这份系统化的技术体系**对大家有一个方向参考。
2021年虽然路途坎坷,都在说Android要没落,但是,不要慌,做自己的计划,学自己的习,竞争无处不在,每个行业都是如此。相信自己,没有做不到的,只有想不到的。祝大家2021年万事大吉。