前面六篇文章:
前面六篇文章从底向上分析了SD卡挂载的流程,前面五篇文章主要是从底层往上,而第六篇文章则反其道而行之,从上层的设置界面开始往下分析,那么本篇文章会是一个引爆点,也就是说,这篇文章是从下往上和从上往下的一个交接处。因为过了段时间了,我们需要总结一下前面的文章,权当复习吧。哈哈,还是先祭处我们的老老图(T_T...)如下:
这是SD卡挂载的整个流程图,首先插入SD卡后,触发硬件中断,Kernel发出uevent;其次通过NetLinkManager初步处理接收到的uevent然后往上传递处理之后的事件信息;然后VolumeManager接着处理经过初步处理之后的时间信息并将信息进行更细致的划分和处理并传递给上层;最后上层接收到SD卡挂载后的信息并显示在界面上。
以上就是整个SD卡挂载的大致流程,下面是大致的流程图:
废话不多说,从这张图大家应该可以理解SD卡的挂载了吧。那么前面五篇博文从底向上,从Kernel发出的uevent一直到Vold,而第六篇博文则是从Setting开始一直到MountService,那么本文主要则描述底层信息最后是如何传递到上层的。如果大家遗忘了的话,还请看看前面的文章。
在第五篇博文中,我们分析到了MountService中的private void updatePublicVolumeState(String path, String state)方法,在该方法中我们当时只分析到了:
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的存储设备状态变更监听器来实现的,如下代码:
if (mStorageManager == null) {
mStorageManager = (StorageManager) getSystemService(Context.STORAGE_SERVICE);
mStorageManager.registerListener(mStorageListener);
}
那么也就是说,如果要通知到上层改变SD卡的挂载状态,底层的信息一定会触发上层注册的监听器,那么我就开始我们的旅程吧!
1.踏上征程
我们先继续查看MountService中的private void updatePublicVolumeState(String path, String state)方法中的同步块中的方法:
Mou