android settings源代码分析(3)
本章主要分析google settings里面存储模块的代码。
存储模块所在的fragment为:
- <!-- Storage -->
- <header
- android:id="@+id/storage_settings"
- android:fragment="com.android.settings.deviceinfo.Memory"
- android:icon="@drawable/ic_settings_storage"
- android:title="@string/storage_settings" />
我们现在看Memory这个类
- @Override
- public void onCreate(Bundle icicle) {
- super.onCreate(icicle);
- final Context context = getActivity();
- mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
- mStorageManager = StorageManager.from(context);
- mStorageManager.registerListener(mStorageListener);
- addPreferencesFromResource(R.xml.device_info_memory);
- addCategory(StorageVolumePreferenceCategory.buildForInternal(context));
- final StorageVolume[] storageVolumes = mStorageManager.getVolumeList();
- for (StorageVolume volume : storageVolumes) {
- if (!volume.isEmulated()) {
- addCategory(StorageVolumePreferenceCategory.buildForPhysical(context, volume));
- }
- }
- setHasOptionsMenu(true);
- }
在onCreate函数中,主要做了几件事情:
1.各种初始化
2.实例化布局,最主要是对Category的添加
3.获取当前挂载的volume,并且实例化为Category
Category最主要的是StorageVolumePreferenceCategory,构造函数如下:
- /**
- * Build category to summarize specific physical {@link StorageVolume}.
- */
- public static StorageVolumePreferenceCategory buildForPhysical(
- Context context, StorageVolume volume) {
- return new StorageVolumePreferenceCategory(context, volume);
- }
- private StorageVolumePreferenceCategory(Context context, StorageVolume volume) {
- super(context);
- mVolume = volume;
- mMeasure = StorageMeasurement.getInstance(context, volume);
- mResources = context.getResources();
- mStorageManager = StorageManager.from(context);
- mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- setTitle(volume != null ? volume.getDescription(context)
- : context.getText(R.string.internal_storage));
- }
构造函数会被如下函数调用:
- /**
- * Build category to summarize internal storage, including any emulated
- * {@link StorageVolume}.
- */
- public static StorageVolumePreferenceCategory buildForInternal(Context context) {
- return new StorageVolumePreferenceCategory(context, null);
- }
到这里,主要是在Category里面做一些初始化,对于存储fragment最上面的“内部存储设备”text显示就是在构造函数中完成:
- setTitle(volume != null ? volume.getDescription(context)
- : context.getText(R.string.internal_storage));
对于外置设备Category的创建,主要是在:
- /**
- * Build category to summarize specific physical {@link StorageVolume}.
- */
- public static StorageVolumePreferenceCategory buildForPhysical(
- Context context, StorageVolume volume) {
- return new StorageVolumePreferenceCategory(context, volume);
- }
唯一的区别就是Volume是否为NULL。
创建Category后,主要是对preference的创建,主要是在init函数:
- public void init() {
- final Context context = getContext();
- removeAll();
- final UserInfo currentUser;
- try {
- currentUser = ActivityManagerNative.getDefault().getCurrentUser();
- } catch (RemoteException e) {
- throw new RuntimeException("Failed to get current user");
- }
- final List<UserInfo> otherUsers = getUsersExcluding(currentUser);
- final boolean showUsers = mVolume == null && otherUsers.size() > 0;
- mUsageBarPreference = new UsageBarPreference(context);
- mUsageBarPreference.setOrder(ORDER_USAGE_BAR);
- addPreference(mUsageBarPreference);
- mItemTotal = buildItem(R.string.memory_size, 0);
- mItemAvailable = buildItem(R.string.memory_available, R.color.memory_avail);
- addPreference(mItemTotal);
- addPreference(mItemAvailable);
- mItemApps = buildItem(R.string.memory_apps_usage, R.color.memory_apps_usage);
- mItemDcim = buildItem(R.string.memory_dcim_usage, R.color.memory_dcim);
- mItemMusic = buildItem(R.string.memory_music_usage, R.color.memory_music);
- mItemDownloads = buildItem(R.string.memory_downloads_usage, R.color.memory_downloads);
- mItemCache = buildItem(R.string.memory_media_cache_usage, R.color.memory_cache);
- mItemMisc = buildItem(R.string.memory_media_misc_usage, R.color.memory_misc);
- mItemCache.setKey(KEY_CACHE);
- final boolean showDetails = mVolume == null || mVolume.isPrimary();
- if (showDetails) {
- if (showUsers) {
- addPreference(new PreferenceHeader(context, currentUser.name));
- }
- addPreference(mItemApps);
- addPreference(mItemDcim);
- addPreference(mItemMusic);
- addPreference(mItemDownloads);
- addPreference(mItemCache);
- addPreference(mItemMisc);
- if (showUsers) {
- addPreference(new PreferenceHeader(context, R.string.storage_other_users));
- int count = 0;
- for (UserInfo info : otherUsers) {
- final int colorRes = count++ % 2 == 0 ? R.color.memory_user_light
- : R.color.memory_user_dark;
- final StorageItemPreference userPref = new StorageItemPreference(
- getContext(), info.name, colorRes, info.id);
- mItemUsers.add(userPref);
- addPreference(userPref);
- }
- }
- }
- final boolean isRemovable = mVolume != null ? mVolume.isRemovable() : false;
- // Always create the preference since many code rely on it existing
- mMountTogglePreference = new Preference(context);
- if (isRemovable) {
- mMountTogglePreference.setTitle(R.string.sd_eject);
- mMountTogglePreference.setSummary(R.string.sd_eject_summary);
- addPreference(mMountTogglePreference);
- }
- final boolean allowFormat = mVolume != null;
- if (allowFormat) {
- mFormatPreference = new Preference(context);
- mFormatPreference.setTitle(R.string.sd_format);
- mFormatPreference.setSummary(R.string.sd_format_summary);
- addPreference(mFormatPreference);
- }
- final IPackageManager pm = ActivityThread.getPackageManager();
- try {
- if (pm.isStorageLow()) {
- mStorageLow = new Preference(context);
- mStorageLow.setOrder(ORDER_STORAGE_LOW);
- mStorageLow.setTitle(R.string.storage_low_title);
- mStorageLow.setSummary(R.string.storage_low_summary);
- addPreference(mStorageLow);
- } else if (mStorageLow != null) {
- removePreference(mStorageLow);
- mStorageLow = null;
- }
- } catch (RemoteException e) {
- }
- }
对preference数据进行更新是在:
- public void updateApproximate(long totalSize, long availSize) {
- mItemTotal.setSummary(formatSize(totalSize));
- mItemAvailable.setSummary(formatSize(availSize));
- mTotalSize = totalSize;
- final long usedSize = totalSize - availSize;
- mUsageBarPreference.clear();
- mUsageBarPreference.addEntry(0, usedSize / (float) totalSize, android.graphics.Color.GRAY);
- mUsageBarPreference.commit();
- updatePreferencesFromState();
- }
当点击cache prefrence时,会弹出dialog,主要是在Memory.java中响应:
- public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
- if (StorageVolumePreferenceCategory.KEY_CACHE.equals(preference.getKey())) {
- ConfirmClearCacheFragment.show(this);
- return true;
- }
查看ConfirmClearCacheFragment的函数:
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- final Context context = getActivity();
- final AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle(R.string.memory_clear_cache_title);
- builder.setMessage(getString(R.string.memory_clear_cache_message));
- builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- final Memory target = (Memory) getTargetFragment();
- final PackageManager pm = context.getPackageManager();
- final List<PackageInfo> infos = pm.getInstalledPackages(0);
- final ClearCacheObserver observer = new ClearCacheObserver(
- target, infos.size());
- for (PackageInfo info : infos) {
- pm.deleteApplicationCacheFiles(info.packageName, observer);
- }
- }
- });
- builder.setNegativeButton(android.R.string.cancel, null);
- return builder.create();
- }
会通过PackageManager获取所有安装apk,然后清除所有apk的缓存数据。
点击“卸载SD卡”,会弹出dialog,对应的代码为:
- private void unmount() {
- // Check if external media is in use.
- try {
- if (hasAppsAccessingStorage()) {
- // Present dialog to user
- showDialogInner(DLG_CONFIRM_UNMOUNT);
- } else {
- doUnmount();
- }
- } catch (RemoteException e) {
- // Very unlikely. But present an error dialog anyway
- Log.e(TAG, "Is MountService running?");
- showDialogInner(DLG_ERROR_UNMOUNT);
- }
- }
- @Override
- public Dialog onCreateDialog(int id) {
- switch (id) {
- case DLG_CONFIRM_UNMOUNT:
- return new AlertDialog.Builder(getActivity())
- .setTitle(R.string.dlg_confirm_unmount_title)
- .setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int which) {
- doUnmount();
- }})
- .setNegativeButton(R.string.cancel, null)
- .setMessage(R.string.dlg_confirm_unmount_text)
- .create();
- private void doUnmount() {
- // Present a toast here
- Toast.makeText(getActivity(), R.string.unmount_inform_text, Toast.LENGTH_SHORT).show();
- IMountService mountService = getMountService();
- try {
- sLastClickedMountToggle.setEnabled(false);
- sLastClickedMountToggle.setTitle(getString(R.string.sd_ejecting_title));
- sLastClickedMountToggle.setSummary(getString(R.string.sd_ejecting_summary));
- mountService.unmountVolume(sClickedMountPoint, true, false);
- } catch (RemoteException e) {
- // Informative dialog to user that unmount failed.
- showDialogInner(DLG_ERROR_UNMOUNT);
- }
- }
原文地址:http://blog.csdn.net/zhudaozhuan/article/details/40621335
android settings源代码分析(3)相关推荐
- android settings源代码分析(2)
通过前一篇文章 Android settings源代码分析(1) 分析,大概知道了Settings主页面是如何显示,今天主要分析"应用"这一块google是如何实现的. 应用对 ...
- android settings源代码分析(1)
1.Android settings源码的source code路径为: kikat_4.4_CTS\packages\apps\Settings 2.settings主界面UI布局 Settings ...
- Android 消息处理源代码分析(1)
Android 消息处理源代码分析(1) 在Android中,通常被使用的消息队列的代码在文件夹\sources\android-22\android\os下,涉及到下面几个类文件 Handler.j ...
- Github android客户端源代码分析之一:环境搭建
1.下载相应的包及项目,参考https://github.com/github/android/wiki/Building-From-Eclipse. 2.若需查看某些包的源文件或者javadoc,则 ...
- Android深入源代码分析理解Aidl总体调用流程(雷惊风)
2017年開始上班的第一天.老不想工作了,假期感觉还没開始就已经结束了,唉,时间就是这样,新的一年開始了,尽管非常不想干正事,没办法,必须干起来.由于后边的路还非常长,距离六十岁还非常远. 刚上班也没 ...
- android map有序存储,Android ArrayMap源代码分析
分析源码之前先来介绍一下ArrayMap的存储结构,ArrayMap数据的存储不同于HashMap和SparseArray. Java提供了HashMap,但是HashMap对于手机端而言,对空间的利 ...
- android stk 源代码分析,Android源码分析--STK
文件:StkAppService.java 函数:onCreate() STK的APP程序启动后执行的第一个函数,会调用方法: com.android.internal.telephony.gsm.s ...
- [Android]Volley源代码分析(店)应用
通过前面的谈话,我相信你有Volley有了一定的了解了原理.本章将给出一些我们的应用程序都可以在样品中直接使用,第一样品是 NetworkImageView类,事实上NetworkImageView顾 ...
- android scrcpy 源代码分析,Scrcpy投屏原理浅析-设备控制篇
起初我真的想过自己单独写一套来着,后来发现 Scrcpy与vysor是都是投屏中比较优秀的项目了,非侵入性,不需要设备单独 scrcpy启动阶段 它到底是怎么做到执行scrcpy命令,在较短的时间内就 ...
最新文章
- matlab 直方图_MATLAB作图实例:19:用二元直方图分析图片颜色
- 可视化神器背后的奥秘
- UESTC 电子科大专题训练 DP-N
- Java Server Page
- Linux BPF hello world C语言示例代码
- Android学习笔记---26_采用JSON格式返回数据给资讯客户端,效率上要高于xml文件解析和传输
- 将运行时地理数据库(*.geodatabase)复制到文件地理数据库
- 《数学之美》—贾里尼克和现代语言处理
- android源码上面开发App
- zookeeper 可以干什么
- 小程序服务器装rsshub,用RSSHub制作自己的RSS订阅源
- 如何建设网站步骤有哪些?
- 配置OSPF认证【eNSP实现】
- android画笔,Android自定义View系列之画笔(一)
- PAT A1010 Radix (25 分)
- 如何清空python的IDLE?
- 微信小程序——绘制折线图
- Module use of python36.dll conflicts with this version of Python
- [教程10]TensorFlow线性模型教程
- 程序员学炒股(4) 早晨十字星靠不靠谱