当前位置: 首页 > news >正文

Android屏幕旋转流程(1)

(1)Gsensor的注册和监听

App -->I2C过程:App通过SensorManager.getSystemServer调用到SystemSensorManager,SystemSensorManager通过jni调用到SensorManager.cpp,后通过binder调用到SensorService。SensorService通过SystemServer启动,后调用到hal kernel。

I2C -->App过程:通过JNI调用到SystemSensorManager中的SensorEventQueue.dispatchSensorEvent,然后通过App向SensorEventQueue注册的mListener,来回调数据到App的onSensorChanged()方法。

(网图)
在这里插入图片描述

//frameworks/base/core/java/android/hardware/SensorManager.javapublic boolean registerListener(SensorEventListener listener, Sensor sensor,int samplingPeriodUs) {return registerListener(listener, sensor, samplingPeriodUs, null);}public boolean registerListener(SensorEventListener listener, Sensor sensor,int samplingPeriodUs, int maxReportLatencyUs) {int delay = getDelay(samplingPeriodUs);return registerListenerImpl(listener, sensor, delay, null, maxReportLatencyUs, 0);}public boolean registerListener(SensorEventListener listener, Sensor sensor,int samplingPeriodUs, Handler handler) {int delay = getDelay(samplingPeriodUs);return registerListenerImpl(listener, sensor, delay, handler, 0, 0);}public boolean registerListener(SensorEventListener listener, Sensor sensor,int samplingPeriodUs, int maxReportLatencyUs, Handler handler) {int delayUs = getDelay(samplingPeriodUs);return registerListenerImpl(listener, sensor, delayUs, handler, maxReportLatencyUs, 0);}/** @hide */
protected abstract boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,int delayUs, Handler handler, int maxReportLatencyUs, int reservedFlags);

registerListenerImpl的具体实现如下:

//frameworks/base/core/java/android/hardware/SystemSensorManager.javapublic class SystemSensorManager extends SensorManager {protected boolean registerListenerImpl(SensorEventListener listener, Sensor sensor,int delayUs, Handler handler, int maxBatchReportLatencyUs, int reservedFlags) {//...synchronized (mSensorListeners) {SensorEventQueue queue = mSensorListeners.get(listener);if (queue == null) {Looper looper = (handler != null) ? handler.getLooper() : mMainLooper;final String fullClassName =listener.getClass().getEnclosingClass() != null? listener.getClass().getEnclosingClass().getName(): listener.getClass().getName();//这里创建SensorEventQueue,并调用addSensor进而调用addSensorEvent函数queue = new SensorEventQueue(listener, looper, this, fullClassName);if (!queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs)) {queue.dispose();return false;}mSensorListeners.put(listener, queue);return true;} else {return queue.addSensor(sensor, delayUs, maxBatchReportLatencyUs);}}}
}

接下来我们看一下SensorEventQueue队列

