摘要: 本文抛砖引玉,简述Android GPS信息获取系统调用流程。

App源代码下载目录: 


应用程序获取GPS,到底经过哪些流程,请让我为你一一呈现。


要想获取GPS信息,你先的有一台GPS设备,先的打开GPS服务,然后运行应用程序,我们首先从打开GPS服务开始。



1. 系统设置中开启GPS服务

     代码:

packages\apps\Settings\src\com\android\settings\location\LocationSettings.java 

       public class LocationSettings extends LocationSettingsBase 
 implements SwitchBar.OnSwitchChangeListener 

       { 

          private SwitchBar mSwitchBar; 

          private Switch mSwitch; 

          ... 

          @Override public void onActivityCreated(Bundle savedInstanceState) 

          { 

                 super.onActivityCreated(savedInstanceState); 

          

                 final SettingsActivity activity = (SettingsActivity) getActivity(); 

                 mUm = (UserManager) activity.getSystemService(Context.USER_SERVICE); 

          

                mSwitchBar = activity.getSwitchBar();
                 mSwitch = mSwitchBar.getSwitch(); 

                 mSwitchBar.show(); 

             } 

       } 

       

       @Override public void onResume() // Activity第一启动的时候执行onCreate()->onStart()->onResume() 

       { 

         super.onResume(); 

        createPreferenceHierarchy(); 

         if (!mValidListener) { 

            mSwitchBar.addOnSwitchChangeListener(this); 

             mValidListener = true; 

         } 

       } 


       @Override public void onPause() // 被另一个透明或者Dialog样式的Activity 覆盖时的状态。此时它依然与窗口管理器保持连接,系统继续维护其内部状态,已经失去了焦点故不可与用户交互。 

       { 

         try { 

             getActivity().unregisterReceiver(mReceiver); 

         } catch (RuntimeException e) { 

             // Ignore exceptions caused by race condition 

             if (Log.isLoggable(TAG, Log.VERBOSE)) { 

                 Log.v(TAG, "Swallowing " + e); 

             } 

         } 

         if (mValidListener) { 

             
mSwitchBar.removeOnSwitchChangeListener(this); 

             mValidListener = false; 

         } 

         super.onPause(); 

       } 

        

       private PreferenceScreen createPreferenceHierarchy() 

       { 

         final SettingsActivity activity = (SettingsActivity) getActivity(); 

         PreferenceScreen root = getPreferenceScreen(); 

         if (root != null) { 

             root.removeAll(); 

         } 

         addPreferencesFromResource(R.xml.location_settings); 

         root = getPreferenceScreen(); 


         setupManagedProfileCategory(root); 

         mLocationMode = root.findPreference(KEY_LOCATION_MODE); // private Preference mLocationMode;  //"location_mode" 

         mLocationMode.setOnPreferenceClickListener( 

                 new Preference.OnPreferenceClickListener() { 

                     @Override 

                     public boolean onPreferenceClick(Preference preference) { 

                         activity.startPreferencePanel(LocationMode.class.getName(), null, 

                                 R.string.location_mode_screen_title, null, LocationSettings.this, 0); 

                         return true; 

                     } 

                 }); 


         mAgpsEnabled = getActivity().getResources().getBoolean(R.bool.config_agps_enabled); 

         mAssistedGps = (CheckBoxPreference)root.findPreference(KEY_ASSISTED_GPS); 

         if (!mAgpsEnabled) { 

             root.removePreference(mAssistedGps); 

             mAGpsParas = (Preference) root.findPreference(KEY_ASSISTED_GPS_PARAS); 

             root.removePreference(mAGpsParas); 

         } 


         if (mAssistedGps != null) { 

             mAssistedGps.setChecked(Settings.Global.getInt(getContentResolver(), 

                     Settings.Global.ASSISTED_GPS_ENABLED, 2) == 1); 

         } 


         mCategoryRecentLocationRequests = (PreferenceCategory) root.findPreference(KEY_RECENT_LOCATION_REQUESTS); // "recent_location_requests" 

         RecentLocationApps recentApps = new RecentLocationApps(activity); 

         List<Preference> recentLocationRequests = recentApps.getAppList(); 

         if (recentLocationRequests.size() > 0) { 

             addPreferencesSorted(recentLocationRequests, mCategoryRecentLocationRequests); 

         } else { 

             // If there's no item to display, add a "No recent apps" item. 

             Preference banner = new Preference(activity); 

             banner.setLayoutResource(R.layout.location_list_no_item); 

             banner.setTitle(R.string.location_no_recent_apps); 

             banner.setSelectable(false); 

             mCategoryRecentLocationRequests.addPreference(banner); 

         } 


         boolean lockdownOnLocationAccess = false; 

         // Checking if device policy has put a location access lock-down on the managed 

         // profile. If managed profile has lock-down on location access then its 

         // injected location services must not be shown. 

         if (mManagedProfile != null 

                 && mUm.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, mManagedProfile)) { 

             lockdownOnLocationAccess = true; 

         } 

         
