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()方法。

(网图)

java 复制代码
//frameworks/base/core/java/android/hardware/SensorManager.java

public 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的具体实现如下:

java 复制代码
//frameworks/base/core/java/android/hardware/SystemSensorManager.java

public 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队列

java 复制代码
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;
        }

        @Override
        public void addSensorEvent(Sensor sensor) {
            SensorEvent t = new SensorEvent(Sensor.getMaxLengthValuesArray(sensor,
                    mManager.mTargetSdkLevel));
            synchronized (mSensorsEvents) {
                mSensorsEvents.put(sensor.getHandle(), t);
            }
        }

        @Override
        public 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 disconnected
                return;
            }

            SensorEvent t = null;
            synchronized (mSensorsEvents) {
                t = mSensorsEvents.get(handle);
            }

            //...
			//这里会回调注册过的监听器的onSensorChanged
            mListener.onSensorChanged(t);
        }
    }

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

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

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

java 复制代码
private class OrientationEventListenerImpl extends OrientationEventListener {
        public OrientationEventListenerImpl(Context context) {
            super(context);
        }

        @Override
        public void onOrientationChanged(int orientation) {
            if (orientation == ORIENTATION_UNKNOWN) {
                return;
            }
            //...
        }
    }

mOrientationListener.enable();
mOrientationListener.disable();

如下为系统代码

java 复制代码
//frameworks/base/core/java/android/view/OrientationEventListener.java

public 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 exist
            mSensorEventListener = 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 value
            if (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 range
                while (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) {

        }
    }
}
相关推荐
seven27291 年前
android设置竖屏仍然跟随屏幕旋转怎么办
android·屏幕旋转