Android 2.3 Rotation and Orientation

本文详细解析了Android系统中屏幕旋转的实现过程,包括初始化服务、设置屏幕方向及获取当前方向等关键步骤。从源码层面介绍了Activity、WindowManagerService及SurfaceFlinger之间的交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Service:
28 window: [android.view.IWindowManager]
38 activity: [android.app.IActivityManager]
46 SurfaceFlinger: [android.ui.ISurfaceComposer]

1) Init services
system/core/init/init.c
restart_processes()@system/core/init/init.c
    service_start()
      execve()   【service zygote /system/bin/app_process -Xzygote/system/bin --zygote--start-system-server init.rc
        main()@frameworks\base\cmds\app_main.cpp
          runtime.start("com.android.internal.os.ZygoteInit",startSystemServer);
            startSystemServer()@com.android.internal.os.ZygoteInit
              main()@com/android/server/SystemServer
                init1()
                  android_server_SystemServer_init1()@com_android_server_SystemServer.cpp
                    system_init()   {SurfaceFlinger::instantiate()}
                      runtime->callStatic("com/android/server/SystemServer", "init2");
                        init2()@com/android/server/SystemServer
                          new ServerThread()
                            ActivityManagerService.main()
                            wm = WindowManagerService.main()
                               new WMThread()@WindowManagerService.java
                                new WindowManagerService()
                                  { final WindowManagerPolicy mPolicy = PolicyManager.makeNewWindowManager();
                                      PolicyManager.makeNewWindowManager()
                                        makeNewWindowManager()@com.android.internal.policy.impl.Policy
                                          return new PhoneWindowManager
                                            { class MyOrientationListener extends WindowOrientationListener }
                                   }


2) Set Orientation
WindowOrientationListener.java
  onSensorChanged() [
ROTATION_XXX -> Surface.ROTATION_XXX]
    onOrientationChanged(
Surface.ROTATION_XXX)
      setRotation()@WindowManagerService
        setRotationUnchecked()
          setRotationUncheckedLocked()
            Surface::setOrientation()
              setOrientation(Surface.ROTATION_XXX)@Surface.java
                Surface_setOrientation()@android_view_Surface.cpp
                  setOrientation()@SurfaceComposerClient.cpp
                    SurfaceFlinger::setOrientation()
                     setTransactionFlags()@SurfaceFlinger.cpp
                       handleTransaction()@SurfaceFlinger.cpp
                         handleTransactionLocked()@SurfaceFlinger.cpp
                           dcblk->orientation = orientation;
                             GraphicPlane::setOrientation(ISurfaceComposer::eOrientation_XXX)@SurfaceFlinger.cpp
                               GraphicPlane::orientationToTransfrom()[
ISurfaceComposer::eOrientationXXX -> Transform::ROT_XXX]

3) Get Orientation
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
getWindowManager().getDefaultDisplay().getOrientation()@Activity.java
  getSystemService(Context.WINDOW_SERVICE)@Activity.java  [== getWindowManager()@Activity.java]
    {return mWindowManager
      attach()@androi.app.Activity
        mWindow = PolicyManager.makeNewWindow(this)
          mWindow.setWindowManager(null)
            wm = WindowManagerImpl.getDefault();
              return new
WindowManagerImpl()
                mWindowManager = new LocalWindowManager(wm);
    }

    getDefaultDisplay()@android.view.WindowManagerImpl
      return new Display()
        init()@android.view.Display
          android_view_Display_init()@android_view_Display.cpp
            SurfaceComposerClient.cpp:: getDisplayInfo()
              get_cblk()
                ISurfaceComposer-> getCblk()
                  getCblk()@SurfaceFlinger.cpp  (SurfaceFlinger: [android.ui.ISurfaceComposer])
                    readyToRun()
                      const GraphicPlane& plane(graphicPlane(dpy));
                      const DisplayHardware& hw = plane.displayHardware();

                      dcblk->orientation = ISurfaceComposer::eOrientationDefault;
       getOrientation()@android.view.Display
         android_view_Display_getOrientation()@android.view.Display
           SurfaceComposerClient::getDisplayOrientation()
             get_cblk()
               return dcblk->orientation

