本章主要分析google settings里面存储模块的代码。

存储模块所在的fragment为:

[html] view plaincopy
  1. <!-- Storage -->
  2. <header
  3. android:id="@+id/storage_settings"
  4. android:fragment="com.android.settings.deviceinfo.Memory"
  5. android:icon="@drawable/ic_settings_storage"
  6. android:title="@string/storage_settings" />

我们现在看Memory这个类

[java] view plaincopy
  1. @Override
  2. public void onCreate(Bundle icicle) {
  3. super.onCreate(icicle);
  4. final Context context = getActivity();
  5. mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
  6. mStorageManager = StorageManager.from(context);
  7. mStorageManager.registerListener(mStorageListener);
  8. addPreferencesFromResource(R.xml.device_info_memory);
  9. addCategory(StorageVolumePreferenceCategory.buildForInternal(context));
  10. final StorageVolume[] storageVolumes = mStorageManager.getVolumeList();
  11. for (StorageVolume volume : storageVolumes) {
  12. if (!volume.isEmulated()) {
  13. addCategory(StorageVolumePreferenceCategory.buildForPhysical(context, volume));
  14. }
  15. }
  16. setHasOptionsMenu(true);
  17. }

在onCreate函数中,主要做了几件事情:

1.各种初始化

2.实例化布局,最主要是对Category的添加

3.获取当前挂载的volume,并且实例化为Category

Category最主要的是StorageVolumePreferenceCategory,构造函数如下:

[java] view plaincopy
  1. /**
  2. * Build category to summarize specific physical {@link StorageVolume}.
  3. */
  4. public static StorageVolumePreferenceCategory buildForPhysical(
  5. Context context, StorageVolume volume) {
  6. return new StorageVolumePreferenceCategory(context, volume);
  7. }
  8. private StorageVolumePreferenceCategory(Context context, StorageVolume volume) {
  9. super(context);
  10. mVolume = volume;
  11. mMeasure = StorageMeasurement.getInstance(context, volume);
  12. mResources = context.getResources();
  13. mStorageManager = StorageManager.from(context);
  14. mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
  15. setTitle(volume != null ? volume.getDescription(context)
  16. : context.getText(R.string.internal_storage));
  17. }

构造函数会被如下函数调用:

[java] view plaincopy
  1. /**
  2. * Build category to summarize internal storage, including any emulated
  3. * {@link StorageVolume}.
  4. */
  5. public static StorageVolumePreferenceCategory buildForInternal(Context context) {
  6. return new StorageVolumePreferenceCategory(context, null);
  7. }

到这里,主要是在Category里面做一些初始化,对于存储fragment最上面的“内部存储设备”text显示就是在构造函数中完成:

[java] view plaincopy
  1. setTitle(volume != null ? volume.getDescription(context)
  2. : context.getText(R.string.internal_storage));

对于外置设备Category的创建,主要是在:

[java] view plaincopy
  1. /**
  2. * Build category to summarize specific physical {@link StorageVolume}.
  3. */
  4. public static StorageVolumePreferenceCategory buildForPhysical(
  5. Context context, StorageVolume volume) {
  6. return new StorageVolumePreferenceCategory(context, volume);
  7. }

唯一的区别就是Volume是否为NULL。

创建Category后,主要是对preference的创建,主要是在init函数:

