Android Mediascannerservice Source Analysis
Last Update:2015-07-03
Source: Internet
Author: User
<span id="Label3"></p>1. Introduction<p><p>Mediascannerservice abbreviated mss, is a service running in the background, the implementation of the runnable Interface.<br>Mediascannerreceiver receives the broadcast and then completes the work by MSS. The main work in MSS is implemented in Servicehandler</p></p>2. Initialize 2.1 onCreate ()<p><p>Complete 2 Jobs<br><strong>(1) Start Thread</strong></p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs sql"> <span class="hljs-operator"><span class="hljs-keyword">Start</span> up the thread running the service. Note that we <span class="hljs-keyword">create</span> a // separate thread because the service normally runs <span class="hljs-keyword">in</span> the process<span class="hljs-string">‘s // main thread, which we don‘</span>t want <span class="hljs-keyword">to</span> block. Thread thr = new Thread(<span class="hljs-keyword">null</span>, this, <span class="hljs-string">"MediaScannerService"</span>);</span> thr.<span class="hljs-operator"><span class="hljs-keyword">start</span>();</span></code></pre></pre><p><p>The Run method is then called, see 2.2<br><strong>(2) register/monitor SDcard Uninstall Event</strong></p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs vbscript"> <span class="hljs-built_in">filter</span><span class="hljs-keyword">new</span> IntentFilter(Intent.ACTION_MEDIA_EJECT); <span class="hljs-built_in">filter</span>.addDataScheme(<span class="hljs-string">"file"</span>); <span class="hljs-built_in">filter</span>.setPriority(<span class="hljs-number">100</span>); <span class="hljs-built_in">filter</span>);</code></pre></pre>2.2 Run<p><p>MSS implements the Runable run method, which is called by OnCreate when the thread is Started.<br>The main function of the Run method is to start Servicehandler</p></p><pre class="prettyprint"><pre class="prettyprint"><code class="hljs cs"> <span class="hljs-keyword">public </span> <span class="hljs-keyword"> void </span> <span class="hljs-title">run </span> () {looper.prepare (); Mservicelooper = Looper.mylooper (); Mservicehandler = <span class="hljs-keyword">new </span> servicehandler (); <span class="hljs-comment"><span class="hljs-xmldoctag">///</span> m:reduce thread priority after Servicehandler has been created to avoid CPU starvation </span> <span class="hljs-comment"><span class="hljs-xmldoctag">///</span> Which may cause ANR because create service handler too slow. </span> <span class="hljs-comment">//reduce priority below other background threads to avoid interfering </span> <span clas s="hljs-comment">//with Other services at boot Time. </span> Process.setthreadpriority (process.thread_priority_background + process.thread_priority_less_favorable); Looper.loop (); }</code></pre></pre>2.3 Onstartcommand<p><p><strong>(1) wait for Servicehandler to start</strong></p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs java"> <span class="hljs-keyword">while</span><span class="hljs-keyword">null</span>) { <span class="hljs-keyword">synchronized</span> (<span class="hljs-keyword">this</span>) { <span class="hljs-keyword">try</span> { wait(<span class="hljs-number">100</span>); <span class="hljs-keyword">catch</span> (InterruptedException e) { <span class="hljs-string">"onStartCommand: InterruptedException!"</span>); } } }</code></pre></pre><p><p><strong>(2) Handling Intent messages</strong></p></p><pre class="prettyprint"><pre class="prettyprint"><code class="hljs javascript"> Bundle <span class="hljs-built_in">arguments </span> = int Ent.getextras (); int what; <span class="hljs-keyword">if </span> (<span class="hljs-built_in">arguments </span>. getString (<span class="hljs-string"> "filepath" </span>)! = <span class="hljs-literal">null </span>) {what = msg_scan_single_file; } <span class="hljs-keyword">else </span> <span class="hljs-keyword">if </span> (<span class="hljs-built_in"> Arguments </span>. getString (<span class="hljs-string"> "thumbpath" </span>)! = <span class="hljs-literal">null </span>) {<span class="hljs-comment">//[+leui][bug][si-17406][guo he][20150630] </span> log.d (TAG, <span class="hljs-string"> "get do extract thumb action" </span>); what = msg_extract_thumbnails; } <span class="hljs-keyword">else </span> {what = msg_scan_directory; }</code></pre></pre><p><p><strong>(3) Pass the message to Servicehandler</strong></p></p><pre class="prettyprint"><pre class="prettyprint"><code class=" hljs avrasm"> Message msg = mServiceHandler<span class="hljs-preprocessor">.obtainMessage</span>(what, startId, -<span class="hljs-number">1</span>, arguments)<span class="hljs-comment">;</span> mServiceHandler<span class="hljs-preprocessor">.sendMessage</span>(msg)<span class="hljs-comment">;</span></code></pre></pre>2.4 Onbind<pre class="prettyprint"><code class=" hljs java"> <span class="hljs-annotation"><span class="hljs-annotation">@Override</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> public</span>IBinder<span class="hljs-title"><span class="hljs-title">Onbind</span></span>(Intent Intent) {<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>mbinder; }<span class="hljs-keyword"><span class="hljs-keyword">Private</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Final</span></span>Imediascannerservice.stub Mbinder =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Imediascannerservice.stub () {<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">Requestscanfile</span></span>(string path, string mimeType, imediascannerlistener listener) {<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(<span class="hljs-keyword"><span class="hljs-keyword">false</span></span>) {LOG.D (TAG,<span class="hljs-string"><span class="hljs-string">"imediascannerservice.scanfile:"</span></span>+ Path +<span class="hljs-string"><span class="hljs-string">"mimeType:"</span></span>+ mimeType); } Bundle args =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Bundle (); Args.putstring (<span class="hljs-string"><span class="hljs-string">"filepath"</span></span>, path); Args.putstring (<span class="hljs-string"><span class="hljs-string">"mimetype"</span></span>, mimeType);<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(listener! =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>) {args.putibinder (<span class="hljs-string"><span class="hljs-string">"listener"</span></span>, Listener.asbinder ()); } startservice (<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Intent (mediascannerservice.<span class="hljs-keyword"><span class="hljs-keyword"></span> this</span>, mediascannerservice.class). Putextras (args)); }<span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">Scanfile</span></span>(string path, String MimeType) {requestscanfile (path, mimeType,<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>); } };</code></pre>3. Servicehandler<p><p>Handling Types in 2<br><strong>folder:</strong><br>Scan (directories, volume);<br><strong>file:</strong><br>URI = Scanfile (filePath, arguments.getstring ("mimetype"));</p></p><pre class="prettyprint"><code class=" hljs java"><span class="hljs-keyword"><span class="hljs-keyword">Private</span></span> <span class="hljs-keyword"><span class="hljs-keyword">Final</span></span> <span class="hljs-class"><span class="hljs-class"> <span class="hljs-keyword">class</span> <span class="hljs-title">servicehandler</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Handler</span> {</span></span> <span class="hljs-annotation"><span class="hljs-annotation">@Override</span></span> <span class="hljs-keyword"><span class="hljs-keyword"></span> public</span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">Handlemessage</span></span>(Message Msg) {bundle arguments = (bundle) msg.obj; String FilePath = arguments.getstring (<span class="hljs-string"><span class="hljs-string">"filepath"</span></span>);<span class="hljs-keyword"><span class="hljs-keyword">Try</span></span>{<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(filePath! =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>) {ibinder Binder = Arguments.getibinder (<span class="hljs-string"><span class="hljs-string">"listener"</span></span>); Imediascannerlistener Listener = (binder = =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>?<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>: IMediaScannerListener.Stub.asInterface (binder)); Uri uri =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">Try</span></span>{uri = Scanfile (filePath, arguments.getstring (<span class="hljs-string"><span class="hljs-string">"mimetype"</span></span>)); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(Exception E) {LOG.E (TAG,<span class="hljs-string"><span class="hljs-string">"Exception Scanning file"</span></span>, e); }<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(listener! =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>) {listener.scancompleted (filePath, uri); } }<span class="hljs-keyword"><span class="hljs-keyword">Else</span></span>{String volume = Arguments.getstring (<span class="hljs-string"><span class="hljs-string">"volume"</span></span>); string[] directories =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(MediaProvider.INTERNAL_VOLUME.equals (VOLUME)) {<span class="hljs-comment"><span class="hljs-comment">//scan Internal Media storage</span></span>directories =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>string[] {environment.getrootdirectory () +<span class="hljs-string"><span class="hljs-string">"/media"</span></span>, Environment.getoemdirectory () +<span class="hljs-string"><span class="hljs-string">"/media"</span></span>, }; }<span class="hljs-keyword"><span class="hljs-keyword">Else</span></span> <span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(MediaProvider.EXTERNAL_VOLUME.equals (VOLUME)) {<span class="hljs-comment"><span class="hljs-comment">//scan External Storage volumes</span></span>directories = mexternalstoragepaths; }<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(directories! =<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>) {<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(<span class="hljs-keyword"><span class="hljs-keyword">false</span></span>) LOG.D (TAG,<span class="hljs-string"><span class="hljs-string">"start Scanning volume"</span></span>+ Volume +<span class="hljs-string"><span class="hljs-string">": "</span></span>+ arrays.tostring (directories)); Scan (directories, volume);<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(<span class="hljs-keyword"><span class="hljs-keyword">false</span></span>) LOG.D (TAG,<span class="hljs-string"><span class="hljs-string">"done Scanning volume"</span></span>+ volume); } } }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(Exception E) {LOG.E (TAG,<span class="hljs-string"><span class="hljs-string">"Exception in handlemessage"</span></span>, e); } stopself (msg.arg1); } };}</code></pre>4. Scanfile & Scan<p><p>Scanfile is basically the same as scan logic, and it's all called Framworks/base/media/java/android/media/mediascanner.java to do the job.</p></p>4.1 Createmediascanner<p><p>Framworks/base/media/java/android/media/mediascanner.java</p></p><pre class="prettyprint"><code class=" hljs vbscript"> <span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>Mediascanner Createmediascanner () {mediascanner scanner =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Mediascanner (this); Locale locale = getresources (). getconfiguration (). locale;<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(locale! =<span class="hljs-literal"><span class="hljs-literal">NULL</span></span>) {<span class="hljs-built_in"><span class="hljs-built_in">String</span></span>Language = Locale.getlanguage ();<span class="hljs-built_in"><span class="hljs-built_in">String</span></span>Country = Locale.getcountry ();<span class="hljs-built_in"><span class="hljs-built_in">String</span></span>Localestring =<span class="hljs-literal"><span class="hljs-literal">NULL</span></span>;<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(language! =<span class="hljs-literal"><span class="hljs-literal">NULL</span></span>) {<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(country! =<span class="hljs-literal"><span class="hljs-literal">NULL</span></span>) {scanner.<span class="hljs-built_in"><span class="hljs-built_in">SetLocale</span></span>(language +<span class="hljs-string"><span class="hljs-string">"_"</span></span>+ country); }<span class="hljs-keyword"><span class="hljs-keyword">Else</span></span>{scanner.<span class="hljs-built_in"><span class="hljs-built_in">SetLocale</span></span>(language); }}} return scanner; }</code></pre>4.2 Scanfile<p><p><strong>core:</strong><br>Scanner.scansinglefile (canonicalpath, volumename, mimeType);</p></p><pre class="prettyprint"><code class=" hljs lasso"> <span class="hljs-keyword"><span class="hljs-keyword">Private</span></span>Uri Scanfile (<span class="hljs-built_in"><span class="hljs-built_in">String</span></span>Path<span class="hljs-built_in"><span class="hljs-built_in">String</span></span>MimeType) {<span class="hljs-built_in"><span class="hljs-built_in">String</span></span>VolumeName<span class="hljs-subst"><span class="hljs-subst">=</span></span>Mediaprovider<span class="hljs-built_in"><span class="hljs-built_in">.</span></span>external_volume; OpenDatabase (volumename); Mediascanner Scanner<span class="hljs-subst"><span class="hljs-subst">=</span></span>Createmediascanner (); try {<span class="hljs-comment"><span class="hljs-comment">//make sure the file path was in canonical form</span></span> <span class="hljs-built_in"><span class="hljs-built_in">String</span></span>Canonicalpath<span class="hljs-subst"><span class="hljs-subst">=</span></span> <span class="hljs-literal"><span class="hljs-literal">New</span></span>File (path)<span class="hljs-built_in"><span class="hljs-built_in">.</span></span>Getcanonicalpath ();<span class="hljs-keyword"><span class="hljs-keyword">return</span></span>Scanner<span class="hljs-built_in"><span class="hljs-built_in">.</span></span>Scansinglefile (canonicalpath, volumename, mimeType); } catch (Exception E) {<span class="hljs-keyword"><span class="hljs-keyword">Log</span></span><span class="hljs-built_in"><span class="hljs-built_in">.</span></span>E<span class="hljs-built_in"><span class="hljs-built_in">TAG</span></span>,<span class="hljs-string"><span class="hljs-string">"bad path"</span></span> <span class="hljs-subst"><span class="hljs-subst">+</span></span>Path<span class="hljs-subst"><span class="hljs-subst">+</span></span> <span class="hljs-string"><span class="hljs-string">"in scanfile ()"</span></span>, e);<span class="hljs-keyword"><span class="hljs-keyword">return</span></span> <span class="hljs-built_in"><span class="hljs-built_in">NULL</span></span>; } }</code></pre>4.3 scan<p><p><strong>Core Statement</strong><br>Scanner.scandirectories (directories, volumename);</p></p><pre class="prettyprint"><code class=" hljs cs"> <span class="hljs-keyword"><span class="hljs-keyword">Private</span></span> <span class="hljs-keyword"><span class="hljs-keyword">void</span></span> <span class="hljs-title"><span class="hljs-title">Scan</span></span>(string[] directories, String Volumename) {uri uri = Uri.parse (<span class="hljs-string"><span class="hljs-string">"file://"</span></span>+ directories[<span class="hljs-number"><span class="hljs-number">0</span></span>]);<span class="hljs-comment"><span class="hljs-comment">//don ' t sleep while scanning</span></span>Mwakelock.acquire ();<span class="hljs-keyword"><span class="hljs-keyword">Try</span></span>{contentvalues values =<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Contentvalues (); Values.put (mediastore.media_scanner_volume, volumename); Uri Scanuri = getcontentresolver (). Insert (mediastore.getmediascanneruri (), values); Sendbroadcast (<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Intent (intent.action_media_scanner_started, uri));<span class="hljs-keyword"><span class="hljs-keyword">Try</span></span>{<span class="hljs-keyword"><span class="hljs-keyword">if</span></span>(volumename.equals (mediaprovider.external_volume)) {opendatabase (volumename); } Mediascanner scanner = Createmediascanner (); Scanner.scandirectories (directories, volumename); }<span class="hljs-keyword"><span class="hljs-keyword">Catch</span></span>(Exception E) {LOG.E (TAG,<span class="hljs-string"><span class="hljs-string">"exception in Mediascanner.scan ()"</span></span>, e); } getcontentresolver (). Delete (scanuri,<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>,<span class="hljs-keyword"><span class="hljs-keyword">NULL</span></span>); }<span class="hljs-keyword"><span class="hljs-keyword">finally</span></span>{sendbroadcast (<span class="hljs-keyword"><span class="hljs-keyword">New</span></span>Intent (intent.action_media_scanner_finished, uri)); Mwakelock.release (); } }</code></pre> <p style="font-size:12px;"><p style="font-size:12px;">Copyright Notice: This article for Bo Master original article, without Bo Master permission not Reproduced.</p></p> <p><p>Android Mediascannerservice Source Analysis</p></p></span>