addLocationServices(activity, root, lockdownOnLocationAccess); 


         refreshLocationMode(); 

         return root; 

       } 

        

       private void addLocationServices(Context context, PreferenceScreen root, boolean lockdownOnLocationAccess) 

       { 

         PreferenceCategory categoryLocationServices = (PreferenceCategory) root.findPreference(KEY_LOCATION_SERVICES); // "location_services" 

         injector = new SettingsInjector(context); 

         // If location access is locked down by device policy then we only show injected settings for the primary profile. 

         List<Preference> locationServices = injector.getInjectedSettings(lockdownOnLocationAccess ? UserHandle.myUserId() : UserHandle.USER_CURRENT); 


         mReceiver = new BroadcastReceiver() { 

             @Override public void onReceive(Context context, Intent intent) { 

                 if (Log.isLoggable(TAG, Log.DEBUG)) { 

                     Log.d(TAG, "Received settings change intent: " + intent); 

                 } 

                 injector.reloadStatusMessages(); 

             } 

         }; 


         IntentFilter filter = new IntentFilter(); 

         filter.addAction(SettingInjectorService.ACTION_INJECTED_SETTING_CHANGED);  // "android.location.InjectedSettingChanged" 

         context.registerReceiver(mReceiver, filter); 


         if (locationServices.size() > 0) { 

             addPreferencesSorted(locationServices, categoryLocationServices); 

         } else { 

             // If there's no item to display, remove the whole category. 

             root.removePreference(categoryLocationServices); 

         } 

      }
 

       // Listens to the state change of the location master switch. 

       @Override public void onSwitchChanged(Switch switchView, boolean isChecked) 

       { 

         if (isChecked) { 

             setLocationMode(android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY); 

         } else { 

             setLocationMode(android.provider.Settings.Secure.LOCATION_MODE_OFF); 

         } 

       } 


      代码: packages\apps\Settings\src\com\android\settings\location\LocationSettingsBase.java 

       public void setLocationMode(int mode) 

       { 

         if (isRestricted()) { 

             if (Log.isLoggable(TAG, Log.INFO)) { 

                 Log.i(TAG, "Restricted user, not setting location mode"); 

             } 

             mode = Settings.Secure.getInt(getContentResolver(), Settings.Secure.LOCATION_MODE, 

                     Settings.Secure.LOCATION_MODE_OFF); 

             if (mActive) { 

                 onModeChanged(mode, true); 

             } 

             return; 

         } 

         Intent intent = new Intent(MODE_CHANGING_ACTION); 

         intent.putExtra(CURRENT_MODE_KEY, mCurrentMode); 

         intent.putExtra(NEW_MODE_KEY, mode); 

         getActivity().sendBroadcast(intent, android.Manifest.permission.WRITE_SECURE_SETTINGS); 

         Settings.Secure.putInt(getContentResolver(), Settings.Secure.LOCATION_MODE, mode); 

         refreshLocationMode(); 

      } 


      代码: packages\apps\Settings\src\com\android\settings\location\LocationSettings.java 

       @Override public void 