[java] view plaincopy
  1. public void init() {
  2. final Context context = getContext();
  3. removeAll();
  4. final UserInfo currentUser;
  5. try {
  6. currentUser = ActivityManagerNative.getDefault().getCurrentUser();
  7. } catch (RemoteException e) {
  8. throw new RuntimeException("Failed to get current user");
  9. }
  10. final List<UserInfo> otherUsers = getUsersExcluding(currentUser);
  11. final boolean showUsers = mVolume == null && otherUsers.size() > 0;
  12. mUsageBarPreference = new UsageBarPreference(context);
  13. mUsageBarPreference.setOrder(ORDER_USAGE_BAR);
  14. addPreference(mUsageBarPreference);
  15. mItemTotal = buildItem(R.string.memory_size, 0);
  16. mItemAvailable = buildItem(R.string.memory_available, R.color.memory_avail);
  17. addPreference(mItemTotal);
  18. addPreference(mItemAvailable);
  19. mItemApps = buildItem(R.string.memory_apps_usage, R.color.memory_apps_usage);
  20. mItemDcim = buildItem(R.string.memory_dcim_usage, R.color.memory_dcim);
  21. mItemMusic = buildItem(R.string.memory_music_usage, R.color.memory_music);
  22. mItemDownloads = buildItem(R.string.memory_downloads_usage, R.color.memory_downloads);
  23. mItemCache = buildItem(R.string.memory_media_cache_usage, R.color.memory_cache);
  24. mItemMisc = buildItem(R.string.memory_media_misc_usage, R.color.memory_misc);
  25. mItemCache.setKey(KEY_CACHE);
  26. final boolean showDetails = mVolume == null || mVolume.isPrimary();
  27. if (showDetails) {
  28. if (showUsers) {
  29. addPreference(new PreferenceHeader(context, currentUser.name));
  30. }
  31. addPreference(mItemApps);
  32. addPreference(mItemDcim);
  33. addPreference(mItemMusic);
  34. addPreference(mItemDownloads);
  35. addPreference(mItemCache);
  36. addPreference(mItemMisc);
  37. if (showUsers) {
  38. addPreference(new PreferenceHeader(context, R.string.storage_other_users));
  39. int count = 0;
  40. for (UserInfo info : otherUsers) {
  41. final int colorRes = count++ % 2 == 0 ? R.color.memory_user_light
  42. : R.color.memory_user_dark;
  43. final StorageItemPreference userPref = new StorageItemPreference(
  44. getContext(), info.name, colorRes, info.id);
  45. mItemUsers.add(userPref);
  46. addPreference(userPref);
  47. }
  48. }
  49. }
  50. final boolean isRemovable = mVolume != null ? mVolume.isRemovable() : false;
  51. // Always create the preference since many code rely on it existing
  52. mMountTogglePreference = new Preference(context);
  53. if (isRemovable) {
  54. mMountTogglePreference.setTitle(R.string.sd_eject);
  55. mMountTogglePreference.setSummary(R.string.sd_eject_summary);
  56. addPreference(mMountTogglePreference);
  57. }
  58. final boolean allowFormat = mVolume != null;
  59. if (allowFormat) {
  60. mFormatPreference = new Preference(context);
  61. mFormatPreference.setTitle(R.string.sd_format);
  62. mFormatPreference.setSummary(R.string.sd_format_summary);
  63. addPreference(mFormatPreference);
  64. }
  65. final IPackageManager pm = ActivityThread.getPackageManager();
  66. try {
  67. if (pm.isStorageLow()) {
  68. mStorageLow = new Preference(context);
  69. mStorageLow.setOrder(ORDER_STORAGE_LOW);
  70. mStorageLow.setTitle(R.string.storage_low_title);
  71. mStorageLow.setSummary(R.string.storage_low_summary);
  72. addPreference(mStorageLow);
  73. } else if (mStorageLow != null) {
  74. removePreference(mStorageLow);
  75. mStorageLow = null;
  76. }
  77. } catch (RemoteException e) {
  78. }
  79. }

对preference数据进行更新是在:

[java] view plaincopy
  1. public void updateApproximate(long totalSize, long availSize) {
  2. mItemTotal.setSummary(formatSize(totalSize));
  3. mItemAvailable.setSummary(formatSize(availSize));
  4. mTotalSize = totalSize;
  5. final long usedSize = totalSize - availSize;
  6. mUsageBarPreference.clear();
  7. mUsageBarPreference.addEntry(0, usedSize / (float) totalSize, android.graphics.Color.GRAY);
  8. mUsageBarPreference.commit();
  9. updatePreferencesFromState();
  10. }

当点击cache prefrence时,会弹出dialog,主要是在Memory.java中响应:

[java] view plaincopy
  1. public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
  2. if (StorageVolumePreferenceCategory.KEY_CACHE.equals(preference.getKey())) {
  3. ConfirmClearCacheFragment.show(this);
  4. return true;
  5. }

查看ConfirmClearCacheFragment的函数:

[java] view plaincopy
  1. @Override
  2. public Dialog onCreateDialog(Bundle savedInstanceState) {
  3. final Context context = getActivity();
  4. final AlertDialog.Builder builder = new AlertDialog.Builder(context);
  5. builder.setTitle(R.string.memory_clear_cache_title);
  6. builder.setMessage(getString(R.string.memory_clear_cache_message));
  7. builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
  8. @Override
  9. public void onClick(DialogInterface dialog, int which) {
  10. final Memory target = (Memory) getTargetFragment();
  11. final PackageManager pm = context.getPackageManager();
  12. final List<PackageInfo> infos = pm.getInstalledPackages(0);
  13. final ClearCacheObserver observer = new ClearCacheObserver(
  14. target, infos.size());
  15. for (PackageInfo info : infos) {
  16. pm.deleteApplicationCacheFiles(info.packageName, observer);
  17. }
  18. }
  19. });
  20. builder.setNegativeButton(android.R.string.cancel, null);
  21. return builder.create();
  22. }

会通过PackageManager获取所有安装apk,然后清除所有apk的缓存数据。

点击“卸载SD卡”,会弹出dialog,对应的代码为:

[java] view plaincopy
  1. private void unmount() {
  2. // Check if external media is in use.
  3. try {
  4. if (hasAppsAccessingStorage()) {
  5. // Present dialog to user
  6. showDialogInner(DLG_CONFIRM_UNMOUNT);
  7. } else {
  8. doUnmount();
  9. }
  10. } catch (RemoteException e) {
  11. // Very unlikely. But present an error dialog anyway
  12. Log.e(TAG, "Is MountService running?");
  13. showDialogInner(DLG_ERROR_UNMOUNT);
  14. }
  15. }
