Android系統中的LocalService

Google将service分成binderservice和localservice。如果service只在本进程使用,则可以将这个service发布为localservice,避免进程间通信。

1 Localservice的定義實現

下面以DeviceStorageMonitorService來解說,該service繼承自SystemService,通過publishLocalService发布为localservice

android/frameworks/base/services/core/java/com/android/server/SystemService.java

 public abstract class SystemService {
      public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // maybe should be a dependency?
      public static final int PHASE_LOCK_SETTINGS_READY = 480;
60      /**
61       * After receiving this boot phase, services can safely call into core system services
62       * such as the PowerManager or PackageManager.
63       */
64      public static final int PHASE_SYSTEM_SERVICES_READY = 500;
66      /**
67       * After receiving this boot phase, services can broadcast Intents.
68       */
69      public static final int PHASE_ACTIVITY_MANAGER_READY = 550;
71      /**
72       * After receiving this boot phase, services can start/bind to third party apps.
73       * Apps will be able to make Binder calls into services at this point.
74       */
75      public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600;
83      public static final int PHASE_BOOT_COMPLETED = 1000;
85      private final Context mContext;
96      public SystemService(Context context) {
97          mContext = context;
98      }
100      /**
101       * Gets the system context.
102       */
103      public final Context getContext() {
104          return mContext;
105      }
106  
107      /**
108       * Get the system UI context. This context is to be used for displaying UI. It is themable,
109       * which means resources can be overridden at runtime. Do not use to retrieve properties that
110       * configure the behavior of the device that is not UX related.
111       */
112      public final Context getUiContext() {
113          // This has already been set up by the time any SystemServices are created.
114          return ActivityThread.currentActivityThread().getSystemUiContext();
115      }
117      /**
118       * Returns true if the system is running in safe mode.
119       * TODO: we should define in which phase this becomes valid
120       */
121      public final boolean isSafeMode() {
122          return getManager().isSafeMode();
123      }
124  
125      /**
126       * Called when the dependencies listed in the @Service class-annotation are available
127       * and after the chosen start phase.
128       * When this method returns, the service should be published.
129       */
130      public abstract void onStart();
138      public void onBootPhase(int phase) {}
145      public void onStartUser(int userHandle) {}
161      public void onUnlockUser(int userHandle) {}
169      public void onSwitchUser(int userHandle) {}
181      public void onStopUser(int userHandle) {}
193      public void onCleanupUser(int userHandle) {}
195      /**
196       * Publish the service so it is accessible to other services and apps.
197       */
198      protected final void publishBinderService(String name, IBinder service) {
199          publishBinderService(name, service, false);
200      }
201  
202      /**
203       * Publish the service so it is accessible to other services and apps.
204       */
205      protected final void publishBinderService(String name, IBinder service,
206              boolean allowIsolated) {
207          ServiceManager.addService(name, service, allowIsolated);
208      }
209  
210      /**
211       * Get a binder service by its name.
212       */
213      protected final IBinder getBinderService(String name) {
214          return ServiceManager.getService(name);
215      }
216  
217      /**
218       * Publish the service so it is only accessible to the system process.
219       */
220      protected final <T> void publishLocalService(Class<T> type, T service) {
221          LocalServices.addService(type, service);
222      }
224      /**
225       * Get a local service by interface.
226       */
227      protected final <T> T getLocalService(Class<T> type) {
228          return LocalServices.getService(type);
229      }
230  
231      private SystemServiceManager getManager() {
232          return LocalServices.getService(SystemServiceManager.class);
233      }
234  }

在SystemService中和local service 有关的就三个函数,其中外界只能使用getLocalService 和 publishLocalService。getManager 是SystemService 自己使用的 ;通常在onStart()中發佈service。

android/frameworks/base/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java