onModeChanged(int mode, boolean restricted) 

       { 

         switch (mode) { 

             case android.provider.Settings.Secure.LOCATION_MODE_OFF: 

                 mLocationMode.setSummary(R.string.location_mode_location_off_title); // private Preference mLocationMode; 

                 break; 

             case android.provider.Settings.Secure.LOCATION_MODE_SENSORS_ONLY: 

                 mLocationMode.setSummary(R.string.location_mode_sensors_only_title); 

                 break; 

             case android.provider.Settings.Secure.LOCATION_MODE_BATTERY_SAVING: 

                 mLocationMode.setSummary(R.string.location_mode_battery_saving_title); 

                 break; 

             case android.provider.Settings.Secure.LOCATION_MODE_HIGH_ACCURACY: 

                 mLocationMode.setSummary(R.string.location_mode_high_accuracy_title); 

                 break; 

             default: 

                 break; 

         } 


         final boolean enabled = (mode != android.provider.Settings.Secure.LOCATION_MODE_OFF);  // 是否打开GPS服务 


         mSwitchBar.setEnabled(!restricted); // 是否限制用户设置 

         mLocationMode.setEnabled(enabled && !restricted); 

         mCategoryRecentLocationRequests.setEnabled(enabled); 


         if (enabled != mSwitch.isChecked()) { 

             // set listener to null so that that code below doesn't trigger onCheckedChanged() 

             if (mValidListener) { 

                 mSwitchBar.removeOnSwitchChangeListener(this); 

             } 

             mSwitch.setChecked(enabled); 

             if (mValidListener) { 

                 mSwitchBar.addOnSwitchChangeListener(this); 

             } 

         } 


         if (mManagedProfilePreference != null) { 

             if (mUm.hasUserRestriction(UserManager.DISALLOW_SHARE_LOCATION, mManagedProfile)) { 

                 changeManagedProfileLocationAccessStatus(false, R.string.managed_profile_location_switch_lockdown); 

             } else { 

                 if (enabled) { 

                     changeManagedProfileLocationAccessStatus(true, R.string.switch_on_text);    // 设置界面显示: On 

                 } else { 

                     changeManagedProfileLocationAccessStatus(false, R.string.switch_off_text);  // 设置界面显示: Off 

                 } 

             } 

         } 


         // As a safety measure, also reloads on location mode change to ensure the settings are 

         // up-to-date even if an affected app doesn't send the setting changed broadcast. 

         injector.reloadStatusMessages(); 

     } 


2. 应用程序 

     为了使代码尽量简洁,省略诸多可靠性判断语句,本代码测试前,请先打开设备的GPS功能。 

     下面是最简单的获取GPS信息的应用程序代码,只需要android.permission.ACCESS_FINE_LOCATION权限。 

     MainActivity.java代码: 

     package com.tom.tomgpstest; 


         import android.app.Activity; 

         import android.content.Context; 

         import android.location.Location; 

         import android.location.LocationManager; 

         import android.os.Bundle; 

         import android.widget.EditText; 

          

         public class MainActivity extends Activity 

         {   

             @Override 

             public void onCreate(Bundle savedInstanceState) 

             { 

                 super.onCreate(savedInstanceState); 

                 setContentView(R.layout.activity_main); 

                  

                 LocationManager lm = (LocationManager) 
getSystemService(Context.LOCATION_SERVICE); // public static final String LOCATION_SERVICE = "location"; 

                 

                 Location location= lm. 
getLastKnownLocation(LocationManager.GPS_PROVIDER); 

                  

                 if(location!=null) 

                 { 

                     EditText editText = (EditText)findViewById(R.id.editText); 

                      

                     editText.append("\n经度:"); 

                     editText.append(String.valueOf(location. 
getLongitude())); 

                     editText.append("\n纬度:"); 

                     editText.append(String.valueOf(location.getLatitude())); 

                     editText.append("\n海拔:"); 

                     editText.append(String.valueOf(location.getAltitude())); 

                 }     

             }   

         } 

     代码最重要的一行是:LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);从系统服务中获取LocationManager服务。 

     于是我们追踪LOCATION_SERVICE服务。 

          

     注: getSystemService这个方法基于context,只有存在TextView控件的窗体中这个方法才会被激活     

      

