settings源码中显示所有进程流程

本文详细解析了Android系统中获取正在运行进程及服务的方法。通过源码分析,介绍了如何通过ActivityManager获取运行的服务和进程列表,并展示了相关代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

源码中获得正在运行进程的简单流程:


也就是图中所看到的


首先我们看到的英是settings下的application(应用程序)下的managerApplication(管理应用程序)下的页面,那么要了解其流程,我们就得到源码中去分析:


那么我们到源码下的package/app/Settings/src/com/android/settings下去找相关代码,首先我们根据名称大概可以找到ApplicationSettings.java文件,这个显而易见


并且它加载了application_settings.xml文件,当然在application_settings.xml文件中我们也能找到管理应用程序的组件:

<PreferenceScreen
            android:title="@string/manageapplications_settings_title"
            android:summary="@string/manageapplications_settings_summary">
        <intent android:action="android.intent.action.MAIN"
                android:targetPackage="com.android.settings"
                android:targetClass="com.android.settings.ManageApplications" />
    </PreferenceScreen>

但是在ApplicationSettings.java文件中却找不到关于管理应用程序的组件的相关代码和实现的功能,因此我们再去找下有那个文件是应用程序的组件的相关代码和实现的功能,


当然我们能找到,那就是ManagerApplication.java文件,从图形界面中我们可以看到在顶端是由一个Tab,所以我们就到文件中去找这个Tab:


因此我们在Oncreate方法中找到了:

                       ................

 mStorageChartLabel = (TextView)mListContainer.findViewById(R.id.storageChartLabel);
        mUsedStorageText = (TextView)mListContainer.findViewById(R.id.usedStorageText);
        mFreeStorageText = (TextView)mListContainer.findViewById(R.id.freeStorageText);
        mRunningProcessesView = (RunningProcessesView)mRootView.findViewById(
                R.id.running_processes);

        final TabHost tabHost = getTabHost();
        tabHost.addTab(tabHost.newTabSpec(TAB_DOWNLOADED)
                .setIndicator(getString(R.string.filter_apps_third_party),
                        getResources().getDrawable(R.drawable.ic_tab_download))
                .setContent(this));
        tabHost.addTab(tabHost.newTabSpec(TAB_ALL)
                .setIndicator(getString(R.string.filter_apps_all),
                        getResources().getDrawable(R.drawable.ic_tab_all))
                .setContent(this));
        tabHost.addTab(tabHost.newTabSpec(TAB_SDCARD)
                .setIndicator(getString(R.string.filter_apps_onsdcard),
                        getResources().getDrawable(R.drawable.ic_tab_sdcard))
                .setContent(this));
        tabHost.addTab(tabHost.newTabSpec(TAB_RUNNING)
                .setIndicator(getString(R.string.filter_apps_running),
                        getResources().getDrawable(R.drawable.ic_tab_running))
                .setContent(this));
        tabHost.setCurrentTabByTag(defaultTabTag);
        tabHost.setOnTabChangedListener(this);

                     .......................


在界面中其实是由菜单键的,这我们知道,因此在其中我们可以找到 onCreateOptionsMenu(Menu menu) 方法创建菜单,onPrepareOptionsMenu准备菜单


以及相应菜单方法onOptionsItemSelected(MenuItem item) ,而在相应菜单中当我们是点击正在运行的子tab时,它的菜单项有两个,一个是显示service,一个是显示


缓存的进程:


                             .............................

else if (menuId == SHOW_RUNNING_SERVICES) {
            mRunningProcessesView.mAdapter.setShowBackground(false);
        } else if (menuId == SHOW_BACKGROUND_PROCESSES) {
            mRunningProcessesView.mAdapter.setShowBackground(true);
        }

                         .....................................

因为主要将的是获取正在运行的进程,所以其它三个子tab就不讲了,感兴趣的自己去分析吧,


那么显然这两个子菜单显示的不一样,但是无论点击那一个子菜单都会调用setShowBackground(。。。)方法。当menuId == SHOW_RUNNING_SERVICES时显示的是service,那么我们就跟踪代码下

去,mRunningProcessesView.mAdapter.setShowBackground(false),调用RunningProcessView.java中的setShowBackground(boolean showBackground) 方法


在setShowBackground中又调用了refreshItems()方法,我们看一看 :