static final class SensorEventQueue extends BaseEventQueue {private final SensorEventListener mListener;private final SparseArray<SensorEvent> mSensorsEvents = new SparseArray<SensorEvent>();public SensorEventQueue(SensorEventListener listener, Looper looper,SystemSensorManager manager, String packageName) {super(looper, manager, OPERATING_MODE_NORMAL, packageName);//App传过来的监听器进行赋值mListener = listener;}@Overridepublic void addSensorEvent(Sensor sensor) {SensorEvent t = new SensorEvent(Sensor.getMaxLengthValuesArray(sensor,mManager.mTargetSdkLevel));synchronized (mSensorsEvents) {mSensorsEvents.put(sensor.getHandle(), t);}}@Overridepublic void removeSensorEvent(Sensor sensor) {synchronized (mSensorsEvents) {mSensorsEvents.delete(sensor.getHandle());}}// Called from native code.@SuppressWarnings("unused")@Override//在addSensorEvent put事件后,通过mSensorsEvents.get获取事件,然后通过mListener分发,这里的mListener就是App传过来的监听接口protected void dispatchSensorEvent(int handle, float[] values, int inAccuracy,long timestamp) {final Sensor sensor = mManager.mHandleToSensor.get(handle);if (sensor == null) {// sensor disconnectedreturn;}SensorEvent t = null;synchronized (mSensorsEvents) {t = mSensorsEvents.get(handle);}//...//这里会回调注册过的监听器的onSensorChangedmListener.onSensorChanged(t);}}

后续文章所提及的屏幕旋转方向等都和这里事件分发相关。

(2)应用注册屏幕旋转事件监听

应用注册使用,通过enable和disable来控制注册和取消注册

private class OrientationEventListenerImpl extends OrientationEventListener {public OrientationEventListenerImpl(Context context) {super(context);}@Overridepublic void onOrientationChanged(int orientation) {if (orientation == ORIENTATION_UNKNOWN) {return;}//...}}mOrientationListener.enable();
mOrientationListener.disable();

如下为系统代码

//frameworks/base/core/java/android/view/OrientationEventListener.javapublic abstract class OrientationEventListener {public OrientationEventListener(Context context) {this(context, SensorManager.SENSOR_DELAY_NORMAL);}public OrientationEventListener(Context context, int rate) {mSensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);mRate = rate;mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);if (mSensor != null) {// Create listener only if sensors do existmSensorEventListener = new SensorEventListenerImpl();}}public void enable() {if (mSensor == null) {Log.w(TAG, "Cannot detect sensors. Not enabled");return;}if (mEnabled == false) {if (localLOGV) Log.d(TAG, "OrientationEventListener enabled");mSensorManager.registerListener(mSensorEventListener, mSensor, mRate);mEnabled = true;}}public void disable() {if (mSensor == null) {Log.w(TAG, "Cannot detect sensors. Invalid disable");return;}if (mEnabled == true) {if (localLOGV) Log.d(TAG, "OrientationEventListener disabled");mSensorManager.unregisterListener(mSensorEventListener);mEnabled = false;}}class SensorEventListenerImpl implements SensorEventListener {private static final int _DATA_X = 0;private static final int _DATA_Y = 1;private static final int _DATA_Z = 2;public void onSensorChanged(SensorEvent event) {float[] values = event.values;int orientation = ORIENTATION_UNKNOWN;float X = -values[_DATA_X];float Y = -values[_DATA_Y];float Z = -values[_DATA_Z];        float magnitude = X*X + Y*Y;// Don't trust the angle if the magnitude is small compared to the y valueif (magnitude * 4 >= Z*Z) {float OneEightyOverPi = 57.29577957855f;float angle = (float)Math.atan2(-Y, X) * OneEightyOverPi;orientation = 90 - (int)Math.round(angle);// normalize to 0 - 359 rangewhile (orientation >= 360) {orientation -= 360;} while (orientation < 0) {orientation += 360;}}if (mOldListener != null) {mOldListener.onSensorChanged(Sensor.TYPE_ACCELEROMETER, event.values);}if (orientation != mOrientation) {mOrientation = orientation;//回调函数onOrientationChanged(orientation);}}//回调函数public void onAccuracyChanged(Sensor sensor, int accuracy) {}}
}
http://www.lryc.cn/news/373349.html

相关文章:

  • JS常见的运算符有哪些?
  • 【scikit-learn入门指南】:机器学习从零开始
  • MEMS:Lecture 17 Noise MDS
  • Windows运维:找到指定端口的服务
  • Linux文件系统讲解!
  • mysql集群,两主两从,使用mysql-proxy实现读写分离
  • Linux文本处理三剑客+正则表达式
  • Linux启动KKfileview文件在线浏览时报错:启动office组件失败,请检查office组件是否可用
  • React <> </>的用法
  • is not null 、StringUtils.isNotEmpty和StringUtils.isNotBlank之间的区别?
  • Git使用-gitlab上面的项目如何整到本地的idea中
  • 活体检验API在Java、Python、PHP中的使用教程
  • 智能计算系统-概述
  • SM5101 SOP-8 充电+触摸+发执丝控制多合一IC触摸打火机专用IC
  • Mysql-题目02
  • Swift开发——循环执行方式
  • Navicat和SQLynx产品功能比较一(整体比较)
  • pip 配置缓存路径
  • 大数据开发语言Scala(一) - Scala入门
  • 大模型中的计算精度——FP32, FP16, bfp16之类的都是什么???
  • 在矩池云使用GLM-4的详细指南(无感连GitHubHuggingFace)
  • 大模型日报2024-06-15
  • 【YOLO系列】YOLOv1学习(PyTorch)原理加代码
  • Postman接口测试工具详解:揭秘API测试的终极利器
  • 紫光展锐5G处理器T750__国产手机芯片5G方案
  • 基于深度学习的红外船舶检测识别分类完整实现数据集8000+张
  • SpringCloud跨服务远程调用
  • postgres常用查询
  • JavaFX应用
  • axios打通fastapi和vue,实现前后端分类项目开发