3. LOCATION_SERVICE服务 

      代码: frameworks\base\core\java\android\app\Activity.java 

         @Override public Object getSystemService(@ServiceName @NonNull String name) 

         { 

             if (getBaseContext() == null) { 

                 throw new IllegalStateException("System services not available to Activities before onCreate()"); 

             } 

      

             if (WINDOW_SERVICE.equals(name)) // public static final String WINDOW_SERVICE = "window"; 

             { 

                 return mWindowManager; 

             } 

             else if (SEARCH_SERVICE.equals(name))  // public static final String SEARCH_SERVICE = "search"; 

             { 

                 ensureSearchManager(); 

                 return mSearchManager; 

             } 

              

             return 
 super.getSystemService(name);  // Context.LOCATION_SERVICE调用本行 

         } 

       Activity继承ContextThemeWrapper,ContextThemeWrapper继承ContextWrapper。ContextWrapper.getSystemService()里面调用mBase.getSystemService()。 

       ContextWrapper中mBase是一个ContextImpl实例变量。 

      代码: frameworks\base\core\java\android\app\ContextImpl.java 

         private static final HashMap<String, ServiceFetcher> SYSTEM_SERVICE_MAP = new HashMap<String, ServiceFetcher>(); 

         ... 

         @Override public Object getSystemService(String name) 

         { 

             ServiceFetcher fetcher = SYSTEM_SERVICE_MAP.get(name); // "location"已在其中 

             return fetcher == null ? null : fetcher.getService(this); // 从后面分析可知,"location"的fetcher是LocationManager的一个实例 

         } 

         ... 

         static class ServiceFetcher 

         { 

         int mContextCacheIndex = -1; 


         public Object 
getService(ContextImpl ctx) 

         { 

             ArrayList<Object> cache = ctx.mServiceCache; 

             Object service; 

             synchronized (cache) { 

                 if (cache.size() == 0) { 

                     // Initialize the cache vector on first access. 

                     // At this point sNextPerContextServiceCacheIndex 

                     // is the number of potential services that are 

                     // cached per-Context. 

                     for (int i = 0; i < sNextPerContextServiceCacheIndex; i++) { 

                         cache.add(null); 

                     } 

                 } else { 

                     service = cache.get(mContextCacheIndex); 

                     if (service != null) { 

                         return service; 

                     } 

                 } 

                 service = createService(ctx); 

                 cache.set(mContextCacheIndex, service); 

                 return service; 

             } 

           } 


           public Object createService(ContextImpl ctx) { 

             throw new RuntimeException("Not implemented"); 

           } 

           } 

             ... 

             
 static // 用static修饰的代码块表示静态代码块,当Java虚拟机(JVM)加载类时,就会执行该代码块。 

             { 

               ... 

               registerService(LOCATION_SERVICE, new ServiceFetcher() { 

                   public Object createService(ContextImpl ctx) { 

                       IBinder b = ServiceManager.getService(LOCATION_SERVICE); 

                       return 
new LocationManager(ctx, ILocationManager.Stub.asInterface(b)); 

                   }}); 

               ... 

            }       

            ... 

              private static void 
registerService(String serviceName, ServiceFetcher fetcher) { 

                     if (!(fetcher instanceof StaticServiceFetcher)) { 

                         fetcher.mContextCacheIndex = sNextPerContextServiceCacheIndex++; 

                     } 

                     SYSTEM_SERVICE_MAP. 
put(serviceName, fetcher); 

              } 

      

    ServiceManager.getService()代码: frameworks\base\core\java\android\os\ServiceManager.java 

         public static IBinder getService(String name) 

         { 

             try { 

                 IBinder service = sCache.get(name); 

                 if (service != null) { 

                     return service; 

                 } else { 

                     return getIServiceManager().getService(name);  // 不再往下追踪了 

                 } 

             } catch (RemoteException e) { 

                 Log.e(TAG, "error in getService", e); 

             } 

             return null; 

         } 

              


