在TabletStatusBar.java的start()函数中,有这样关于USB的状态监听机制:
// storage
mStorageManager = (StorageManager) context.getSystemService(Context.STORAGE_SERVICE);
mStorageManager.registerListener(
new com.android.systemui.usb.StorageNotification(context));
进入StorageManager.java的registerListener去查看是怎样监听的:
public void registerListener(StorageEventListener listener) {
if (listener == null) {
return;
}
synchronized (mListeners) {
mListeners.add(new ListenerDelegate(listener));
}
}
可见所谓注册过程就是将监听类添加到监听的List表中,那么,在这个表中如何监听的?
查看ListenerDelegate:
ListenerDelegate(StorageEventListener listener) {
mStorageEventListener = listener;
mHandler = new Handler(mTgtLooper) {
@Override
public void handleMessage(Message msg) {
StorageEvent e = (StorageEvent) msg.obj;
if (msg.what == StorageEvent.EVENT_UMS_CONNECTION_CHANGED) {
UmsConnectionChangedStorageEvent ev = (UmsConnectionChangedStorageEvent) e;
mStorageEventListener.onUsbMassStorageConnectionChanged(ev.available);
} else if (msg.what == StorageEvent.EVENT_STORAGE_STATE_CHANGED) {
StorageStateChangedStorageEvent ev = (StorageStateChangedStorageEvent) e;
mStorageEventListener.onStorageStateChanged(ev.path, ev.oldState, ev.newState);
} else {
Log.e(TAG, "Unsupported event " + msg.what);
}
}
};
}
实际上就是开启一个无线循环的Handler等待消息的传送过来,到这一步自然就会想到是谁发送消息?
先插卡StorageManager类的构造函数:
public StorageManager(Looper tgtLooper) throws RemoteException {
mMountService = IMountService.Stub.asInterface(ServiceManager.getService("mount"));
if (mMountService == null) {
Log.e(TAG, "Unable to connect to mount service! - is it running yet?");
return;
}
mTgtLooper = tgtLooper;
mBinderListener = new MountServiceBinderListener();
mMountService.registerListener(mBinderListener);
}
在开启StorageManager的时候实际上就开启一个MountService,将MountServiceBinderListener注册为监听类:
它的作用是这样的:
private class MountServiceBinderListener extends IMountServiceListener.Stub {
public void onUsbMassStorageConnectionChanged(boolean available) {
final int size = mListeners.size();
for (int i = 0; i < size; i++) {
mListeners.get(i).sendShareAvailabilityChanged(available);
}
}
public void onStorageStateChanged(String path, String oldState, String newState) {
final int size = mListeners.size();
for (int i = 0; i < size; i++) {
mListeners.get(i).sendStorageStateChanged(path, oldState, newState);
}
}
}
也就是实际发送StorageEvent.EVENT_UMS_CONNECTION_CHANGED或者另外的消息:
EVENT_STORAGE_STATE_CHANGED。
那么这个监听类如何知道状态变化的?
在MountService.java中,
public void registerListener(IMountServiceListener listener) {
synchronized (mListeners) {
MountServiceBinderListener bl = new MountServiceBinderListener(listener);
try {
listener.asBinder().linkToDeath(bl, 0);
mListeners.add(bl);
} catch (RemoteException rex) {
Slog.e(TAG, "Failed to link to listener death");
}
}
}
在MountService中有一个可供守护进程调用的函数:
public boolean onEvent(int code, String raw, String[] cooked),它在有关状态发生变化时会调用相关函数,比如VolumeStateChange时,notifyShareAvailabilityChange(),而在 notifyShareAvailabilityChange()中会更新:
updatePublicVolumeState(),在这里我们看到实际就是通过Environment中相关函数判断Sd卡状态,
在这里:
synchronized (mListeners) {
for (int i = mListeners.size() -1; i >= 0; i--) {
MountServiceBinderListener bl = mListeners.get(i);
try {
bl.mListener.onStorageStateChanged(path, oldState, state);
} catch (RemoteException rex) {
Slog.e(TAG, "Listener dead");
mListeners.remove(i);
} catch (Exception ex) {
Slog.e(TAG, "Listener failed", ex);
}
}
}
也就是守护进程检测sd卡状态变化时调用StorageManager中的mBinderListener对象的onStorageStateChanged,此时在StorageManager中,就依次向需要知道Storage状态变化的目标发送消息,刚才我们说的StorageManager开启的无限循环的Handler收到消息就开始了相应处理。