平台:qcom msm8953 android7.1

现象:客户app或者应用商城下载的app在我们自己的Android板上运行是,会出现反方向显示的情况,如系统方向是90°,运行某些app,app打开后会是270°的方向。

 

解决方法:

思路1:理清AndroidGUI系统显示框架,刚开始从底层想去理清AndroidGUI系统显示框架,结果越看涉及的知识越来愈多,最后看的头脑一点都不清醒了,越看越糊涂,更别说解决这个bug了。于是开始转向思路2;

思路2:之前有了解过Android系统屏幕旋转是基于WMS和PMS的,另外,做过一段时间的Android应用开发,知道在Android应用中是可以通过xml去设置应用显示的方向的,于是结合这两点,开始往这方面靠。

 

首先找到一篇文章https://blog.csdn.net/jinzhuojun/article/details/50085491,大家可以结合这个阅读下源码,我在PMS,和WMS中分别加了点打印,然后抓取打开会出现问题的app,找到了一些信息,发现 在我打开app的时候产生屏幕旋转的现象在WMS中会进入

updateRotationUncheckedLocked这个方法,紧接着在这个方法中,我发现在该方法中运行到如图所示的时候,对屏幕方向进行了修改

那么看到这里图中第一句赋值语句中的右值的值是从何而来呢?往上跟踪源码发现,是经过rotationForOrientationLw这个方法而来,那这个方法在哪定义和实现的呢?继续跟踪可以看到是mPolicy中的一个方法,那么继续找到何处继承了这个代理类,最终跟踪到PMS中找到了该方法的实现。

 @Override    public int rotationForOrientationLw(int orientation, int lastRotation) {        if (true) {            Slog.v(TAG, "rotationForOrientationLw(orient="                    + orientation + ", last=" + lastRotation                    + "); user=" + mUserRotation + " "                    + ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED)                    ? "USER_ROTATION_LOCKED" : "")            );        }        .......            if (DEBUG_LAYOUT) Slog.i(TAG, "orientation: " + orientation);            if (getScreenWidth(mContext) < getScreenHeight(mContext)) {  //Determine the physical screen direction                Slog.v(TAG, "width < height");                switch (lastRotation) //Make the app direction follow system                {                    case Surface.ROTATION_0:                        mPortraitRotation = Surface.ROTATION_0;  //shu  portrait                        mUpsideDownRotation = Surface.ROTATION_180; // fan shu                        mLandscapeRotation = Surface.ROTATION_90; // heng  landscape                        mSeascapeRotation = Surface.ROTATION_270; //fan heng                        break;                    case Surface.ROTATION_90:                        mPortraitRotation = Surface.ROTATION_90;  //shu  portrait                        mUpsideDownRotation = Surface.ROTATION_270; // fan shu                        mLandscapeRotation = Surface.ROTATION_0; // heng  landscape                        mSeascapeRotation = Surface.ROTATION_180; //fan heng                        break;                    case Surface.ROTATION_180:                        mPortraitRotation = Surface.ROTATION_180;  //shu  portrait                        mUpsideDownRotation = Surface.ROTATION_0; // fan shu                        mLandscapeRotation = Surface.ROTATION_270; // heng  landscape                        mSeascapeRotation = Surface.ROTATION_90; //fan heng                        break;                    case Surface.ROTATION_270:                        mPortraitRotation = Surface.ROTATION_270;  //shu  portrait                        mUpsideDownRotation = Surface.ROTATION_90; // fan shu                        mLandscapeRotation = Surface.ROTATION_180; // heng  landscape                        mSeascapeRotation = Surface.ROTATION_0; //fan heng                        break;                }            } else {                Slog.v(TAG, "width > height");                switch (lastRotation)//Make the app direction follow system                {                    case Surface.ROTATION_0:                        mPortraitRotation = Surface.ROTATION_0;  //shu  portrait                        mUpsideDownRotation = Surface.ROTATION_180; // fan shu                        mLandscapeRotation = Surface.ROTATION_90; // heng  landscape                        mSeascapeRotation = Surface.ROTATION_270; //fan heng                        break;                    case Surface.ROTATION_90:                        mPortraitRotation = Surface.ROTATION_90;  //shu  portrait                        mUpsideDownRotation = Surface.ROTATION_270; // fan shu                        mLandscapeRotation = Surface.ROTATION_0; // heng  landscape                        mSeascapeRotation = Surface.ROTATION_180; //fan heng                        break;                    case Surface.ROTATION_180:                        mPortraitRotation = Surface.ROTATION_180;  //shu  portrait                        mUpsideDownRotation = Surface.ROTATION_0; // fan shu                        mLandscapeRotation = Surface.ROTATION_270; // heng  landscape                        mSeascapeRotation = Surface.ROTATION_90; //fan heng                        break;                    case Surface.ROTATION_270:                        mPortraitRotation = Surface.ROTATION_270;                        mUpsideDownRotation = Surface.ROTATION_90;                        mLandscapeRotation = Surface.ROTATION_180;                        mSeascapeRotation = Surface.ROTATION_0;                        break;                }            }            switch (orientation) {                case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:  //portrait                    // Return portrait unless overridden.                    if (isAnyPortrait(preferredRotation)) {                        Slog.v(TAG, "preferredRotation:" + preferredRotation);                        return preferredRotation;                    }                    Slog.v(TAG, "mPortraitRotation:" + mPortraitRotation);                    return mPortraitRotation;                case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE: //landscape                    // Return landscape unless overridden.                    if (isLandscapeOrSeascape(preferredRotation)) {                        return preferredRotation;                    }                    return mLandscapeRotation;                case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT: //reversePortrait >= api 9                    // Return reverse portrait unless overridden.                    if (isAnyPortrait(preferredRotation)) {                        return preferredRotation;                    }                    return mUpsideDownRotation;                case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE: //reverseLandscape >= api 9                    // Return seascape unless overridden.                    if (isLandscapeOrSeascape(preferredRotation)) {                        return preferredRotation;                    }                    return mSeascapeRotation;                case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:                case ActivityInfo.SCREEN_ORIENTATION_USER_LANDSCAPE:                    // Return either landscape rotation.                    if (isLandscapeOrSeascape(preferredRotation)) {                        return preferredRotation;                    }                    if (isLandscapeOrSeascape(lastRotation)) {                        return lastRotation;                    }                    return mLandscapeRotation;                case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:                case ActivityInfo.SCREEN_ORIENTATION_USER_PORTRAIT:                    // Return either portrait rotation.                    if (isAnyPortrait(preferredRotation)) {                        return preferredRotation;                    }                    if (isAnyPortrait(lastRotation)) {                        return lastRotation;                    }                    return mPortraitRotation;                default:                    // For USER, UNSPECIFIED, NOSENSOR, SENSOR and FULL_SENSOR,                    // just return the preferred orientation we already calculated.                    if (preferredRotation >= 0) {                        return preferredRotation;                    }                    //return Surface.ROTATION_0;                    return mDefaultOrientation;            }        }    }

代码略长,省略部分,只看重点,在这个方法中添加一些打印发现,这里正是对app 通过设置xml配置屏幕方向的一些分类情况处理,我们可以看到图中 switch (orientation) 处,这里分别对应了应用层的一些设置,如:“portrait”,"landscape"等,

那么分析到这里,我想是不是可以在这个分类处理之前做些处理,让app跟随系统方向,于是进行了标红处的代码添加,最终运行测试,OK,测试通过!!

 

PS:  横屏好像还有点问题,后面再细查。

PMS:frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java

WMS:frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java

更多相关文章

  1. Android(安卓)为何比 iOS 卡?
  2. 更新操作系统Google 修正 Android(安卓)碎片化新法:多更新组件少
  3. Android异步消息处理机制完全解析,带你从源码的角度彻底理解
  4. 安卓自定义相机,使用系统相机教程源码都有
  5. 处女男学Android(三)---Handler简介以及初步应用
  6. Android(安卓)来电(包括铃声),短信拦截的实现方法
  7. IPv6升级测试指南(Android/iOS/Mac)
  8. 从零开始--系统深入学习android(实践-让我们开始写代码-Android框
  9. Android(安卓)BSP成长计划随笔之虚拟设备搭建和input系统

随机推荐

  1. Android(安卓)sqlite 数据库操作
  2. Android图片下载缓存库picasso解析
  3. android webview
  4. Android之SDK、NDK、JNI和so文件
  5. Android(安卓)Studio中图片的格式转换
  6. Android之ProGuard混淆器
  7. 【Android】android studio ndk使用例子
  8. Android(安卓)Studio中src/main/res/valu
  9. 2018/8/13
  10. Android(安卓)日历提供器(二)