日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

android settings源代码分析(2)

發布時間:2025/3/15 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 android settings源代码分析(2) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ? ?通過前一篇文章 ?Android?settings源代碼分析(1)? 分析,大概知道了Settings主頁面是如何顯示,今天主要分析“應用”這一塊google是如何實現的。

?

應用對應的fragment為:

[html]?view plaincopy
  • <span?style="font-size:14px;">?<!--?Application?Settings?-->??
  • ????<header??
  • ????????android:fragment="com.android.settings.applications.ManageApplications"??
  • ????????android:icon="@drawable/ic_settings_applications"??
  • ????????android:title="@string/applications_settings"??
  • ????????android:id="@+id/application_settings"?/></span>??
  • 因此需要查看ManageApplications如何實現。

    ManageApplications所在路徑為:

    kikat_4.4_CTS\packages\apps\Settings\src\com\android\settings\applications

    ?

    從Application UI可以看出,fragment主要是一個tab,以及每一個tab下都會顯示和存儲相關的信息,比如RAM,SDCARD和內部存儲空間的大小。接下來分析tab如何實現以及這些存儲信息如何獲取。

    ?

    查看ManageApplications的onCreateView函數,可以看到:

    [java]?view plaincopy
  • View?rootView?=?mInflater.inflate(R.layout.manage_applications_content,??
  • ???????????????container,?false);??
  • 這里會使用manage_applications_content.xml,我們查看xml的內容:

    [html]?view plaincopy
  • <?xml?version="1.0"?encoding="utf-8"?>??
  • <!--??
  • /*??
  • **??
  • **?Copyright?2012,?The?Android?Open?Source?Project??
  • **??
  • **?Licensed?under?the?Apache?License,?Version?2.0?(the?"License");??
  • **?you?may?not?use?this?file?except?in?compliance?with?the?License.??
  • **?You?may?obtain?a?copy?of?the?License?at??
  • **??
  • **?????http://www.apache.org/licenses/LICENSE-2.0??
  • **??
  • **?Unless?required?by?applicable?law?or?agreed?to?in?writing,?software??
  • **?distributed?under?the?License?is?distributed?on?an?"AS?IS"?BASIS,??
  • **?WITHOUT?WARRANTIES?OR?CONDITIONS?OF?ANY?KIND,?either?express?or?implied.??
  • **?See?the?License?for?the?specific?language?governing?permissions?and??
  • **?limitations?under?the?License.??
  • */??
  • -->??
  • ??
  • <LinearLayout??
  • ????xmlns:android="http://schemas.android.com/apk/res/android"??
  • ????android:layout_width="match_parent"??
  • ????android:layout_height="match_parent"??
  • ????android:orientation="vertical">??
  • ??
  • ????<android.support.v4.view.ViewPager??
  • ????????????android:id="@+id/pager"??
  • ????????????android:layout_width="match_parent"??
  • ????????????android:layout_height="match_parent"??
  • ????????????android:layout_weight="1">??
  • ????????<android.support.v4.view.PagerTabStrip??
  • ????????????????android:id="@+id/tabs"??
  • ????????????????android:layout_width="match_parent"??
  • ????????????????android:layout_height="wrap_content"??
  • ????????????????android:layout_gravity="top"??
  • ????????????????android:textAppearance="@style/TextAppearance.PagerTabs"??
  • ????????????????android:padding="0dp">??
  • ????????</android.support.v4.view.PagerTabStrip>??
  • ????</android.support.v4.view.ViewPager>??
  • ??
  • </LinearLayout>??
  • application fragment的布局本質就是一個ViewPager,因此可以支持左右滑動,每一頁對應一個tab的顯示。

    ?

    [java]?view plaincopy
  • MyPagerAdapter?adapter?=?new?MyPagerAdapter();??
  • ???????mViewPager.setAdapter(adapter);??
  • ???????mViewPager.setOnPageChangeListener(adapter);??
  • 這里會設置一個adapter,用來填充ViewPager里的內容。

    ?

    [java]?view plaincopy
  • class?MyPagerAdapter?extends?PagerAdapter??
  • ???????????implements?ViewPager.OnPageChangeListener?{??
  • ???????int?mCurPos?=?0;??
  • ??
  • ???????@Override??
  • ???????public?int?getCount()?{??
  • ???????????return?mNumTabs;??
  • ???????}??
  • ?????????
  • ???????@Override??
  • ???????public?Object?instantiateItem(ViewGroup?container,?int?position)?{??
  • ???????????TabInfo?tab?=?mTabs.get(position);??
  • ???????????View?root?=?tab.build(mInflater,?mContentContainer,?mRootView);??
  • ???????????container.addView(root);??
  • ???????????root.setTag(R.id.name,?tab);??
  • ???????????return?root;??
  • ???????}??
  • ??
  • ???????@Override??
  • ???????public?void?destroyItem(ViewGroup?container,?int?position,?Object?object)?{??
  • ???????????container.removeView((View)object);??
  • ???????}??
  • ??
  • ???????@Override??
  • ???????public?boolean?isViewFromObject(View?view,?Object?object)?{??
  • ???????????return?view?==?object;??
  • ???????}??
  • ??
  • ???????@Override??
  • ???????public?int?getItemPosition(Object?object)?{??
  • ???????????return?super.getItemPosition(object);??
  • ???????????//return?((TabInfo)((View)object).getTag(R.id.name)).mListType;??
  • ???????}??
  • ??
  • ???????@Override??
  • ???????public?CharSequence?getPageTitle(int?position)?{??
  • ???????????return?mTabs.get(position).mLabel;??
  • ???????}??
  • ??
  • ???????@Override??
  • ???????public?void?onPageScrolled(int?position,?float?positionOffset,?int?positionOffsetPixels)?{??
  • ???????}??
  • ??
  • ???????@Override??
  • ???????public?void?onPageSelected(int?position)?{??
  • ???????????mCurPos?=?position;??
  • ???????}??
  • ??
  • ???????@Override??
  • ???????public?void?onPageScrollStateChanged(int?state)?{??
  • ???????????if?(state?==?ViewPager.SCROLL_STATE_IDLE)?{??
  • ???????????????updateCurrentTab(mCurPos);??
  • ???????????}??
  • ???????}??
  • ???}??
  • 此adapter中instantiateItem函數會初始化每一個子項,即每一頁:

    [java]?view plaincopy
  • TabInfo?tab?=?mTabs.get(position);??
  • View?root?=?tab.build(mInflater,?mContentContainer,?mRootView);??
  • 因此需要查看TabInfo中的build函數。

    [java]?view plaincopy
  • public?View?build(LayoutInflater?inflater,?ViewGroup?contentParent,?View?contentChild)?{??
  • ????????????if?(mRootView?!=?null)?{??
  • ????????????????return?mRootView;??
  • ????????????}??
  • ??
  • ????????????mInflater?=?inflater;??
  • ????????????mRootView?=?inflater.inflate(mListType?==?LIST_TYPE_RUNNING??
  • ??????????????????????R.layout.manage_applications_running??
  • ????????????????????:?R.layout.manage_applications_apps,?null);??
  • ????????????mLoadingContainer?=?mRootView.findViewById(R.id.loading_container);??
  • ????????????mLoadingContainer.setVisibility(View.VISIBLE);??
  • ????????????mListContainer?=?mRootView.findViewById(R.id.list_container);??
  • ????????????if?(mListContainer?!=?null)?{??
  • ????????????????//?Create?adapter?and?list?view?here??
  • ????????????????View?emptyView?=?mListContainer.findViewById(com.android.internal.R.id.empty);??
  • ????????????????ListView?lv?=?(ListView)?mListContainer.findViewById(android.R.id.list);??
  • ????????????????if?(emptyView?!=?null)?{??
  • ????????????????????lv.setEmptyView(emptyView);??
  • ????????????????}??
  • ????????????????lv.setOnItemClickListener(this);??
  • ????????????????lv.setSaveEnabled(true);??
  • ????????????????lv.setItemsCanFocus(true);??
  • ????????????????lv.setTextFilterEnabled(true);??
  • ????????????????mListView?=?lv;??
  • ????????????????mApplications?=?new?ApplicationsAdapter(mApplicationsState,?this,?mFilter);??
  • ????????????????mListView.setAdapter(mApplications);??
  • ????????????????mListView.setRecyclerListener(mApplications);??
  • ????????????????mColorBar?=?(LinearColorBar)mListContainer.findViewById(R.id.storage_color_bar);??
  • ????????????????mStorageChartLabel?=?(TextView)mListContainer.findViewById(R.id.storageChartLabel);??
  • ????????????????mUsedStorageText?=?(TextView)mListContainer.findViewById(R.id.usedStorageText);??
  • ????????????????mFreeStorageText?=?(TextView)mListContainer.findViewById(R.id.freeStorageText);??
  • ????????????????Utils.prepareCustomPreferencesList(contentParent,?contentChild,?mListView,?false);??
  • ????????????????if?(mFilter?==?FILTER_APPS_SDCARD)?{??
  • ????????????????????mStorageChartLabel.setText(mOwner.getActivity().getText(??
  • ????????????????????????????R.string.sd_card_storage));??
  • ????????????????}?else?{??
  • ????????????????????mStorageChartLabel.setText(mOwner.getActivity().getText(??
  • ????????????????????????????R.string.internal_storage));??
  • ????????????????}??
  • ????????????????applyCurrentStorage();??
  • ????????????}??
  • ????????????mRunningProcessesView?=?(RunningProcessesView)mRootView.findViewById(??
  • ????????????????????R.id.running_processes);??
  • ????????????if?(mRunningProcessesView?!=?null)?{??
  • ????????????????mRunningProcessesView.doCreate(mSavedInstanceState);??
  • ????????????}??
  • ??
  • ????????????return?mRootView;??
  • ????????}??
  • 此函數中用來顯示tab中listview和tab下對應的storage顯示信息。

    ?

    對于tab中listView的填充:

    [java]?view plaincopy
  • public?View?getView(int?position,?View?convertView,?ViewGroup?parent)?{??
  • ????????????//?A?ViewHolder?keeps?references?to?children?views?to?avoid?unnecessary?calls??
  • ????????????//?to?findViewById()?on?each?row.??
  • ????????????AppViewHolder?holder?=?AppViewHolder.createOrRecycle(mTab.mInflater,?convertView);??
  • ????????????convertView?=?holder.rootView;??
  • ??
  • ????????????//?Bind?the?data?efficiently?with?the?holder??
  • ????????????ApplicationsState.AppEntry?entry?=?mEntries.get(position);??
  • ????????????synchronized?(entry)?{??
  • ????????????????holder.entry?=?entry;??
  • ????????????????if?(entry.label?!=?null)?{??
  • ????????????????????holder.appName.setText(entry.label);??
  • ????????????????}??
  • ????????????????mState.ensureIcon(entry);??
  • ????????????????if?(entry.icon?!=?null)?{??
  • ????????????????????holder.appIcon.setImageDrawable(entry.icon);??
  • ????????????????}??
  • ????????????????holder.updateSizeText(mTab.mInvalidSizeStr,?mWhichSize);??
  • ????????????????if?((entry.info.flags&ApplicationInfo.FLAG_INSTALLED)?==?0)?{??
  • ????????????????????holder.disabled.setVisibility(View.VISIBLE);??
  • ????????????????????holder.disabled.setText(R.string.not_installed);??
  • ????????????????}?else?if?(!entry.info.enabled)?{??
  • ????????????????????holder.disabled.setVisibility(View.VISIBLE);??
  • ????????????????????holder.disabled.setText(R.string.disabled);??
  • ????????????????}?else?{??
  • ????????????????????holder.disabled.setVisibility(View.GONE);??
  • ????????????????}??
  • ????????????????if?(mFilterMode?==?FILTER_APPS_SDCARD)?{??
  • ????????????????????holder.checkBox.setVisibility(View.VISIBLE);??
  • ????????????????????holder.checkBox.setChecked((entry.info.flags??
  • ????????????????????????????&?ApplicationInfo.FLAG_EXTERNAL_STORAGE)?!=?0);??
  • ????????????????}?else?{??
  • ????????????????????holder.checkBox.setVisibility(View.GONE);??
  • ????????????????}??
  • ????????????}??
  • ????????????mActive.remove(convertView);??
  • ????????????mActive.add(convertView);??
  • ????????????return?convertView;??
  • ????????}??
  • ?

    對于storage的獲取,需要使用到IMediaContainerService,綁定此service的地方:

    [java]?view plaincopy
  • getActivity().bindService(containerIntent,?mContainerConnection,?Context.BIND_AUTO_CREATE);??

  • 連接此service,每一個tab都會得到此service實例,通過此實例獲取storage相關信息

    [java]?view plaincopy
  • private?volatile?IMediaContainerService?mContainerService;??
  • ??
  • ???private?final?ServiceConnection?mContainerConnection?=?new?ServiceConnection()?{??
  • ???????@Override??
  • ???????public?void?onServiceConnected(ComponentName?name,?IBinder?service)?{??
  • ???????????mContainerService?=?IMediaContainerService.Stub.asInterface(service);??
  • ???????????for?(int?i=0;?i<mTabs.size();?i++)?{??
  • ???????????????mTabs.get(i).setContainerService(mContainerService);??
  • ???????????}??
  • ???????}??
  • ??
  • ???????@Override??
  • ???????public?void?onServiceDisconnected(ComponentName?name)?{??
  • ???????????mContainerService?=?null;??
  • ???????}??
  • ???};??

  • 獲取storage信息代碼如下:

    獲取SD卡:

    [java]?view plaincopy
  • if?(mFilter?==?FILTER_APPS_SDCARD)?{??
  • ????????????????if?(mContainerService?!=?null)?{??
  • ????????????????????try?{??
  • ????????????????????????final?long[]?stats?=?mContainerService.getFileSystemStats(??
  • ????????????????????????????????Environment.getExternalStorageDirectory().getPath());??
  • ????????????????????????mTotalStorage?=?stats[0];??
  • ????????????????????????mFreeStorage?=?stats[1];??
  • ????????????????????}?catch?(RemoteException?e)?{??
  • ????????????????????????Log.w(TAG,?"Problem?in?container?service",?e);??
  • ????????????????????}??
  • ????????????????}??
  • ??
  • ????????????????if?(mApplications?!=?null)?{??
  • ????????????????????final?int?N?=?mApplications.getCount();??
  • ????????????????????for?(int?i=0;?i<N;?i++)?{??
  • ????????????????????????ApplicationsState.AppEntry?ae?=?mApplications.getAppEntry(i);??
  • ????????????????????????mAppStorage?+=?ae.externalCodeSize?+?ae.externalDataSize??
  • ????????????????????????????????+?ae.externalCacheSize;??
  • ????????????????????}??
  • ????????????????}??

  • 獲取本地存儲空間信息:

    [java]?view plaincopy
  • if?(mContainerService?!=?null)?{??
  • ???????????????????try?{??
  • ???????????????????????final?long[]?stats?=?mContainerService.getFileSystemStats(??
  • ???????????????????????????????Environment.getDataDirectory().getPath());??
  • ???????????????????????mTotalStorage?=?stats[0];??
  • ???????????????????????mFreeStorage?=?stats[1];??
  • ???????????????????}?catch?(RemoteException?e)?{??
  • ???????????????????????Log.w(TAG,?"Problem?in?container?service",?e);??
  • ???????????????????}??
  • ???????????????}??
  • 最后顯示到UI上去:

    [java]?view plaincopy
  • void?applyCurrentStorage()?{??
  • ????//?If?view?hierarchy?is?not?yet?created,?no?views?to?update.??
  • ????if?(mRootView?==?null)?{??
  • ????????return;??
  • ????}??
  • ????if?(mTotalStorage?>?0)?{??
  • ????????BidiFormatter?bidiFormatter?=?BidiFormatter.getInstance();??
  • ????????mColorBar.setRatios((mTotalStorage-mFreeStorage-mAppStorage)/(float)mTotalStorage,??
  • ????????????????mAppStorage/(float)mTotalStorage,?mFreeStorage/(float)mTotalStorage);??
  • ????????long?usedStorage?=?mTotalStorage?-?mFreeStorage;??
  • ????????if?(mLastUsedStorage?!=?usedStorage)?{??
  • ????????????mLastUsedStorage?=?usedStorage;??
  • ????????????String?sizeStr?=?bidiFormatter.unicodeWrap(??
  • ????????????????????Formatter.formatShortFileSize(mOwner.getActivity(),?usedStorage));??
  • ????????????mUsedStorageText.setText(mOwner.getActivity().getResources().getString(??
  • ????????????????????R.string.service_foreground_processes,?sizeStr));??
  • ????????}??
  • ????????if?(mLastFreeStorage?!=?mFreeStorage)?{??
  • ????????????mLastFreeStorage?=?mFreeStorage;??
  • ????????????String?sizeStr?=?bidiFormatter.unicodeWrap(??
  • ????????????????????Formatter.formatShortFileSize(mOwner.getActivity(),?mFreeStorage));??
  • ????????????mFreeStorageText.setText(mOwner.getActivity().getResources().getString(??
  • ????????????????????R.string.service_background_processes,?sizeStr));??
  • ????????}??
  • ????}?else?{??
  • ????????mColorBar.setRatios(0,?0,?0);??
  • ????????if?(mLastUsedStorage?!=?-1)?{??
  • ????????????mLastUsedStorage?=?-1;??
  • ????????????mUsedStorageText.setText("");??
  • ????????}??
  • ????????if?(mLastFreeStorage?!=?-1)?{??
  • ????????????mLastFreeStorage?=?-1;??
  • ????????????mFreeStorageText.setText("");??
  • ????????}??
  • ????}??
  • }??

  • 當點擊listView子項時,會跳轉到詳細列表頁面:

    [java]?view plaincopy
  • public?void?onItemClick(TabInfo?tab,?AdapterView<?>?parent,?View?view,?int?position,??
  • ??????????long?id)?{??
  • ??????if?(tab.mApplications?!=?null?&&?tab.mApplications.getCount()?>?position)?{??
  • ??????????ApplicationsState.AppEntry?entry?=?tab.mApplications.getAppEntry(position);??
  • ??????????mCurrentPkgName?=?entry.info.packageName;??
  • ??????????startApplicationDetailsActivity();??
  • ??????}??
  • ??}??
  • [java]?view plaincopy
  • //?utility?method?used?to?start?sub?activity??
  • ??private?void?startApplicationDetailsActivity()?{??
  • ??????//?start?new?fragment?to?display?extended?information??
  • ??????Bundle?args?=?new?Bundle();??
  • ??????args.putString(InstalledAppDetails.ARG_PACKAGE_NAME,?mCurrentPkgName);??
  • ??
  • ??????PreferenceActivity?pa?=?(PreferenceActivity)getActivity();??
  • ??????pa.startPreferencePanel(InstalledAppDetails.class.getName(),?args,??
  • ??????????????R.string.application_info_label,?null,?this,?INSTALLED_APP_DETAILS);??
  • ??}??
  • 查看詳細列表對應的類:

    [java]?view plaincopy
  • public?class?InstalledAppDetails?extends?Fragment??
  • ????????implements?View.OnClickListener,?CompoundButton.OnCheckedChangeListener,??
  • ????????ApplicationsState.Callbacks??
  • 即也是一個fragment。

    ?

    詳細列表界面相關button操作代碼如下:

    [java]?view plaincopy
  • public?void?onClick(View?v)?{??
  • ???????String?packageName?=?mAppEntry.info.packageName;??
  • ???????if(v?==?mUninstallButton)?{??
  • ???????????if?(mUpdatedSysApp)?{??
  • ???????????????showDialogInner(DLG_FACTORY_RESET,?0);??
  • ???????????}?else?{??
  • ???????????????if?((mAppEntry.info.flags?&?ApplicationInfo.FLAG_SYSTEM)?!=?0)?{??
  • ???????????????????if?(mAppEntry.info.enabled)?{??
  • ???????????????????????showDialogInner(DLG_DISABLE,?0);??
  • ???????????????????}?else?{??
  • ???????????????????????new?DisableChanger(this,?mAppEntry.info,??
  • ???????????????????????????????PackageManager.COMPONENT_ENABLED_STATE_DEFAULT)??
  • ???????????????????????.execute((Object)null);??
  • ???????????????????}??
  • ???????????????}?else?if?((mAppEntry.info.flags?&?ApplicationInfo.FLAG_INSTALLED)?==?0)?{??
  • ???????????????????uninstallPkg(packageName,?true,?false);??
  • ???????????????}?else?{??
  • ???????????????????uninstallPkg(packageName,?false,?false);??
  • ???????????????}??
  • ???????????}??
  • ???????}?else?if(v?==?mSpecialDisableButton)?{??
  • ???????????showDialogInner(DLG_SPECIAL_DISABLE,?0);??
  • ???????}?else?if(v?==?mActivitiesButton)?{??
  • ???????????mPm.clearPackagePreferredActivities(packageName);??
  • ???????????try?{??
  • ???????????????mUsbManager.clearDefaults(packageName,?UserHandle.myUserId());??
  • ???????????}?catch?(RemoteException?e)?{??
  • ???????????????Log.e(TAG,?"mUsbManager.clearDefaults",?e);??
  • ???????????}??
  • ???????????mAppWidgetManager.setBindAppWidgetPermission(packageName,?false);??
  • ???????????TextView?autoLaunchTitleView?=??
  • ???????????????????(TextView)?mRootView.findViewById(R.id.auto_launch_title);??
  • ???????????TextView?autoLaunchView?=?(TextView)?mRootView.findViewById(R.id.auto_launch);??
  • ???????????resetLaunchDefaultsUi(autoLaunchTitleView,?autoLaunchView);??
  • ???????}?else?if(v?==?mClearDataButton)?{??
  • ???????????if?(mAppEntry.info.manageSpaceActivityName?!=?null)?{??
  • ???????????????if?(!Utils.isMonkeyRunning())?{??
  • ???????????????????Intent?intent?=?new?Intent(Intent.ACTION_DEFAULT);??
  • ???????????????????intent.setClassName(mAppEntry.info.packageName,??
  • ???????????????????????????mAppEntry.info.manageSpaceActivityName);??
  • ???????????????????startActivityForResult(intent,?REQUEST_MANAGE_SPACE);??
  • ???????????????}??
  • ???????????}?else?{??
  • ???????????????showDialogInner(DLG_CLEAR_DATA,?0);??
  • ???????????}??
  • ???????}?else?if?(v?==?mClearCacheButton)?{??
  • ???????????//?Lazy?initialization?of?observer??
  • ???????????if?(mClearCacheObserver?==?null)?{??
  • ???????????????mClearCacheObserver?=?new?ClearCacheObserver();??
  • ???????????}??
  • ???????????mPm.deleteApplicationCacheFiles(packageName,?mClearCacheObserver);??
  • ???????}?else?if?(v?==?mForceStopButton)?{??
  • ???????????showDialogInner(DLG_FORCE_STOP,?0);??
  • ???????????//forceStopPackage(mAppInfo.packageName);??
  • ???????}?else?if?(v?==?mMoveAppButton)?{??
  • ???????????if?(mPackageMoveObserver?==?null)?{??
  • ???????????????mPackageMoveObserver?=?new?PackageMoveObserver();??
  • ???????????}??
  • ???????????int?moveFlags?=?(mAppEntry.info.flags?&?ApplicationInfo.FLAG_EXTERNAL_STORAGE)?!=?0????
  • ???????????????????PackageManager.MOVE_INTERNAL?:?PackageManager.MOVE_EXTERNAL_MEDIA;??
  • ???????????mMoveInProgress?=?true;??
  • ???????????refreshButtons();??
  • ???????????mPm.movePackage(mAppEntry.info.packageName,?mPackageMoveObserver,?moveFlags);??
  • ???????}??
  • ???}??

  • ?原文地址:?http://blog.csdn.net/zhudaozhuan/article/details/40619371

    總結

    以上是生活随笔為你收集整理的android settings源代码分析(2)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。