MTK camera 4.2 app PreferenceGroup生成过程(2013/8)

前言

Camera APP的系统设置模块是经过精心设计的一套流程。 
该套流程在初次接触的过程中会感觉有些复杂,在此对其初始化的过程进行分析。

入口

void com.android.camera.Camera.initializeCameraPreferences() 
该方法最终生成一个PreferenceGroup对象,保存在com.android.camera.Camera的属性mPreferenceGroup中。

调用位置

Referenced by com.android.camera.Camera.CameraStartUpThread.run(). 
在每次对硬件Camera打开后调用。

相关类及方法

preferences的初始化过程涉及到对以下类进行初始化

  1. PreferenceGroup
  2. ListPrefernece(IconListPreference)
  3. ComboPreferences
  4. SettingChecker
下图中列出了被初始化的属性,类及类间相互调用的方法。

了解上述类

这一节对上述类中的属性进行介绍。所谓初始化就是对这些属性初始化。

CameraPreference

抽象类,定义了接口OnPreferenceChangedListener,定义了方法getSharedPreferences(),该方法通过调用ComboPreferences.get()取得SharedPreferences。

PreferenceGroup

继承自CameraPreference。定义了属性ArrayList<CameraPreference> list。定义了方法findPreference(key)用于从list中取得key对应的ListPreference,该方法可以从PreferenceGroup中通过递归获得ListPreference

ListPreference


承自CameraPreference。理解ListPreference是了解整个初始化过程的关键。

  • 定义了三组entries,entryValues数组。


这三组数组的关系,用集合表示如下图 


与这三组数组相关方法及转换过程如下图


  • getValue()

通过getSharedPreferences()取得key value;(ComboPreferences)

  • proetected persistStringValue()

该方法封装在setValue()中,负责写入key value(ComboPreferences)

IconListPreference

继承自ListPreference,为每个属性增加了图标,增加了对图标的操作。该类及子类此处不做深入了解。初始化过程参照ListPreference

ComboPreferences

保存APP自定义的global,local SharedPreferences

SettingChecker

SettingChecker控制setting界面中选项的位置,状态。 
定义了一张表mListPrefs[],表中条目为setting界面的选项。

初始化过程


Camera_preferences.xml

定义了PreferenceGroup,其中的成员是ListPreference,IconListPreference。 
每个成员定义了defaultValue,entries,entryValues,icons,key,title

CameraSetting.getPreferenceGroup()

该方法通过PreferenceInflater对象的inflate方法, 解析Camera_preferences.xml文件,将CameraPreference,ListPreference,IconListPreference通过反射机制生成具体对象。

CameraSettings.initPreference()

作用
初始化SettingChecker.mListPrefs[]。使得PreferenceGroup中每一个ListPreferene都映射mListPrefs中一项。 
最终结果如下图

过程

多数设置项的处理流程相似,只是某些项想有单独的处理方式。把握住上面的Entries关系图就能基本清楚。

  1. 先通过settingChecker.clearListPreference()清空该数组。
  2. 不需要进行supported检查的pref,通过settingChecker.setListPreference(int row, ListPreference pref);将PreferenceGroup.list[]中保存的引用赋值给mListPrefs[]。
  3. 需要进行检查的pref,调用filterUnsupportedOptions(),mParameters.getSupportedXXX(),ListPreferene.filterUnsupported(),将mOriginalEntries,mOriginalEntryValues中supported的值保存到mEntries,mEntryValues,mOriginalSupportedEntries,mOriginalSupportedEntryValues。参见上面Entries关系图。最后将将PreferenceGroup.list[]中保存的引用赋值给mListPrefs[]。
  4. 上一步中,如果mOriginalSupportedEntries是空串,则调用removePreference(),将该pref从PreferenceGroup中移除(group.removePreference(i);),将mListPrefs这一项的值设为null(CameraSetting.removePreference(int row))
其他情况
  • 录像的品质是MTK自己设定的,所以使用getMTKSupportedVideoQuality()替代mParameters.getSupportedXXX()
  • filter picture size 会先根据mParameters.getSupportedPictureSizes(),再根据pictureRatio构建出的supportedForRatio,前后两次来设置ListPreference。两次filter的流程与基本流程一致。
  • FeatureSwitcher.isXXXenabled()是MTK用来标记某些功能是否打开。

SettingChecker.filterUnsuportedPreference()

源代码中注释:

       //CameraSetting.initPreference() will filter some preference according to native Parameter
       //Unluckily, not all item are set by camera server, here we correct these lost items.

这段注释描述了CameraSetting.initPreference()的作用,也表示filterUnsuportedPreference()是对其补充。 
该方法根据二维静态数组static SettingChecker.MATRIX_SETTING_VISIBLE[][](前后摄像头各一个维度),决定该pref是否显示出来。如果不显示,则将该pref从PreferenceGroup,SettingChecker.mListPrefs[]中移除。

初始化结束

发送消息MSG_CAMERA_PREFERENCE_READY,notifyPreferenceReady()让监听者更新与preference相关的属性.

设计


  public ComboPreferences getPreferences() { //not recommended
       return mPreferences;
   }
   
   public PreferenceGroup getPreferenceGroup() { //not recommended
       return mPreferenceGroup;
   }
   
   public ListPreference getListPreference(int row) {
       return mSettingChecker.getListPreference(row);
   }
  • 附上的源代码可以看到,直接获取ComboPreferences,PreferenceGroup 是不被推荐的,mSettingChecker是获得ListPreference,修改Preference的接口。
  • ListPreference中的getValue(),setValue()可以保证ListPreference,ComboPreferences同时更新。
  • 源码中只有SettingChecker会调用getPreferences()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值