android 横竖屏调整分析
来源:互联网 发布:淘宝找同款货源插件 编辑:程序博客网 时间:2024/05/23 13:18
屏幕横竖屏切换的设置是在packages/apps/Settings下的DisplaySettings.java中定义的,代码如下:
在frameworks/base/policy/src/com/android/internal/policy/impl/phonewindowmanager.java中,定义了一个Observer,用来观察Setting数据库的改动,代码如下:
mFancyRotationAnimation);的实现类是windowmanagerservice.java:
到这里,屏幕的横竖屏切换大概就分析完了,如有错误疏漏的地方敬请指正!
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { if (preference == mAccelerometer) { Settings.System.putInt(getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, mAccelerometer.isChecked() ? 1 : 0); } else if (preference instanceof PreferenceScreen) { final String key = preference.getKey(); if (KEY_SENSORLEVELCALIBRATION.equals(key)) { Intent intent = new Intent(this, SensorLevelCalibration.class); startActivity(intent); } } return true; }通过跟踪代码,发现最后跑到了frameworks/base/core/java/android/provider/settings.java中,代码如下:
protected static boolean putString(ContentResolver resolver, Uri uri, String name, String value) { // The database will take care of replacing duplicates. try { ContentValues values = new ContentValues(); values.put(NAME, name); values.put(VALUE, value); resolver.insert(uri, values); return true; } catch (SQLException e) { Log.w(TAG, "Can't set key " + name + " in " + uri, e); return false; } }即将值插入到了setting的数据库中,开关设置到这里就算完成了,下面来分析后续的动作。
在frameworks/base/policy/src/com/android/internal/policy/impl/phonewindowmanager.java中,定义了一个Observer,用来观察Setting数据库的改动,代码如下:
class SettingsObserver extends ContentObserver { SettingsObserver(Handler handler) { super(handler); } //设置观察对象 void observe() { ContentResolver resolver = mContext.getContentResolver(); resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.END_BUTTON_BEHAVIOR), false, this); resolver.registerContentObserver(Settings.Secure.getUriFor( Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR), false, this); resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.ACCELEROMETER_ROTATION), false, this); resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.SCREEN_OFF_TIMEOUT), false, this); resolver.registerContentObserver(Settings.System.getUriFor( Settings.System.POINTER_LOCATION), false, this); resolver.registerContentObserver(Settings.Secure.getUriFor( Settings.Secure.DEFAULT_INPUT_METHOD), false, this); resolver.registerContentObserver(Settings.System.getUriFor( "fancy_rotation_anim"), false, this); updateSettings(); } //当观察对象改变时,回调 @Override public void onChange(boolean selfChange) { updateSettings(); try { mWindowManager.setRotation(USE_LAST_ROTATION, false, mFancyRotationAnimation); } catch (RemoteException e) { // Ignore } } }从上面代码可以看出,当setting数据库中被注册了的几个值发生改变时,就会调用onChange()函数,下面先分析updateSettings():
public void updateSettings() { ContentResolver resolver = mContext.getContentResolver(); . . int accelerometerDefault = Settings.System.getInt(resolver, Settings.System.ACCELEROMETER_ROTATION, DEFAULT_ACCELEROMETER_ROTATION); if (mAccelerometerDefault != accelerometerDefault) { mAccelerometerDefault = accelerometerDefault; updateOrientationListenerLp(); //进行更改 } . . } void updateOrientationListenerLp() { if (!mOrientationListener.canDetectOrientation()) { // If sensor is turned off or nonexistent for some reason return; } //Could have been invoked due to screen turning on or off or //change of the currently visible window's orientation if (localLOGV) Log.v(TAG, "Screen status="+mScreenOn+ ", current orientation="+mCurrentAppOrientation+ ", SensorEnabled="+mOrientationSensorEnabled); boolean disable = true; if (mScreenOn) { //当屏幕是开启状态时,才能进行屏幕旋转 if (needSensorRunningLp()) { //根据当前sensor的反馈信息和当前屏幕状态检查是否需要循环转屏幕 disable = false; //enable listener if not already enabled if (!mOrientationSensorEnabled) { //如果mOrientationListener状态是disable的 mOrientationListener.enable(); if(localLOGV) Log.v(TAG, "Enabling listeners"); mOrientationSensorEnabled = true; } } } }mOrientationListener.enable()的实现方法在frameworks/base/core/java/android/view/windoworientationlistener.java中:
public void enable() { if (mSensor == null) { Log.w(TAG, "Cannot detect sensors. Not enabled"); return; } if (mEnabled == false) { if (localLOGV) Log.d(TAG, "WindowOrientationListener enabled"); mSensorManager.registerListener(mSensorEventListener, mSensor, mRate); mEnabled = true; } }
可以看到,在enable()方法中,在mSensorManager中注册了一个mSensorEventListener,下面就要分析下在mSensorEventListener中做了什么事情,mSensorEventListener是SensorEventListenerImpl的一个对象,在SensorEventListenerImpl的实现中,其实现了onSensorChanged()方法,这个方法就是当传感器发生数据变化时接收数据,并进行计算的地方了。
下面再继续分析Observer的onChange()方法:mWindowManager.setRotation(USE_LAST_ROTATION, false,mFancyRotationAnimation);的实现类是windowmanagerservice.java:
public void setRotation(int rotation, boolean alwaysSendConfiguration, int animFlags) { if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION, "setRotation()")) { throw new SecurityException("Requires SET_ORIENTATION permission"); } setRotationUnchecked(rotation, alwaysSendConfiguration, animFlags); }继续跟进:
public void setRotationUnchecked(int rotation, boolean alwaysSendConfiguration, int animFlags) { if(DEBUG_ORIENTATION) Slog.v(TAG, "alwaysSendConfiguration set to "+alwaysSendConfiguration); long origId = Binder.clearCallingIdentity(); boolean changed; synchronized(mWindowMap) { changed = setRotationUncheckedLocked(rotation, animFlags); // } if (changed || alwaysSendConfiguration) { sendNewConfiguration(); } Binder.restoreCallingIdentity(origId); }setRotationUncheckedLocked()的官方说法是:Apply a new rotation to the screen, respecting the requests of applications. Use WindowManagerPolicy.USE_LAST_ROTATION to simply re-evaluate the desired rotation.大概就是重新计算要旋转的方向吧。下一步如果要旋转的话,则调用sendNewConfiguration():
void sendNewConfiguration() { try { mActivityManager.updateConfiguration(null); } catch (RemoteException e) { } }即通知窗口管理器要重画窗口了,后续的就是一个Activity的oncreate()等一系列过程。
到这里,屏幕的横竖屏切换大概就分析完了,如有错误疏漏的地方敬请指正!
- android 横竖屏调整分析
- Android使用SurfaceView播放视频时横竖屏的调整
- Android使用SurfaceView播放视频时横竖屏的调整
- Android 播放视频时横竖屏的调整
- Android 横竖屏切换问题分析
- 横竖屏切换SurfaceView 大小的调整
- 源码DisplaySettings分析android横竖屏切换的开关
- android横竖屏问题
- Android横竖屏总结
- android 横竖屏
- android横竖屏总结
- Android 横竖屏切换
- Android横竖屏'切换
- Android中的横竖屏
- Android横竖屏相关
- android 横竖屏
- android横竖屏总结
- Android横竖屏切换
- 【xinfanqie】教你如何在双系统下简单卸载win8
- K2BPM系列:浅识K2 blackpearl中SmartObject
- java中文乱码解决方法
- 进程和线程
- 让Editplus支持sql语法高亮显示 sql.stx
- android 横竖屏调整分析
- ExtJs 增删改查
- WdatePicker日历控件使用方法
- ACE_Message_Block功能
- tableLayoutPanel 循环添加的控件,不闪屏的方法;
- 转载:C语言do-while语句的用法
- AppFuse代码生成器(AMP)
- Oracle游标使用全解
- C# 串行化与反串行化