void refreshItems() {
         //mState.getCurrentBackgroundItems() is get cache process
            //mState.getCurrentMergedItems() is get services        
            ArrayList<RunningState.MergedItem> newItems =
                mShowBackground ? mState.getCurrentBackgroundItems()
                        : mState.getCurrentMergedItems();
         
         //for(int i=0;i< mState.mBackgroundItems.size();i++)
               // Log.i("processName","processName"+ mState.mBackgroundItems.get(i));
        // Log.i("number","number="+ mState.getCurrentBackgroundItems().size());
            if (mItems != newItems) {
                mItems = newItems;
            }
            if (mItems == null) {
                mItems = new ArrayList<RunningState.MergedItem>();
            }
        }
根据mShowBackground的值,也就是mRunningProcessesView.mAdapter.setShowBackground(false)中传下来的这个boolean值来判断是显示service还是


进程。



mState.getCurrentBackgroundItems()是得到缓存进程的列表,而mState.getCurrentMergedItems() 是得到services的列表,并且他们都是来自RunningStatus.java:

             ..................................

  ArrayList<MergedItem> getCurrentMergedItems() {
        synchronized (mLock) {
            return mMergedItems;
        }
    }

    ArrayList<MergedItem> getCurrentBackgroundItems() {
        synchronized (mLock) {
            return mBackgroundItems;
        }

                .................................

那么我就来看一看怎样得到mMergedItems和mBackgroundItems的两个listView:


我们可以发现在一开是就定义了

ArrayList<MergedItem> mMergedItems = new ArrayList<MergedItem>();
 ArrayList<MergedItem> mBackgroundItems = new ArrayList<MergedItem>();


而且在private boolean update(Context context, ActivityManager am) 方法中去得到它们(具体的在这个方法中,自己仔细分析吧,我自己有也看得晕晕的):



在private boolean update(Context context, ActivityManager am) 方法中有得到当前的正在运行的服务和进程:

..........................

List<ActivityManager.RunningServiceInfo> services 
                = am.getRunningServices(MAX_SERVICES);

.............................

.............................

 List<ActivityManager.RunningAppProcessInfo> processes
                = am.getRunningAppProcesses();

........................

那么在这里就必须要提一下ActivityManager了(framework/base/core/java/android/app/ActivityManager.java):


ActivityManager是android框架的一个重要部分,它负责一新ActivityThread进程创建,Activity生命周期的维护


它提供了我们管理Activity的一些基本的方法
如下:
        public void testgetRecentTasks()
                //
获取最近的应用,最后启动的排前
        public void testgetRunningTasks()
                //
获取当前运行的Activity应用
        public void testgetRunningServices()
                //
获取当前运行的service应用
        public void testgetRunningAppProcesses()
                //
获取所用系统运行的进程

当然我们所讲的获取系统运行的进程和运行的service应用都是来自ActivityManager这个类中的方法,而且在长按home键显示最近使用的应用程序也是


使用ActivityManager类中的获取最近使用的应用程序getRecentTasks()方法。

<think>嗯,用户问的是GPS中settings开关的流程。首先,我需要确定用户指的是Android系统中的GPS设置开关流程。因为GPS在Android设备中是一个重要的功能,用户可能想了解从设置界面到实际硬件开启的过程。 接下来,我应该回忆一下Android的系统架构。GPS设置通常位于系统设置的“位置”或“位置信息”部分。当用户打开或关闭GPS开关时,系统会触发一系列的流程。这可能涉及到Settings应用、系统服务(如LocationManagerService)、以及底层硬件抽象层(HAL)的交互。 首先,用户操作的是Settings应用中的开关控件,比如SwitchPreference。当用户点击开关时,应用会调用系统的API来改变位置模式。例如,使用LocationManager的setLocationEnabled方法,或者通过Settings.Secure来修改相关设置。 然后,系统服务接收到这个请求,会进行权限检查,确保调用者有权限修改位置设置。之后,系统服务会通知相关的监听器,比如应用注册的LocationListener,并更新系统状态。 接下来,系统可能需要与底层的HAL模块通信,实际开启或关闭GPS硬件。这可能涉及到PowerManager来管理电源,确保GPS模块的供电,并启动或停止相关的硬件服务。 另外,用户可能还关心权限管理,比如应用需要哪些权限才能修改GPS设置,以及用户授权的流程。例如,需要WRITE_SECURE_SETTINGS权限,或者通过系统提示让用户授权。 还需要考虑不同Android版本之间的差异,比如在Android 6.0之后,位置权限的管理更加严格,用户可能需要在应用运行时请求权限,而不仅仅是安装时声明。 此外,可能涉及的系统组件包括Settings应用、LocationManager、LocationManagerService、HAL层的GPS模块,以及底层的Linux驱动。整个流程需要协调这些组件,确保开关状态的正确传递和硬件的正确响应。 最后,用户可能希望了解具体的代码示例或系统调用流程,比如如何通过adb命令修改设置,或者系统服务中的具体实现方法。例如,Settings.Secure.LOCATION_MODE的设置值变化如何触发底层行为。 需要验证这些步骤是否正确,可能需要查阅Android源码中的相关部分,比如LocationManagerService的实现,以及HAL层的GPS接口定义。同时,注意不同设备厂商可能对GPS流程有不同的定制,但标准Android流程应该遵循上述步骤。 总结起来,回答应该涵盖用户操作界面、系统API调用、权限检查、系统服务处理、HAL层交互以及可能的底层硬件控制。同时,需要指出关键的类和方法,比如Settings应用中的Preference处理,LocationManager的API,以及系统设置的数据库更新。</think>在Android系统中,GPS开关的流程涉及从用户界面到底层硬件的多层交互,具体流程如下: --- ### **1. 用户界面操作(Settings应用)** - **入口**:用户在系统设置的 **"位置"(Location)** 页面点击GPS开关(通常标记为"高精度"或"设备位置")。 - **实现方式**: - 开关控件(如`SwitchPreference`)绑定系统设置项(通过`Settings.Secure.LOCATION_MODE`)。 - 点击事件触发后,调用`LocationManager.setLocationEnabled()`或直接修改系统设置数据库。 --- ### **2. 系统服务层(LocationManagerService)** - **权限检查**: - 需持有`Manifest.permission.WRITE_SECURE_SETTINGS`权限(系统应用或Root权限)。 - 应用需通过`Settings.ACTION_LOCATION_SOURCE_SETTINGS`隐式Intent引导用户手动操作。 - **核心逻辑**: ```java // 修改位置模式(触发GPS开关) Settings.Secure.putInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE, Settings.Secure.LOCATION_MODE_HIGH_ACCURACY); ``` - **广播通知**: - 系统发送`LocationManager.MODE_CHANGED`广播,通知监听应用(如地图应用)位置模式变化。 --- ### **3. 硬件抽象层(HAL)与GPS模块** - **HAL接口**: - 系统通过`hardware/libhardware/include/hardware/gps.h`定义的HAL接口与GPS硬件通信。 - 标准实现路径:`/system/bin/gpsd`守护进程或厂商定制的GPS服务。 - **关键流程**: 1. **初始化**:加载`libgps.so`动态库(厂商实现)。 2. **启动GPS**:调用`gps_ops.start()`方法,初始化硬件并启动卫星搜索。 3. **数据回调**:GPS模块通过`gps_location_callback`上报定位数据。 --- ### **4. 底层驱动与电源管理** - **电源控制**: - PowerManagerService协调GPS模块供电(如控制`/sys/class/gpio/gps_en` GPIO引脚)。 - 通过`wakelock`机制保持CPU唤醒以维持GPS信号接收。 - **驱动交互**: - GPS芯片通过UART、I2C或USB接口与主控通信,驱动位于`/kernel/drivers/misc/gps/`。 --- ### **5. 权限与安全机制** - **用户授权**: - Android 6.0+要求应用在运行时请求`ACCESS_FINE_LOCATION`权限。 - 系统弹出权限请求对话框(由`AppOpsService`管理)。 - **安全限制**: - 非系统应用无法直接修改`LOCATION_MODE`,需用户主动在设置中启用。 --- ### **示例:通过ADB修改GPS开关** ```bash # 启用GPS(高精度模式) adb shell settings put secure location_mode 3 # 禁用GPS adb shell settings put secure location_mode 0 # 查询当前模式 adb shell settings get secure location_mode ``` - **模式值说明**: - `0`: 关闭 - `1`: 仅设备(GPS) - `2`: 仅网络 - `3`: 高精度(GPS+网络) --- ### **关键类与文件** - `LocationManager.java`(框架API) - `LocationManagerService.java`(系统服务实现) - `GpsLocationProvider.java`(GPS模块核心交互) - `/etc/gps.conf`(GPS配置文件,定义NTP服务器、SUPL服务器等) ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值