2024年最全深入理解WMS(四):从WMS的角度分析Activity之间的关系,2024年哔哩哔哩Android高级面试题及答案

最后

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

腾讯、字节跳动、阿里、百度等BAT大厂 2019-2021面试真题解析

资料太多,全部展示会影响篇幅,暂时就先列举这些部分截图

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

其中:(WindowManager)context.getSystemService(Context.WINDOW_SERVICE)获取到是WindowManagerImpl:

这边会走到ContextImpl.getSystemService:

class ContextImpl extends Context {

@Override

public Object getSystemService(String name) {

return SystemServiceRegistry.getSystemService(this, name);

}

}

SystemServiceRegistry:

final class SystemServiceRegistry {

public static Object getSystemService(ContextImpl ctx, String name) {

ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);

return fetcher != null ? fetcher.getService(ctx) : null;

}

private static final HashMap<Class<?>, String> SYSTEM_SERVICE_NAMES =

new HashMap<Class<?>, String>();

private static final HashMap<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS =

new HashMap<String, ServiceFetcher<?>>();

private static int sServiceCacheSize;

static {

registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,

new CachedServiceFetcher() {

@Override

public AccessibilityManager createService(ContextImpl ctx) {

return AccessibilityManager.getInstance(ctx);

}});

registerService(Context.WINDOW_SERVICE, WindowManager.class,

new CachedServiceFetcher() {

@Override

public WindowManager createService(ContextImpl ctx) {

return new WindowManagerImpl(ctx);

}});

}

返回是new WindowManagerImpl(ctx);在performLaunchActivity函数中,走完attach后,继续调用mInstrumentation.callActivityOnCreate去实行XXXActivity的onCreate,这时候大家会写setContentView(R.layout.xxx)

Step3:

Activity.setContentView():

会调用getWindow().setContentView(layoutResID),即PhoneWindow类中的setContentView:主要是在PhoneWindow创建DecorView mDecor(This is the top-level view of the window, containing the window decor),然后从mDecor找出android.R.id.content: mContentParent(ViewGroup), 然后把activity设置的View添加到mContentParent.addView(view, params);

public void setContentView(@LayoutRes int layoutResID) {

getWindow().setContentView(layoutResID);

initWindowDecorActionBar();

}

PhoneWindow:

public class PhoneWindow extends Window implements MenuBuilder.Callback {

public void setContentView(int layoutResID) {

if (mContentParent == null) {

installDecor();

} else if (!hasFeature(FEATURE_CONTENT_TRANSITIONS)) {

mContentParent.removeAllViews();

}

if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {

final Scene newScene = Scene.getSceneForLayout(mContentParent, layoutResID,

getContext());

transitionTo(newScene);

} else {

mLayoutInflater.inflate(layoutResID, mContentParent);

}

mContentParent.requestApplyInsets();

final Callback cb = getCallback();

if (cb != null && !isDestroyed()) {

cb.onContentChanged();

}

mContentParentExplicitlySet = true;

}

}

Step4:

在ActivitThread.handleLaunchActivity函数走完performLaunchActivity后,接着走handleResumeActivity函数中,显示启动r = performResumeActivity(token, clearHide, reason);去走XXXActivity的onResume。

接着会对Activity的对应的window设置窗口类型:**l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION,**WMS是对窗口进行操作,每个activity对应一个窗口,Framework会定义好几种窗口类型,比如系统Window、应用程序window、子Window等。这边的type类型很重要,没有这个,window显示不出来的。

接着会调用到ViewManager wm = a.getWindowManager();wm.addView(decor, l);走到WindowManagerImpl.addView:

ActivityThread:

