3、菜单的监听事件
当菜单被点击时,菜单的监听事件就会监听到该事件,并作出相应的处理。监听事件定义在文件Packages/apps/camera/src/com/android/camera/Camera.java中。其具体定义为:
private class MyHeadUpDisplayListener implements HeadUpDisplay.Listener {
// The callback functions here will be called from the GLThread. So,
// we need to post these runnables to the main thread
public void onSharedPreferencesChanged() {
mHandler.post(new Runnable() {
public void run() {
Camera.this.onSharedPreferenceChanged();
}
});
}
public void onRestorePreferencesClicked() {
mHandler.post(new Runnable() {
public void run() {
Camera.this.onRestorePreferencesClicked();
}
});
}
public void onPopupWindowVisibilityChanged(int visibility) {
}
}
函数onSharedPreferenceChanged()定义为:
private void onSharedPreferenceChanged() {
// ignore the events after "onPause()"
if (mPausing) return;
boolean recordLocation;
synchronized (mPreferences) {
recordLocation = RecordLocationPreference.get(
mPreferences, getContentResolver());
mQuickCapture = getQuickCaptureSettings();
}
if (mRecordLocation != recordLocation) {
mRecordLocation = recordLocation;
if (mRecordLocation) {
startReceivingLocationUpdates();
} else {
stopReceivingLocationUpdates();
}
}
setCameraParametersWhenIdle(UPDATE_PARAM_PREFERENCE);
}
其中函数setCameraParametersWhenIdle()定义为:
// If the Camera is idle, update the parameters immediately, otherwise
// accumulate them in mUpdateSet and update later.
private void setCameraParametersWhenIdle(int additionalUpdateSet) {
mUpdateSet |= additionalUpdateSet;
if (mCameraDevice == null) {
// We will update all the parameters when we open the device, so
// we don't need to do anything now.
mUpdateSet = 0;
return;
} else if (isCameraIdle()) {
setCameraParameters(mUpdateSet);
mUpdateSet = 0;
} else {
if (!mHandler.hasMessages(SET_CAMERA_PARAMETERS_WHEN_IDLE)) {
mHandler.sendEmptyMessageDelayed(
SET_CAMERA_PARAMETERS_WHEN_IDLE, 1000);
}
}
}
函数setCameraParameters()定义为:
// We separate the parameters into several subsets, so we can update only
// the subsets actually need updating. The PREFERENCE set needs extra
// locking because the preference can be changed from GLThread as well.
private void setCameraParameters(int updateSet) {
mParameters = mCameraDevice.getParameters();
if ((updateSet & UPDATE_PARAM_INITIALIZE) != 0) {
updateCameraParametersInitialize();
}
if ((updateSet & UPDATE_PARAM_ZOOM) != 0) {
updateCameraParametersZoom();
}
if ((updateSet & UPDATE_PARAM_PREFERENCE) != 0) {
synchronized (mPreferences) {
updateCameraParametersPreference();
}
}
mCameraDevice.setParameters(mParameters);
}
Picture大小的设置属于UPDATE_PARAM_PREFERENCE,所以会调到函数updateCameraParametersPreference(),其定义为:
private void updateCameraParametersPreference() {
// Set picture size.
String pictureSize = mPreferences.getString(
CameraSettings.KEY_PICTURE_SIZE, null);
if (pictureSize == null) {
CameraSettings.initialCameraPictureSize(this, mParameters);
} else {
List<Size> supported = mParameters.getSupportedPictureSizes();
CameraSettings.setCameraPictureSize(
pictureSize, supported, mParameters);
}
// Set the preview frame aspect ratio according to the picture size.
Size size = mParameters.getPictureSize();
PreviewFrameLayout frameLayout =
(PreviewFrameLayout) findViewById(R.id.frame_layout);
frameLayout.setAspectRatio((double) size.width / size.height);
// Set a preview size that is closest to the viewfinder height and has
// the right aspect ratio.
List<Size> sizes = mParameters.getSupportedPreviewSizes();
Size optimalSize = getOptimalPreviewSize(
sizes, (double) size.width / size.height);
if (optimalSize != null) {
mParameters.setPreviewSize(optimalSize.width, optimalSize.height);
}
……
}
函数CameraSettings.initialCameraPictureSize()的定义如下:
public static void initialCameraPictureSize(
Context context, Parameters parameters) {
// When launching the camera app first time, we will set the picture
// size to the first one in the list defined in "arrays.xml" and is also
// supported by the driver.
List<Size> supported = parameters.getSupportedPictureSizes();
if (supported == null) return;
for (String candidate : context.getResources().getStringArray(
R.array.pref_camera_picturesize_entryvalues)) {
if (setCameraPictureSize(candidate, supported, parameters)) {
SharedPreferences.Editor editor = PreferenceManager
.getDefaultSharedPreferences(context).edit();
editor.putString(KEY_PICTURE_SIZE, candidate);
editor.commit();
return;
}
}
Log.e(TAG, "No supported picture size found");
}
函数setCameraPictureSize()定义如下:
public static boolean setCameraPictureSize(
String candidate, List<Size> supported, Parameters parameters) {
int index = candidate.indexOf('x');
if (index == NOT_FOUND) return false;
int width = Integer.parseInt(candidate.substring(0, index));
int height = Integer.parseInt(candidate.substring(index + 1));
for (Size size: supported) {
if (size.width == width && size.height == height) {
parameters.setPictureSize(width, height);
return true;
}
}
return false;
}
监听事件中的onRestorePreferencesClicked()定义如下:
protected void onRestorePreferencesClicked() {
if (mPausing) return;
Runnable runnable = new Runnable() {
public void run() {
mHeadUpDisplay.restorePreferences(mParameters);
}
};
MenuHelper.confirmAction(this,
getString(R.string.confirm_restore_title),
getString(R.string.confirm_restore_message),
runnable);
}
其中restorePreferences()函数定义如下:
public void restorePreferences(final Parameters param) {
getGLRootView().runInGLThread(new Runnable() {
public void run() {
OnSharedPreferenceChangeListener l =
mSharedPreferenceChangeListener;
// Unregister the listener since "upgrade preference" will
// change bunch of preferences. We can handle them with one
// onSharedPreferencesChanged();
mSharedPrefs.unregisterOnSharedPreferenceChangeListener(l);
Context context = getGLRootView().getContext();
synchronized (mSharedPrefs) {
Editor editor = mSharedPrefs.edit();
editor.clear();
editor.commit();
}
CameraSettings.upgradePreferences(mSharedPrefs);
CameraSettings.initialCameraPictureSize(context, param);
reloadPreferences();
if (mListener != null) {
mListener.onSharedPreferencesChanged();
}
mSharedPrefs.registerOnSharedPreferenceChangeListener(l);
}
});
}
函数reloadPreferences()定义如下:
public void reloadPreferences() {
mPreferenceGroup.reloadValue();
mIndicatorBar.reloadPreferences();
}
}
4、小结
由于Camera应用程序比较复杂,其菜单的设置流程也是比较难以理解。这里我只是做了一个初步的小结,很多地方还不清楚,以备日后再做细化。