[java] view plaincopy
  1. @Override
  2. public Dialog onCreateDialog(int id) {
  3. switch (id) {
  4. case DLG_CONFIRM_UNMOUNT:
  5. return new AlertDialog.Builder(getActivity())
  6. .setTitle(R.string.dlg_confirm_unmount_title)
  7. .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
  8. public void onClick(DialogInterface dialog, int which) {
  9. doUnmount();
  10. }})
  11. .setNegativeButton(R.string.cancel, null)
  12. .setMessage(R.string.dlg_confirm_unmount_text)
  13. .create();
[java] view plaincopy
  1. private void doUnmount() {
  2. // Present a toast here
  3. Toast.makeText(getActivity(), R.string.unmount_inform_text, Toast.LENGTH_SHORT).show();
  4. IMountService mountService = getMountService();
  5. try {
  6. sLastClickedMountToggle.setEnabled(false);
  7. sLastClickedMountToggle.setTitle(getString(R.string.sd_ejecting_title));
  8. sLastClickedMountToggle.setSummary(getString(R.string.sd_ejecting_summary));
  9. mountService.unmountVolume(sClickedMountPoint, true, false);
  10. } catch (RemoteException e) {
  11. // Informative dialog to user that unmount failed.
  12. showDialogInner(DLG_ERROR_UNMOUNT);
  13. }
  14. }

原文地址:http://blog.csdn.net/zhudaozhuan/article/details/40621335

android settings源代码分析(3)相关推荐

  1. android settings源代码分析(2)

    通过前一篇文章  Android settings源代码分析(1)  分析,大概知道了Settings主页面是如何显示,今天主要分析"应用"这一块google是如何实现的. 应用对 ...

  2. android settings源代码分析(1)

    1.Android settings源码的source code路径为: kikat_4.4_CTS\packages\apps\Settings 2.settings主界面UI布局 Settings ...

  3. Android 消息处理源代码分析(1)

    Android 消息处理源代码分析(1) 在Android中,通常被使用的消息队列的代码在文件夹\sources\android-22\android\os下,涉及到下面几个类文件 Handler.j ...

  4. Github android客户端源代码分析之一:环境搭建

    1.下载相应的包及项目,参考https://github.com/github/android/wiki/Building-From-Eclipse. 2.若需查看某些包的源文件或者javadoc,则 ...

  5. Android深入源代码分析理解Aidl总体调用流程(雷惊风)

    2017年開始上班的第一天.老不想工作了,假期感觉还没開始就已经结束了,唉,时间就是这样,新的一年開始了,尽管非常不想干正事,没办法,必须干起来.由于后边的路还非常长,距离六十岁还非常远. 刚上班也没 ...

  6. android map有序存储,Android ArrayMap源代码分析

    分析源码之前先来介绍一下ArrayMap的存储结构,ArrayMap数据的存储不同于HashMap和SparseArray. Java提供了HashMap,但是HashMap对于手机端而言,对空间的利 ...

  7. android stk 源代码分析,Android源码分析--STK

    文件:StkAppService.java 函数:onCreate() STK的APP程序启动后执行的第一个函数,会调用方法: com.android.internal.telephony.gsm.s ...

  8. [Android]Volley源代码分析(店)应用

    通过前面的谈话,我相信你有Volley有了一定的了解了原理.本章将给出一些我们的应用程序都可以在样品中直接使用,第一样品是 NetworkImageView类,事实上NetworkImageView顾 ...

  9. android scrcpy 源代码分析,Scrcpy投屏原理浅析-设备控制篇

    起初我真的想过自己单独写一套来着,后来发现 Scrcpy与vysor是都是投屏中比较优秀的项目了,非侵入性,不需要设备单独 scrcpy启动阶段 它到底是怎么做到执行scrcpy命令,在较短的时间内就 ...

最新文章

  1. matlab 直方图_MATLAB作图实例:19:用二元直方图分析图片颜色
  2. 可视化神器背后的奥秘
  3. UESTC 电子科大专题训练 DP-N
  4. Java Server Page
  5. Linux BPF hello world C语言示例代码
  6. Android学习笔记---26_采用JSON格式返回数据给资讯客户端,效率上要高于xml文件解析和传输
  7. 将运行时地理数据库(*.geodatabase)复制到文件地理数据库
  8. 《数学之美》—贾里尼克和现代语言处理
  9. android源码上面开发App
  10. zookeeper 可以干什么
  11. 小程序服务器装rsshub,用RSSHub制作自己的RSS订阅源
  12. 如何建设网站步骤有哪些?
  13. 配置OSPF认证【eNSP实现】
  14. android画笔,Android自定义View系列之画笔(一)
  15. PAT A1010 Radix (25 分)
  16. 如何清空python的IDLE?
  17. 微信小程序——绘制折线图
  18. Module use of python36.dll conflicts with this version of Python
  19. [教程10]TensorFlow线性模型教程
  20. 程序员学炒股(4) 早晨十字星靠不靠谱

热门文章

  1. 英文Ubuntu安装中文包(locale)的方法
  2. volatile 关键字
  3. [多媒体]MKV 配音分离提取, 伴奏提取
  4. c++中的explicit关键字
  5. Go版本升级后编译出错:Load redeclared in this block
  6. Win10:tensorflow 学习笔记(1)
  7. extern C的用法解析
  8. linux切换root权限
  9. JVM学习01总体概述
  10. 云炬金融每日一题20211008