RemoteListenerManager.java
上传用户:szyujian
上传日期:2016-09-20
资源大小:320k
文件大小:3k
源码类别:

android开发

开发平台:

C/C++

  1. /*
  2.  * Copyright (C) 2007-2008 Esmertec AG.
  3.  * Copyright (C) 2007-2008 The Android Open Source Project
  4.  *
  5.  * Licensed under the Apache License, Version 2.0 (the "License");
  6.  * you may not use this file except in compliance with the License.
  7.  * You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package com.android.im.service;
  18. import java.util.ArrayList;
  19. import java.util.concurrent.CopyOnWriteArrayList;
  20. import android.os.RemoteException;
  21. import android.os.IInterface;
  22. import android.util.Log;
  23. /**
  24.  * Manages and notifies remote listeners.
  25.  *
  26.  * @param <E>
  27.  */
  28. class RemoteListenerManager<E extends IInterface> {
  29.     private static final String TAG = RemoteImService.TAG;
  30.     private final CopyOnWriteArrayList<E> mRemoteListeners;
  31.     public RemoteListenerManager() {
  32.         mRemoteListeners = new CopyOnWriteArrayList<E>();
  33.     }
  34.     public void addRemoteListener(E listener) {
  35.         mRemoteListeners.add(listener);
  36.     }
  37.     public void removeRemoteListener(E listener) {
  38.         // we may have duplicated listeners, or different listeners that
  39.         // are actually a same binder.
  40.         ArrayList<E> listeners = new ArrayList<E>();
  41.         for (E remoteListener : mRemoteListeners) {
  42.             if (remoteListener.asBinder() == listener.asBinder()) {
  43.                 listeners.add(remoteListener);
  44.             }
  45.         }
  46.         if (!listeners.isEmpty()) {
  47.             mRemoteListeners.removeAll(listeners);
  48.         }
  49.     }
  50.     /* This method does not hold a lock on the listener list during the
  51.      * traversal in order not to block {@link #addRemoteListener(E)} or
  52.      * {@link #removeRemoteListener(E)}.
  53.      */
  54.     protected boolean notifyRemoteListeners(ListenerInvocation<E> invocation) {
  55.         boolean notified = false;
  56.         ArrayList<E> deadListeners = null;
  57.         for (E remoteListener : mRemoteListeners) {
  58.             try {
  59.                 invocation.invoke(remoteListener);
  60.                 notified = true;
  61.             } catch (RemoteException e) {
  62.                 Log.i(TAG, remoteListener.getClass().getName()
  63.                         + ": removing dead listener ");
  64.                 if (deadListeners == null) {
  65.                     deadListeners = new ArrayList<E>();
  66.                 }
  67.                 deadListeners.add(remoteListener);
  68.             }
  69.         }
  70.         if (deadListeners != null) {
  71.             mRemoteListeners.removeAll(deadListeners);
  72.         }
  73.         return notified;
  74.     }
  75.     // a simplified solution for java.reflect.Method
  76.     static interface ListenerInvocation<E extends IInterface > {
  77.         public void invoke(E remoteListener) throws RemoteException;
  78.     }
  79. }