4. LocationManager.getLastKnownLocation() 

     代码: frameworks\base\location\java\android\location\LocationManager.java 

           public class LocationManager 

           { 

         private final ILocationManager mService; 

             ... 

             public Location getLastKnownLocation(String provider) 

             { 

                 checkProvider(provider); 

                 String packageName = mContext.getPackageName(); 

                 LocationRequest request = LocationRequest.createFromDeprecatedProvider(provider, 0, 0, true); 

          

                 try { 

                     return 
 mService.getLastLocation(request, packageName); 

                 } catch (RemoteException e) { 

                     Log.e(TAG, "RemoteException", e); 

                     return null; 

                 } 

             } 

             ... 

             } 



     代码: frameworks\base\services\core\java\com\android\server\LocationManagerService.java           

       private final HashMap<String, Location> mLastLocation = new HashMap<String, Location>(); 

       ... 

             @Override public Location getLastLocation(LocationRequest request, String packageName) 

             { 

             if (D) Log.d(TAG, "getLastLocation: " + request); 

             if (request == null) request = DEFAULT_LOCATION_REQUEST; 

             int allowedResolutionLevel = getCallerAllowedResolutionLevel(); 

             checkPackageName(packageName); 

             checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel, request.getProvider()); 

             // no need to sanitize this request, as only the provider name is used 

      

             final int uid = Binder.getCallingUid(); 

             final long identity = Binder.clearCallingIdentity(); 

             try { 

                 if (mBlacklist.isBlacklisted(packageName)) { 

                     if (D) Log.d(TAG, "not returning last loc for blacklisted app: " + packageName); 

                     return null; 

                 } 

      

                 if (!reportLocationAccessNoThrow(uid, packageName, allowedResolutionLevel)) { 

                     if (D) Log.d(TAG, "not returning last loc for no op app: " + packageName); 

                     return null; 

                 } 

      

                 synchronized (mLock) { 

                     // Figure out the provider. Either its explicitly request (deprecated API's), 

                     // or use the fused provider 

                     String name = request.getProvider(); 

                     if (name == null) name = LocationManager.FUSED_PROVIDER; 

                     LocationProviderInterface provider = mProvidersByName.get(name); 

                     if (provider == null) return null; 

      

                     if (!isAllowedByUserSettingsLocked(name, uid)) return null; 

      

                     Location location; 

                     if (allowedResolutionLevel < RESOLUTION_LEVEL_FINE) { 

                         // Make sure that an app with coarse permissions can't get frequent location 

                         // updates by calling LocationManager.getLastKnownLocation repeatedly. 

                         location = 
mLastLocationCoarseInterval.get(name);  // 获取更新慢的Location //  private final HashMap<String, Location> mLastLocationCoarseInterval = new HashMap<String, Location>(); 

                     } else { 

                         location = 
mLastLocation.get(name);  // 获取Location //private final HashMap<String, Location> mLastLocation = new HashMap<String, Location>(); 

                     } 

                     if (location == null) { 

                         return null; 

                     } 

                     if (allowedResolutionLevel < RESOLUTION_LEVEL_FINE) { 

                         Location noGPSLocation = location.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION); 

                         if (noGPSLocation != null) { 

                             return new Location(mLocationFudger.getOrCreate(noGPSLocation));   // 返回Location 

                         } 

                     } else { 

                         return new Location(location); // 返回Location 

                     } 

                 } 

                 return null; 

             } finally { 

                 Binder.restoreCallingIdentity(identity); 

             } 

       } 


              

5. Location.getLongitude() 

     代码: frameworks\base\location\java\android\location\LocationManager.java 

       public class Location implements Parcelable 

       { 

         ... 

                 public double 
getLongitude() 

                 { 

                 return mLongitude; 

             } 

             ... 

           } 

     注: base\services\core\java\com\android\server\location\GpsLocationProvider.java中reportLocation(),buildLocation()调用了setLongitude(). 

      

      

      

