Android Surface理解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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创建

/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又是什么东东?

以上是关于Android Surface理解的主要内容,如果未能解决你的问题,请参考以下文章

android6.0 Activity Surface创建

了解 Canvas 和 Surface 概念

Surface的理解

Surface的理解

如何在不将图像保存在本地的情况下将捕获的图像(Surface View)传递给另一个片段?

Android 截屏 Surface View 显示黑屏