先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip204888 (备注Android)
正文
fragmentList.add(Fragment2())
fragmentList.add(Fragment3())
// 为MyPagerAdapter适配器设置FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT 参数
val myPagerAdapter: MyPagerAdapter = MyPagerAdapter(
getSupportFragmentManager(),
FragmentPagerAdapter.BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT, fragmentList
)
viewPager.setAdapter(myPagerAdapter)
// 设置预加载为3页,来测试懒加载是否成功
viewPager.offscreenPageLimit = 3
}
class MyPagerAdapter(
fm: FragmentManager,
behavior: Int,
val fragmentList: List<Fragment>
) :
FragmentPagerAdapter(fm, behavior) {
override fun getCount() = fragmentList.size
override fun getItem(position: Int) = fragmentList[position]
}
}
FragmentPagerAdapter 在创建 Fragment后,根据 behavior 调用了setMaxLifecycle。
//FragmentPagerAdapter.java
public FragmentPagerAdapter(@NonNull FragmentManager fm,
@Behavior int behavior) {
mFragmentManager = fm;
mBehavior = behavior;
}
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
…
if (fragment != mCurrentPrimaryItem) {
fragment.setMenuVisibility(false);
// mBehaviour为1的时候走新逻辑
if (mBehavior == BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
// 初始化item时将其生命周期限制为STARTED
mCurTransaction.setMaxLifecycle(fragment, Lifecycle.State.STARTED);
} else {
// 兼容旧版逻辑
fragment.setUserVisibleHint(false);
}
}
return fragment;
}
@Override
public void setPrimaryItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
Fragment fragment = (Fragment)object;
if (fragment != mCurrentPrimaryItem) {
if (mCurrentPrimaryItem != null) {
mCurrentPrimaryItem.setMenuVisibility(false);
if (mBehavior == BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
…
// 滑走的会变成非主item, 设置其Lifecycle为STARTED
mCurTransaction.setMaxLifecycle(mCurrentPrimaryItem, Lifecycle.State.STARTED);
} else {
mCurrentPrimaryItem.setUserVisibleHint(false);
}
}
fragment.setMenuVisibility(true);
if (mBehavior == BEHAVIOR_RESUME_ONLY_CURRENT_FRAGMENT) {
…
// 设置新滑到的主item的Lifecycle为RESUMED
mCurTransaction.setMaxLifecycle(fragment, Lifecycle.State.RESUMED);
} else {
fragment.setUserVisibleHint(true);
}
mCurrentPrimaryItem = fragment;
}
}
不借助 behavior,在自定义Adapter中构建 Framgent时直接调用setMaxLifecycle 也是等价的。
#### setMaxLifecycle 实现原理
setMaxLifecycle 使用方法很简单,接下来通过梳理源码了解一下实现原理(基于1.3.0-rc01),即使面试官追问其原理你也能沉着应对。
**OP\_SET\_MAX\_LIFECYCLE**
我们知道 FramgentTransition 对 Fragment 的所有操作都将转换为一个Op,针对setMaxLifecycle也同样增加了一个新的Op -- `OP_SET_MAX_LIFECYCLE`, 专门用来设置生命周期的上限。
@NonNull
public FragmentTransaction setMaxLifecycle(@NonNull Fragment fragment,
@NonNull Lifecycle.State state) {
addOp(new Op(OP_SET_MAX_LIFECYCLE, fragment, state));
return this;
}
当 FramgentTransition 对 Frament 添加了 OP\_SET\_MAX\_LIFECYCLE 后,在实现类 BackStackRecord 中, FragmentManager 会遍历 Transaction 的 Op 列表
void executeOps() {
final int numOps = mOps.size();
for (int opNum = 0; opNum < numOps; opNum++) {
final Op op = mOps.get(opNum);
final Fragment f = op.mFragment;
//…
switch (op.mCmd) {
//…
// 新引入的这个Op类型, 在这里会给这个Fragment设置允许的生命周期上限
case OP_SET_MAX_LIFECYCLE:
mManager.setMaxLifecycle(f, op.mCurrentMaxState);
break;
//…
}
}
当遇到 OP\_SET\_MAX\_LIFECYCLE 时,通过调用 FragmentManager 的 setMaxLifeCycle 方法设置 fragment 的 mMaxState,以标记其生命周期上限
void setMaxLifecycle(@NonNull Fragment f, @NonNull Lifecycle.State state) {
//…
f.mMaxState = state;
}
**FragmentStateManager**
FragmentManager 通过 FragmentStateManager 推进 Fragment 的生命周期。 推进过程中根据 mMaxState 对生命周期
值得一提的是,FragmentStateManager 是 1.3.0-alpha08 之后新增的类,将原来和 State 相关的逻辑从FragmentManager 抽离了出来, 降低了与 Fragment 的耦合, 职责更加单一。
![](https://img-blog.csdnimg.cn/img_convert/dc29ff1568df243549116a4d5dd68383.png)
看一下在 FragmentStateManager 中具体是如何推进 Fragment 生命周期的:
void moveToExpectedState() {
try {
…
// 循环计算声明周期是否可以推进
while ((newState = computeExpectedState()) != mFragment.mState) {
if (newState > mFragment.mState) {
// 生命周期向前推进
int nextStep = mFragment.mState + 1;
//…
switch (nextStep) {
//…
case Fragment.ACTIVITY_CREATED:
//…
case Fragment.STARTED:
start();
break;
//…
case Fragment.RESUMED:
resume();
break;
}
} else {
// 如果应有的生命周期小于当前, 后退
int nextStep = mFragment.mState - 1;
//…
switch (nextStep) {
// 与上面的switch类似
//…
}
}
}
…
}
…
}
int computeExpectedState() {
// 其他计算expected state的逻辑, 算出maxState
//…
// mMaxState 对生命周期做出限制
switch (mFragment.mMaxState) {
case RESUMED:
break;
case STARTED:
maxState = Math.min(maxState, Fragment.STARTED);
break;
case CREATED:
maxState = Math.min(maxState, Fragment.CREATED);
break;
default:
maxState = Math.min(maxState, Fragment.INITIALIZING);
}
// 其他计算expected state的逻辑, 算出 maxState
// ...
return maxState;
}
整体流程图如下
![](https://img-blog.csdnimg.cn/img_convert/71921e979185987a6634b90b0cb76ebd.png)
#### 最后
除了使用默认的 BEHAVIOR\_RESUME\_ONLY\_CURRENT\_FRAGMENT,我们甚至可以在自定义 Adapter 的instantiateItem 中为将 Fragment的 MaxLifecycle 设置为 `CREATED`, 这样可以让 Fragment 只走到onCreate 从而延迟更多操作,比如在 onCreateView 中的 inflate 以及 onViewCreated 中的一些操作。 Fragment 1.3.0-rc01 已经支持设置最大生命周期为 `INITIALIZED`
面试前复习路线参考
### 总结
其实客户端开发的知识点就那么多,面试问来问去还是那么点东西。所以面试没有其他的诀窍,只看你对这些知识点准备的充分程度。so,出去面试时先看看自己复习到了哪个阶段就好。
![Android大厂面试真题全套解析](https://img-blog.csdnimg.cn/img_convert/7d6bd239d519425205dc510fe67c6847.webp?x-oss-process=image/format,png)
![2017-2020字节跳动Android面试真题解析PDF](https://img-blog.csdnimg.cn/img_convert/cdeaa31aa5e4e3e963b048d5ebdd54fb.webp?x-oss-process=image/format,png)
然而Android架构学习进阶是一条漫长而艰苦的道路,不能靠一时激情,更不是熬几天几夜就能学好的,必须养成平时努力学习的习惯。所以:**贵在坚持!**
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)**
![img](https://img-blog.csdnimg.cn/img_convert/e0275a1ba4cba8972107c87a371cbf8a.png)
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
的习惯。所以:**贵在坚持!**
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**需要这份系统化的资料的朋友,可以添加V获取:vip204888 (备注Android)**
[外链图片转存中...(img-U9CgY5UR-1713049014192)]
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**