附录: SystemServer中LOCATION_SERVICE服务 

      代码: frameworks\base\services\java\com\android\server\SystemServer.java 

    在startOtherServices()函数中,LOCATION_SERVICE服务被加入服务列表之中: 

             if (!disableLocation) 

             { 

                 try { 

                     Slog.i(TAG, "Location Manager"); 

                     location = new LocationManagerService(context); 

                     ServiceManager.addService(Context.LOCATION_SERVICE, location); 

                 } catch (Throwable e) { 

                     reportWtf("starting Location Manager", e); 

                 }             

                ...
                 final LocationManagerService locationF = location;                ...        
                mActivityManagerService.systemReady(new Runnable()
                {
                    @Override  public void run() {
                           ...                            try {
                                  if (locationF != null) locationF.systemRunning();
                           } catch (Throwable e) {
                                  reportWtf("Notifying Location Service running", e);                           }
                          ...   
                          }                  }
    addService()代码:frameworks\base\services\core\java\com\android\server\LocationManagerService.java
systemRunning()
         {
             synchronized (mLock)
             {
                 if (D) Log.d(TAG, "systemReady()");
     
                 // fetch package manager
                 mPackageManager = mContext.getPackageManager();
     
                 // fetch power manager
                 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
     
                 // prepare worker thread
                 mLocationHandler = new LocationWorkerHandler(BackgroundThread.get().getLooper());
     
                 // prepare mLocationHandler's dependents
                 mLocationFudger = new LocationFudger(mContext, mLocationHandler);
                 mBlacklist = new LocationBlacklist(mContext, mLocationHandler);
                 mBlacklist.init();
                 mGeofenceManager = new GeofenceManager(mContext, mBlacklist);
     
                 // Monitor for app ops mode changes.
                 AppOpsManager.OnOpChangedListener callback
                         = new AppOpsManager.OnOpChangedInternalListener() {
                     public void onOpChanged(int op, String packageName) {
                         synchronized (mLock) {
                             for (Receiver receiver : mReceivers.values()) {
                                 receiver.updateMonitoring(true);
                             }
                             applyAllProviderRequirementsLocked();
                         }
                     }
                 };
                 mAppOps.startWatchingMode(AppOpsManager.OP_COARSE_LOCATION, null, callback);
     
                 mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
                 updateUserProfiles(mCurrentUserId);
     
                // prepare providers
                 loadProvidersLocked();  // 执行gpsProvider = new GpsLocationProvider(...),静态块class_init_native()被调用,对应frameworks\base\services\core\com_android_server_location_GpsLocationProvider.cpp, android_location_GpsLocationProvider_class_init_native(),其中执行hw_get_module("gps",...),我的代码hardware\qcom\gps\loc_api\libloc_api_50001\gps.c中构建了gps模块(知道了硬件代码实现位置),获取gps_device_t* gps_device = (gps_device_t *)device; sGpsInterface = gps_device->get_gps_interface(gps_device);
                 updateProvidersLocked();  // 调用GpsLocationProvider.enable(),引发handleEnable(),运行native_init(),对应android_location_GpsLocationProvider_init()),与native层通信,不再细究
             }
     
             // listen for settings changes
             mContext.getContentResolver().registerContentObserver(
                     Settings.Secure.getUriFor(Settings.Secure.LOCATION_PROVIDERS_ALLOWED), true,
                     new ContentObserver(mLocationHandler) {
                         @Override
                         public void onChange(boolean selfChange) {
                             synchronized (mLock) {
                                 updateProvidersLocked();
                             }
                         }
                     }, UserHandle.USER_ALL);
             mPackageMonitor.register(mContext, mLocationHandler.getLooper(), true);
     
             // listen for user change
             IntentFilter intentFilter = new IntentFilter();
             intentFilter.addAction(Intent.ACTION_USER_SWITCHED);
             intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED);
             intentFilter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED);
     
             mContext.registerReceiverAsUser(new BroadcastReceiver()
             {
                 @Override
                 public void onReceive(Context context, Intent intent) {
                     String action = intent.getAction();
                     if (Intent.ACTION_USER_SWITCHED.equals(action)) {
                         switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0));
                     } else if (Intent.ACTION_MANAGED_PROFILE_ADDED.equals(action)
                             || Intent.ACTION_MANAGED_PROFILE_REMOVED.equals(action)) {
                         updateUserProfiles(mCurrentUserId);
                     }
                 }
             }, UserHandle.ALL, intentFilter, null,  mLocationHandler);
         }        ...
       private void loadProvidersLocked()
       {
             // create a passive location provider, which is always enabled
             PassiveProvider passiveProvider = new PassiveProvider(this);
             addProviderLocked(passiveProvider);
             mEnabledProviders.add(passiveProvider.getName());
             mPassiveProvider = passiveProvider;
             // Create a gps location provider
             GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this,
                     mLocationHandler.getLooper());
     
             if (GpsLocationProvider.isSupported()) {
                 mGpsStatusProvider = gpsProvider.getGpsStatusProvider();
                 mNetInitiatedListener = gpsProvider.getNetInitiatedListener();
                 addProviderLocked(gpsProvider);
                 mRealProviders.put(LocationManager.GPS_PROVIDER, gpsProvider);
             }
             mGpsMeasurementsProvider = gpsProvider.getGpsMeasurementsProvider();
             mGpsNavigationMessageProvider = gpsProvider.getGpsNavigationMessageProvider();            ...
       }
    addService()代码: frameworks\base\core\java\android\os\ServiceManager.java
             public final class ServiceManager 

             { 

               ... 

             public static void addService(String name, IBinder service) 

             { 

                 try { 

                     getIServiceManager().addService(name, service, false); 

                 } catch (RemoteException e) { 

                     Log.e(TAG, "error in addService", e); 

                 } 

             } 

              

                 private static IServiceManager getIServiceManager() 

                 { 

                     if (sServiceManager != null) { 

                         return sServiceManager; 

                     } 

                  

                     // Find the service manager 

                     sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); 

                     return sServiceManager; 

                 } 

                 ... 

           } 

     asInterface()代码: frameworks\base\core\java\android\os\ServiceManagerNative.java 

             public abstract class ServiceManagerNative extends Binder implements IServiceManager 

             { 

               ... 

             static public IServiceManager asInterface(IBinder obj) 

             { 

                 if (obj == null) { 

                     return null; 

                 } 

                 IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor); 

                 if (in != null) { 

                     return in; 

                 } 

                  

                 return new ServiceManagerProxy(obj); 

             } 

             ... 

             public void addService(String name, IBinder service, boolean allowIsolated) throws RemoteException 

             { 

                 Parcel data = Parcel.obtain();  // 从sOwnedPool取回一个新的Parcel对象 

                 Parcel reply = Parcel.obtain(); 

                 data.writeInterfaceToken(IServiceManager.descriptor);  // 实现在frameworks\base\core\jni\android_os_Parcel.cpp 

                 data.writeString(name); 

                 data.writeStrongBinder(service); 

                 data.writeInt(allowIsolated ? 1 : 0); 

                 mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);  // private IBinder mRemote; 

                 reply.recycle(); 

                 data.recycle(); 

             } 

             ... 

           } 

           说明:Parcel定义: 

             public final class Parcel 

             { 

               ... 

                 private static final Parcel[] sOwnedPool = new Parcel[POOL_SIZE]; 

                 private static final Parcel[] sHolderPool = new Parcel[POOL_SIZE]; 

                 ... 

             } 


       IServiceManager代码: frameworks\base\core\java\android\os\IServiceManager.java 

           public interface IServiceManager extends IInterface 

           { 

               ... 

               public void addService(String name, IBinder service, boolean allowIsolated) throws RemoteException; 

               ... 

               static final String descriptor = "android.os.IServiceManager"; 

               ... 

           }