WindowOrientationListener.java
    private static final int ROTATION_0 = 0;
    private static final int ROTATION_90 = 1;
    private static final int ROTATION_270 = 2;
    private static final int ROTATION_180 = 3;

Surface.java
    public static final int ROTATION_0       = 0;
    public static final int ROTATION_90      = 1;
    public static final int ROTATION_180     = 2;
    public static final int ROTATION_270     = 3;

ISurfaceComposer.h
enum {
    eOrientationDefault     = 0,
    eOrientation90          = 1,
    eOrientation180         = 2,
    eOrientation270         = 3,
    eOrientationSwapMask    = 0x01
};

Transform.h
enum orientation_flags {
    ROT_0   = 0x00000000,
    FLIP_H  = HAL_TRANSFORM_FLIP_H,
    FLIP_V  = HAL_TRANSFORM_FLIP_V,
    ROT_90  = HAL_TRANSFORM_ROT_90,
    ROT_180 = FLIP_H|FLIP_V,
    ROT_270 = ROT_180|ROT_90,
    ROT_INVALID = 0x80

};


getRequestedOrientation()@Activity.java
  ActivityManagerNative.getDefault().getRequestedOrientation()
    ServiceManager.getService("activity").asInterface()
      getRequestedOrientation()@ActivityManagerService.java
        getAppOrientation()@WindowManagerService
          findAppWindowToken()
            getAppOrientation()
              return wtoken.requestedOrientation;

setRequestedOrientation()@Activity.java
  ActivityManagerNative.getDefault().setRequestedOrientation()
    ServiceManager.getService("activity").asInterface()
      setRequestedOrientation()@ActivityManagerService.java
        setAppOrientation()@WindowManagerService
          findAppWindowToken()
            setAppOrientation()
              wtoken.requestedOrientation = requestedOrientation;
        updateOrientationFromAppTokens()@WindowManagerService
          setRotationUncheckedLocked()

            Surface.setOrientation()


http://blog.youkuaiyun.com/watchnight/article/details/6701260


### 设置 Android 视图旋转属性 在 Android 中,可以通过 `rotation` 属性来实现视图的旋转变换。对于需要将视图旋转 90 度的情况,在 XML 布局文件中可以直接指定该属性[^2]。 #### 使用 XML 定义静态旋转效果 通过在布局资源文件内定义视图组件时加入特定属性完成初始化状态下的角度变换: ```xml <View android:layout_width="75dp" android:layout_height="75dp" android:rotation="90"/> ``` 上述代码片段展示了如何利用 XML 来配置一个具有固定大小并已预先设置了顺时针方向上转动了四分之一圆周(即 90°)的对象实例。 #### 动态调整视图的角度 除了可以在 XML 文件里设定初始值外,还可以借助 Java 或 Kotlin 编程语言中的 API 实现运行期间动态改变控件的姿态特性。下面给出了一种基于对象动画器的方法用于执行平滑过渡至目标方位角的过程[^4]。 ##### 示例:创建围绕 Z 轴自转的效果 ```kotlin val rotationAnimator = ObjectAnimator.ofFloat(viewToRotate, "rotation", viewToRotate.rotation, 90f) rotationAnimator.duration = 300 // 持续时间为3rotationAnimator.start() ``` 此段脚本实现了从当前视角位置逐步演化到垂直向上指向的状态变化过程,并且整个动作会在三秒钟之内平稳结束。 当涉及到屏幕物理坐标系发生转换的情形下,则需额外注意宽高参数可能随之变动的问题;例如设备由横屏切换成竖屏模式或是相反操作之后,某些 UI 元素的实际呈现区域也许会受到影响而变得不再合适,这时应该考虑重置这些受影响部件的新尺寸规格以确保界面美观性和功能性不受损害[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值