final void handleResumeActivity(IBinder token,

boolean clearHide, boolean isForward, boolean reallyResume, int seq, String reason) {

ActivityClientRecord r = mActivities.get(token);

r = performResumeActivity(token, clearHide, reason);

if (r.window == null && !a.mFinished && willBeVisible) {

r.window = r.activity.getWindow();

View decor = r.window.getDecorView();

decor.setVisibility(View.INVISIBLE);

ViewManager wm = a.getWindowManager();

WindowManager.LayoutParams l = r.window.getAttributes();

a.mDecor = decor;

l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION;

l.softInputMode |= forwardBit;

if (r.mPreserveWindow) {

a.mWindowAdded = true;

r.mPreserveWindow = false;

ViewRootImpl impl = decor.getViewRootImpl();

if (impl != null) {

impl.notifyChildRebuilt();

}

}

if (a.mVisibleFromClient && !a.mWindowAdded) {

a.mWindowAdded = true;

wm.addView(decor, l);

}

}

Step5:

WindowManagerImpl的addView又调用到WindowManagerGlobal.getInstance()的addView:

这个函数会创建root = new ViewRootImpl(view.getContext(), display);然后保存到mRoots.add(root)

接着调用到 root.setView(view, wparams, panelParentView);

public final class WindowManagerImpl implements WindowManager {

private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();

@Override

public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) {

applyDefaultToken(params);

mGlobal.addView(view, params, mContext.getDisplay(), mParentWindow);

}

}

public final class WindowManagerGlobal {

public void addView(View view, ViewGroup.LayoutParams params,

Display display, Window parentWindow) {

ViewRootImpl root;

View panelParentView = null;

synchronized (mLock) {

root = new ViewRootImpl(view.getContext(), display);

view.setLayoutParams(wparams);

mViews.add(view);

mRoots.add(root);

mParams.add(wparams);

}

// do this last because it fires off messages to start doing things

try {

root.setView(view, wparams, panelParentView);

} catch (RuntimeException e) {

}

}

}

Step6:

ViewRootImpl.setView():

这个函数中,通过WindowManagerGloabl拿到IWindowSession mWindowSession及远程WMS的Seesion的对象,进行mWindowSession.addToDisplay,到system_server进程的Session中。

public final class ViewRootImpl implements ViewParent,

View.AttachInfo.Callbacks, ThreadedRenderer.HardwareDrawCallbacks {

public void setView(View view, WindowManager.LayoutParams attrs, View panelParentView) {

synchronized (this) {

try {

res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,

getHostVisibility(), mDisplay.getDisplayId(),

mAttachInfo.mContentInsets, mAttachInfo.mStableInsets,

mAttachInfo.mOutsets, mInputChannel);

}

}

}

}

这个mWindowSession是

public static IWindowSession getWindowSession() {

synchronized (WindowManagerGlobal.class) {

if (sWindowSession == null) {

try {

InputMethodManager imm = InputMethodManager.getInstance();

IWindowManager windowManager = getWindowManagerService();

sWindowSession = windowManager.openSession(

new IWindowSessionCallback.Stub() {

@Override

public void onAnimatorScaleChanged(float scale) {

ValueAnimator.setDurationScale(scale);

}

},

imm.getClient(), imm.getInputContext());

} catch (RemoteException e) {

总结

【Android 详细知识点思维脑图(技能树)】

我个人是做Android开发,已经有十来年了,目前在某创业公司任职CTO兼系统架构师。虽然 Android 没有前几年火热了,已经过去了会四大组件就能找到高薪职位的时代了。这只能说明 Android 中级以下的岗位饱和了,现在高级工程师还是比较缺少的,很多高级职位给的薪资真的特别高(钱多也不一定能找到合适的),所以努力让自己成为高级工程师才是最重要的。

这里附上上述的面试题相关的几十套字节跳动,京东,小米,腾讯、头条、阿里、美团等公司19年的面试题。把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

最后,赠与大家一句话,共勉!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节。

由于篇幅有限,这里以图片的形式给大家展示一小部分。

[外链图片转存中…(img-F25nkk62-1715128084295)]

网上学习 Android的资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。希望这份系统化的技术体系对大家有一个方向参考。

最后,赠与大家一句话,共勉!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值