MediaScanner分析
一 MediaScannerService
多媒体扫描是从MediaScannerService开始的。这是一个单独的package。位于
packagesprovidersMediaProvider:含以下java文件
l MediaProvider.java
l MediaScannerReceiver.java
l MediaScannerService.java
l MediaThumbRequest.java
分析这个目录的Android.mk文件,发现它运行的进程名字就是android.process.media。
application android:process=android.process.media
1.1 MediaScannerReceiver
这个类从BroadcastReceiver中派生,用来接收任务的。
MediaScannerReceiver extends BroadcastReceiver
在它重载的onRecieve函数内有以下几种走向:
java代码:
if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
// 收到”启动完毕“广播后,扫描内部存储
scan(context, MediaProvider.INTERNAL_VOLUME);
} else {
if (action.equals(Intent.ACTION_MEDIA_MOUNTED) &&
externalStoragePath.equals(path)) {
//收到MOUNT信息后,扫描外部存储
scan(context, MediaProvider.EXTERNAL_VOLUME);
}
else if (action.equals(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE) &&
path != null && path.startsWith(externalStoragePath + "/")) {
//收到请求要求扫描某个文件,注意不会扫描内部存储上的文件
scanFile(context, path);
}
复制代码
下面是它调用的scan函数:
java代码:
scan(Context context, String volume)
Bundle args = new Bundle();
args.putString("volume", volume);
//直接启动MediaScannerService了,
context.startService(
new Intent(context, MediaScannerService.class).putExtras(args));
复制代码
总结: MediaScannerReceiver是用来接收任务的,它收到广播后,会启动MediaService进行扫描工作。
1.2 MediaScannerService
MSS标准的从Service中派生下来,
MediaScannerService extends Service implements Runnable
//注意:是一个Runnable…,可能有线程之类的东西存在
下面从Service的生命周期的角度来看看它的工作。
1. onCreate
java代码:
public void onCreate()
PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
//获得电源锁,防止在扫描过程中休眠
//单独搞一个线程去跑扫描工作,防止ANR
Thread thr = new Thread(null, this, "MediaScannerService");
thr.start();
复制代码
2. onStartCommand
java代码:
@Override
public int onStartCommand(Intent intent, int flags, int startId){
//注意这个handler,是在另外一个线程中创建的,往这个handler里sendMessage
//都会在那个线程里边处理
//不明白的可以去查看handler和Looper机制
//这里就是同步机制,等待mServiceHandler在另外那个线程创建完毕
while (mServiceHandler == null) {
synchronized (this) {
try {
wait(100);
} catch (InterruptedException e) {
}
}
}
if (intent == null) {
Log.e(TAG, "Intent is null in onStartCommand: ",new NullPointerException());
return Service.START_NOT_STICKY;
}
Message msg = mServiceHandler.obtainMessage();
msg.arg1 = startId;
msg.obj = intent.getExtras();
//把MediaScannerReceiver发出的消息传递到另外那个线程去处理。
mServiceHandler.sendMessage(msg);
复制代码
基本上MSR(MediaScannerReceiver)发出的请求都会传到onStartCommand中处理。如果有多个存储的话,也只能一个一个扫描了。
文章来自: 安卓手机网(www.anzhuopp.com) 详文参考:http://www.anzhuopp.com/Androidshouji/3043/