/**
65   * Service that monitors and maintains free space on storage volumes.
66   * <p>
67   * As the free space on a volume nears the threshold defined by
68   * {@link StorageManager#getStorageLowBytes(File)}, this service will clear out
69   * cached data to keep the disk from entering this low state.
70   */
71  public class DeviceStorageMonitorService extends SystemService {
72      private static final String TAG = "DeviceStorageMonitorService";
        ......
80      private static final int MSG_CHECK = 1;
        ......
         /**
158       * Handler that checks the amount of disk space on the device and sends a
159       * notification if the device runs low on disk space
160       */
161      private final Handler mHandler = new Handler(IoThread.get().getLooper()) {
162          @Override
163          public void handleMessage(Message msg) {
164              switch (msg.what) {
165                  case MSG_CHECK:
166                      check();
167                      return;
168              }
169          }
170      };
         public DeviceStorageMonitorService(Context context) {
258          super(context);
259      }
         //實現onStart()
         @Override
271      public void onStart() {
272          final Context context = getContext();
273          mNotifManager = context.getSystemService(NotificationManager.class);
274  
275          mCacheFileDeletedObserver = new CacheFileDeletedObserver();
276          mCacheFileDeletedObserver.startWatching();
277  
278          // Ensure that the notification channel is set up
279          PackageManager packageManager = context.getPackageManager();
280          boolean isTv = packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
281  
282          if (isTv) {
283              mNotifManager.createNotificationChannel(new NotificationChannel(
284                      TV_NOTIFICATION_CHANNEL_ID,
285                      context.getString(
286                          com.android.internal.R.string.device_storage_monitor_notification_channel),
287                      NotificationManager.IMPORTANCE_HIGH));
288          }
289          //發佈 binderservice
290          publishBinderService(SERVICE, mRemoteService);
             //發佈localservice
291          publishLocalService(DeviceStorageMonitorInternal.class, mLocalService);
292  
293          // Kick off pass to examine storage state
294          mHandler.removeMessages(MSG_CHECK);
295          mHandler.obtainMessage(MSG_CHECK).sendToTarget();
296      }

         private final DeviceStorageMonitorInternal mLocalService = new DeviceStorageMonitorInternal() {
299          @Override
300          public void checkMemory() {
301              // Kick off pass to examine storage state
302              mHandler.removeMessages(MSG_CHECK);
303              mHandler.obtainMessage(MSG_CHECK).sendToTarget();
304          }
305  
306          @Override
307          public boolean isMemoryLow() {
308              return Environment.getDataDirectory().getUsableSpace() < getMemoryLowThreshold();
309          }
310  
311          @Override
312          public long getMemoryLowThreshold() {
313              return getContext().getSystemService(StorageManager.class)
314                      .getStorageLowBytes(Environment.getDataDirectory());
315          }
316      };
317  
318      private final Binder mRemoteService = new Binder() {
319          @Override
320          protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
321              if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
322              dumpImpl(fd, pw, args);
323          }
324  
325          @Override
326          public void onShellCommand(FileDescriptor in, FileDescriptor out,
327                  FileDescriptor err, String[] args, ShellCallback callback,
328                  ResultReceiver resultReceiver) {
329              (new Shell()).exec(this, in, out, err, args, callback, resultReceiver);
330          }
331      };
332  

DeviceStorageMonitorInternal.java接口的定義:

android/frameworks/base/services/core/java/com/android/server/storage/DeviceStorageMonitorInternal.java

17  package com.android.server.storage;
18  
19  public interface DeviceStorageMonitorInternal {
20      boolean isMemoryLow();
21      long getMemoryLowThreshold();
22      void checkMemory();
23  }

2 Localservice的使用

我們看下PackageManagerService中對DeviceStorageMonitorService發佈的localservice的使用
通過final class LocalServices獲取getService(DeviceStorageMonitorInternal.class)獲取localservice的實例dsm,然後調用其方法 dsm.checkMemory()

frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java

 
20257      @Override
20258      public void clearApplicationUserData(final String packageName,
20259              final IPackageDataObserver observer, final int userId) {
               // Queue up an async operation since the package deletion may take a little while.
20276          mHandler.post(new Runnable() {
20277              public void run() {
20278                  mHandler.removeCallbacks(this);
20279                  final boolean succeeded;
20280                  try (PackageFreezer freezer = freezePackage(packageName,
20281                          "clearApplicationUserData")) {
20282                      synchronized (mInstallLock) {
20283                          succeeded = clearApplicationUserDataLIF(packageName, userId);
20284                      }
20285                      clearExternalStorageDataSync(packageName, userId, true);
20286                      synchronized (mPackages) {
20287                          mInstantAppRegistry.deleteInstantApplicationMetadataLPw(
20288                                  packageName, userId);
20289                      }
20290                  }
20291                  if (succeeded) {
20292                      // invoke DeviceStorageMonitor's update method to clear any notifications
20293                      DeviceStorageMonitorInternal dsm = LocalServices
20294                              .getService(DeviceStorageMonitorInternal.class);
20295                      if (dsm != null) {
20296                          dsm.checkMemory();
20297                      }
20298                  }
20299                  if(observer != null) {
20300                      try {
20301                          observer.onRemoveCompleted(packageName, succeeded);
20302                      } catch (RemoteException e) {
20303                          Log.i(TAG, "Observer no longer exists.");
20304                      }
20305                  } //end if observer
20306              } //end run
20307          });

發佈localservice實際是調用LocalServices.addService(), 放入一個靜態數組中sLocalServiceObjects ,而getService 也是以class type爲key从sLocalServiceObjects 数组中拿到是实现的class

android/frameworks/base/core/java/com/android/server/LocalServices.java

 public final class LocalServices {
33      private LocalServices() {}
34  
35      private static final ArrayMap<Class<?>, Object> sLocalServiceObjects =
36              new ArrayMap<Class<?>, Object>();
37  
38      /**
39       * Returns a local service instance that implements the specified interface.
40       *
41       * @param type The type of service.
42       * @return The service object.
43       */
44      @SuppressWarnings("unchecked")
45      public static <T> T getService(Class<T> type) {
46          synchronized (sLocalServiceObjects) {
47              return (T) sLocalServiceObjects.get(type);
48          }
49      }
50  
51      /**
52       * Adds a service instance of the specified interface to the global registry of local services.
53       */
54      public static <T> void addService(Class<T> type, T service) {
55          synchronized (sLocalServiceObjects) {
56              if (sLocalServiceObjects.containsKey(type)) {
57                  throw new IllegalStateException("Overriding service registration");
58              }
59              sLocalServiceObjects.put(type, service);
60          }
61      }
62  
......
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安德路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值