亦余心之所善兮,虽九死其犹未悔。这篇文章主要讲述Android Surface理解相关的知识,希望能为你提供帮助。
结合别人的博客和自己看的代码,梳理下自己对surface的理解
1.代码相关文件
/AOSP/frameworks/native/libs/ui
文章图片
主要是bufferqueuecore与surfaceflinger中分配
/AOSP/frameworks/native/libs/gui
android.mk IGraphicBufferAlloc.cpp BitTube.cpp IGraphicBufferConsumer.cpp BufferItemConsumer.cpp IGraphicBufferProducer.cpp BufferItem.cpp IProducerListener.cpp BufferQueueConsumer.cpp ISensorEventConnection.cpp BufferQueueCore.cpp ISensorServer.cpp BufferQueue.cpp ISurfaceComposerClient.cpp BufferQueueProducer.cpp ISurfaceComposer.cpp BufferSlot.cpp LayerState.cpp CleanSpec.mk Sensor.cpp ConsumerBase.cpp SensorEventQueue.cpp CpuConsumer.cpp SensorManager.cpp DisplayEventReceiver.cpp StreamSplitter.cpp GLConsumer.cpp SurfaceComposerClient.cpp GraphicBufferAlloc.cpp SurfaceControl.cpp GuiConfig.cpp Surface.cpp IConsumerListener.cpp SyncFeatures.cpp IDisplayEventConnection.cpp tests
SurfaceComposerClient 中成员变量 sp< ISurfaceComposerClient> mClient; 与surface.cpp binder通信
/AOSP/frameworks/native/services/surfaceflinger
Android.mk EventControlThread.cpp MODULE_LICENSE_APACHE2 Barrier.h EventControlThread.h MonitoredProducer.cpp Client.cpp EventLog MonitoredProducer.h Client.h EventThread.cpp RenderEngine clz.h EventThread.h SurfaceFlingerConsumer.cpp Colorizer.h FrameTracker.cpp SurfaceFlingerConsumer.h DdmConnection.cpp FrameTracker.h SurfaceFlinger.cpp DdmConnection.h Layer.cpp SurfaceFlinger.h DisplayDevice.cpp LayerDim.cpp surfaceflinger.rc DisplayDevice.h LayerDim.h tests DisplayHardware Layer.h Transform.cpp DispSync.cpp main_surfaceflinger.cpp Transform.h DispSync.h MessageQueue.cpp Effects MessageQueue.h
surfaceflinger管理surface及layer
2. Activity显示
2.1 Activity创建
【Android Surface理解】/base/core/java/android/app/ActivityThread.java
handleLaunchActivity(ActivityClientRecord r, Intent customIntent) { ............... //根据类名以Java反射的方法创建一个Activity Activity a = performLaunchActivity(r, customIntent); handleResumeActivity(r.token, false, r.isForward, !r.activity.mFinished & & !r.startsNotResumed); ................}
2.2 handleResumeActivity
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) { ..................... if (r.window == null & & !a.mFinished & & willBeVisible) { r.window = r.activity.getWindow(); //得到一个view对象 View decor = r.window.getDecorView(); decor.setVisibility(View.INVISIBLE); //获得viewManager ViewManager wm = a.getWindowManager(); WindowManager.LayoutParams l = r.window.getAttributes(); a.mDecor = decor; l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; l.softInputMode |= forwardBit; if (a.mVisibleFromClient) { a.mWindowAdded = true; //将view加入viewmanager wm.addView(decor, l); } } ..................................}
2.3 Activity 通过setContentView设置UI
Activity.java
public void setContentView(View view, ViewGroup.LayoutParams params) { getWindow().setContentView(view, params); initWindowDecorActionBar(); } public Window getWindow() { return mWindow; }
上面出现了两个和UI有关系的类:View和Window
文章图片
2.4 Activity Window 与WindowManager
Activity.java
final void attach(Context context, ActivityThread aThread, Instrumentation instr, IBinder token, int ident, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, NonConfigurationInstances lastNonConfigurationInstances, Configuration config, String referrer, IVoiceInteractor voiceInteractor) { //创建window对象 mWindow = new PhoneWindow(this); mWindow.setCallback(this); mWindow.setOnWindowDismissedCallback(this); mWindow.getLayoutInflater().setPrivateFactory(this); //创建windowManager mWindow.setWindowManager( (WindowManager)context.getSystemService(Context.WINDOW_SERVICE), mToken, mComponent.flattenToString(), (info.flags & ActivityInfo.FLAG_HARDWARE_ACCELERATED) != 0); //保存WindowManager对象 mWindowManager = mWindow.getWindowManager();
setWindowManager由PhoneWindow父类window.java实现
Window.java
public void setWindowManager(WindowManager wm, IBinder appToken, String appName,){ mWindowManager = ((WindowManagerImpl)wm).createLocalWindowManager(this); }
WindowManagerImpl.java
public WindowManagerImpl createLocalWindowManager(Window parentWindow) { return new WindowManagerImpl(mDisplay, parentWindow); } public final class WindowManagerImpl implements WindowManager {}
文章图片
(2.4)中流程总结
2.5 继续分析setContentView()
Activity.java
public void setContentView(View view, ViewGroup.LayoutParams params) { getWindow().setContentView(view, params); initWindowDecorActionBar(); }
PhoneWindow.java
private ViewGroup mContentParent; public void setContentView(View view) { setContentView(view, new ViewGroup.LayoutParams(MATCH_PARENT, MATCH_PARENT)); } public void setContentView(View view, ViewGroup.LayoutParams params) { //mContentParent是一个viewGroup对象 if (mContentParent == null) { installDecor(); } if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) { view.setLayoutParams(params); final Scene newScene = new Scene(mContentParent, view); transitionTo(newScene); } else { //把view加入到ViewGroup中 mContentParent.addView(view, params); } ........}
mContentParent是一个ViewGroup类型,它从View中派生,所以也是一个UI单元。从它名字中“Group”所表达的意思分析,它还可以包含其他的View元素。这又是什么意思呢?也就是说,在绘制一个ViewGroup时,它不仅需要把自己的样子画出来,还需要把它包含的View元素的样子也画出来。读者可将它想象成一个容器,容器中的元素就是View。
installDecor()函数
主要用来给view绘制icon ,window title,logo, menu等等
2.6 重回handleResumeActivity
我们之所以分析2.5内容,是为了弄清楚View, ViewManager(就是WindowManager)这些对象
final void handleResumeActivity(IBinder token, boolean clearHide, boolean isForward, boolean reallyResume) { ..................... if (r.window == null & & !a.mFinished & & willBeVisible) { r.window = r.activity.getWindow(); //得到一个view对象 View decor = r.window.getDecorView(); decor.setVisibility(View.INVISIBLE); //获得viewManager ViewManager wm = a.getWindowManager(); WindowManager.LayoutParams l = r.window.getAttributes(); a.mDecor = decor; l.type = WindowManager.LayoutParams.TYPE_BASE_APPLICATION; l.softInputMode |= forwardBit; if (a.mVisibleFromClient) { a.mWindowAdded = true; //将view加入viewmanager wm.addView(decor, l); } } ..................................}
分析wm.addView(decor,l)
WindowManagerImpl.java
public final class WindowManagerImpl implements WindowManager { private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance(); public void addView(@NonNull View view, @NonNull ViewGroup.LayoutParams params) { applyDefaultToken(params); mGlobal.addView(view, params, mDisplay, mParentWindow); }
WindowManagerGlobal里面可以通过AIDL与IWindowManager.Stub.asInterface 及IWindowSessionCallback.Stub() IPC通信
WindowManagerGlobal.java
public void addView(View view, ViewGroup.LayoutParams params, Display display, Window parentWindow) { root = new ViewRootImpl(view.getContext(), display); view.setLayoutParams(wparams); mViews.add(view); mRoots.add(root); mParams.add(wparams);
ViewRootImpl又是什么东东?
推荐阅读
- 手把手教你实现折线图之------安卓最好用的图表库hellocharts之最详细的使用介绍
- Android开发环境搭建
- Android艺术开发探索——第二章(IPC机制(下))
- Android开发艺术探索——第二章(IPC机制(上))
- 「android」查看应用占用cpu和内存消耗情况
- 学习笔记Android常用布局
- Android的RecyclerView
- Android TV开发总结TV上屏幕适配总结
- Android-实现底部弹出PopupWindow并让背景逐渐变暗