android settings源代码分析(3)

来源:互联网 发布:golang.org上不去 编辑:程序博客网 时间:2024/04/30 12:05

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

存储模块所在的fragment为:

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  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 plain copy
 在CODE上查看代码片派生到我的代码片
  1. @Override  
  2.   public void onCreate(Bundle icicle) {  
  3.       super.onCreate(icicle);  
  4.   
  5.       final Context context = getActivity();  
  6.   
  7.       mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);  
  8.   
  9.       mStorageManager = StorageManager.from(context);  
  10.       mStorageManager.registerListener(mStorageListener);  
  11.   
  12.       addPreferencesFromResource(R.xml.device_info_memory);  
  13.   
  14.       addCategory(StorageVolumePreferenceCategory.buildForInternal(context));  
  15.   
  16.       final StorageVolume[] storageVolumes = mStorageManager.getVolumeList();  
  17.       for (StorageVolume volume : storageVolumes) {  
  18.           if (!volume.isEmulated()) {  
  19.               addCategory(StorageVolumePreferenceCategory.buildForPhysical(context, volume));  
  20.           }  
  21.       }  
  22.   
  23.       setHasOptionsMenu(true);  
  24.   }  

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

1.各种初始化

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

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

 

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

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  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.   
  9.  private StorageVolumePreferenceCategory(Context context, StorageVolume volume) {  
  10.      super(context);  
  11.   
  12.      mVolume = volume;  
  13.      mMeasure = StorageMeasurement.getInstance(context, volume);  
  14.   
  15.      mResources = context.getResources();  
  16.      mStorageManager = StorageManager.from(context);  
  17.      mUserManager = (UserManager) context.getSystemService(Context.USER_SERVICE);  
  18.   
  19.      setTitle(volume != null ? volume.getDescription(context)  
  20.              : context.getText(R.string.internal_storage));  
  21.  }  

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

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  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 plain copy
 在CODE上查看代码片派生到我的代码片
  1. setTitle(volume != null ? volume.getDescription(context)  
  2.                 : context.getText(R.string.internal_storage));  

 

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

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

对preference数据进行更新是在:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public void updateApproximate(long totalSize, long availSize) {  
  2.     mItemTotal.setSummary(formatSize(totalSize));  
  3.     mItemAvailable.setSummary(formatSize(availSize));  
  4.   
  5.     mTotalSize = totalSize;  
  6.   
  7.     final long usedSize = totalSize - availSize;  
  8.   
  9.     mUsageBarPreference.clear();  
  10.     mUsageBarPreference.addEntry(0, usedSize / (float) totalSize, android.graphics.Color.GRAY);  
  11.     mUsageBarPreference.commit();  
  12.   
  13.     updatePreferencesFromState();  
  14. }  

 

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

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  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 plain copy
 在CODE上查看代码片派生到我的代码片
  1. @Override  
  2.    public Dialog onCreateDialog(Bundle savedInstanceState) {  
  3.        final Context context = getActivity();  
  4.   
  5.        final AlertDialog.Builder builder = new AlertDialog.Builder(context);  
  6.        builder.setTitle(R.string.memory_clear_cache_title);  
  7.        builder.setMessage(getString(R.string.memory_clear_cache_message));  
  8.   
  9.        builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {  
  10.            @Override  
  11.            public void onClick(DialogInterface dialog, int which) {  
  12.                final Memory target = (Memory) getTargetFragment();  
  13.                final PackageManager pm = context.getPackageManager();  
  14.                final List<PackageInfo> infos = pm.getInstalledPackages(0);  
  15.                final ClearCacheObserver observer = new ClearCacheObserver(  
  16.                        target, infos.size());  
  17.                for (PackageInfo info : infos) {  
  18.                    pm.deleteApplicationCacheFiles(info.packageName, observer);  
  19.                }  
  20.            }  
  21.        });  
  22.        builder.setNegativeButton(android.R.string.cancel, null);  
  23.   
  24.        return builder.create();  
  25.    }  

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

 

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

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  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 plain copy
 在CODE上查看代码片派生到我的代码片
  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 plain copy
 在CODE上查看代码片派生到我的代码片
  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, truefalse);  
  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

0 0
原创粉丝点击