From:http://blog.csdn.net/fengye810130/article/details/9118221

google原生Android中,MiniThumbFile.java里存储图片/视频的缩略图的算法有问题。 该算法的漏洞造成微缩略图文件( DCIM\.thumbnails\.thumbdata4--1967290299 )非常庞大和臃肿,多达1G,理论上可以无限大,直到填满SD卡 重现步骤: 第一步 :插入一张拥有10万张图片的外部SD卡, 第二步 :等待手机扫描完整个SD卡,这个过程大概30分钟。至于扫描是否完成,你可以看TAG为MediaProvider的日志。 第三步 :拔出外部SD卡,再次等手机进行扫描大概10分钟。 第四步 :按下手机的电源key +音量down key来截屏。 第五步 :通过电脑查看内部SD卡的DCIM\.thumbnails\.thumbdata4--1967290299文件。这时你会发现,该文件多达1G. 对于该问题,大概的逻辑是这样的MediaProvider会对SD卡上的文件的进行扫描,得到一些基本的信息放入数据库的files这个表中。 对于一些图片(比如手机截屏图片),手机会以这些图片文件在files表中的_id的值,作为一个定位标志,把其缩略文件存放在.thumbdata4--1967290299中。 比如 _id为1,那么该文件的缩略图就存放在.thumbdata4--1967290299文件的_id * BYTES_PER_MINTHUMB开始的位置,其中BYTES_PER_MINTHUMB = 17000, 对此可以参照MiniThumbFile.java文件中的 saveMiniThumbToFile(byte[] data, long id, long magic)等函数 对于Android的Sqlite3数据库,_id是自增的。比如,最开始我插入了10001记录,这时最后一条记录的_id为10001,这时如果删除1到10000条记录, 再插入一条记录,那么这条的记录的_id值为10002. 因此, 随着用户日常中不停的向SD卡反复地添加删除文件,那么files表中的_id的值会不停的增大当该值为10万时,即使我们截屏时,系统只把该截屏图片这样一张图的缩略图保存在.thumbdata4--1967290299文件, 10万*BYTES_PER_MINTHUMB>1G,也就是说.thumbdata4--1967290299文件就会占用了1G多的SD空间。随着时间的推移,该值会继续变大,直到填满SD卡我们的方案就是把 .thumbdata4--1967290299 文件分成多个文件来存储缩略图。 比如.thumbdata4--1967290299-0存_id 为1到1024的文件的缩略图,.thumbdata4--1967290299-1存_id 为1025到2048的文件的缩略图 同时对缩略图文件做一些维护,即如果一个缩略图文件本身对应原文件不在时,清理掉该微缩略图文件。 另外在极端情况下(剩余容量小于100M下),清理掉所有的微缩略图文件。 在MTK 6575平台上对该问题的修改包含2个文件的修改:
<div><span class="pln"><span class="pln">   modified</span></span><span class="pun" style="color:#0;"><span class="pun">:</span></span><span class="pln"><span class="pln"> frameworks</span></span><span class="pun" style="color:#0;"><span class="pun">/</span></span><span class="kwd" style="color:#0;"><span class="kwd">base</span></span><span class="pun" style="color:#0;"><span class="pun">/</span></span><span class="pln"><span class="pln">media</span></span><span class="pun" style="color:#0;"><span class="pun">/</span></span><span class="pln"><span class="pln">java</span></span><span class="pun" style="color:#0;"><span class="pun">/</span></span><span class="pln"><span class="pln">android</span></span><span class="pun" style="color:#0;"><span class="pun">/</span></span><span class="pln"><span class="pln">media</span></span><span class="pun" style="color:#0;"><span class="pun">/</span></span><span class="typ" style="color:#0;"><span class="typ">MediaScanner</span></span><span class="pun" style="color:#0;"><span class="pun">.</span></span><span class="pln"><span class="pln">java</span></span></div><div><span class="pln"><span class="pln">   modified</span></span><span class="pun" style="color:#0;"><span class="pun">:</span></span><span class="pln"><span class="pln"> frameworks</span></span><span class="pun" style="color:#0;"><span class="pun">/</span></span><span class="kwd" style="color:#0;"><span class="kwd">base</span></span><span class="pun" style="color:#0;"><span class="pun">/</span></span><span class="pln"><span class="pln">media</span></span><span class="pun" style="color:#0;"><span class="pun">/</span></span><span class="pln"><span class="pln">java</span></span><span class="pun" style="color:#0;"><span class="pun">/</span></span><span class="pln"><span class="pln">android</span></span><span class="pun" style="color:#0;"><span class="pun">/</span></span><span class="pln"><span class="pln">media</span></span><span class="pun" style="color:#0;"><span class="pun">/</span></span><span class="typ" style="color:#0;"><span class="typ">MiniThumbFile</span></span><span class="pun" style="color:#0;"><span class="pun">.</span></span><span class="pln"><span class="pln">java</span></span></div>
MiniThumbFile.java文件的主要修改如下:
<div class="dp-highlighter bg_java" sizcache="27" sizset="60"><div class="bar" sizcache="27" sizset="60"><div class="tools" sizcache="27" sizset="60"><strong>[java]</strong> <a target=_blank title="view plain" class="ViewSource" href="http://blog.csdn.net/fengye810130/article/details/9118221#">view plain</a><a target=_blank title="copy" class="CopyToClipboard" href="http://blog.csdn.net/fengye810130/article/details/9118221#">copy</a><a target=_blank title="print" class="PrintSource" href="http://blog.csdn.net/fengye810130/article/details/9118221#">print</a><a target=_blank title="?" class="About" href="http://blog.csdn.net/fengye810130/article/details/9118221#">?</a></div></div><ol class="dp-j"><li class="alt"><span><span><PRE</span><span class="keyword">class</span><span>=javaname=</span><span class="string">"code"</span><span>></span><span class="comment">/**</span></span></li><li><span><span class="comment">@@-85,16+89,34@@publicclassMiniThumbFile{</span></span></li><li class="alt"><span><span class="comment">/*add1ongoogle'sversion.*/</span><span></span></span></li><li><span></span><span class="comment">/*thisversionaddcheckcodeforthumbdata.*/</span><span></span></li><li class="alt"><span></span><span class="keyword">private</span><span></span><span class="keyword">static</span><span></span><span class="keyword">final</span><span></span><span class="keyword">int</span><span>MINI_THUMB_DATA_FILE_VERSION=</span><span class="number">3</span><span>+</span><span class="number">1</span><span>;</span></li><li><span></span><span class="keyword">public</span><span></span><span class="keyword">static</span><span></span><span class="keyword">final</span><span></span><span class="keyword">int</span><span>BYTES_PER_MINTHUMB=</span><span class="number">17000</span><span>;</span></li><li class="alt"><span></span><span class="keyword">public</span><span></span><span class="keyword">static</span><span></span><span class="keyword">final</span><span></span><span class="keyword">int</span><span>BYTES_PER_MINTHUMB=</span><span class="number">17000</span><span>;</span></li><li><span></span><span class="keyword">private</span><span></span><span class="keyword">static</span><span></span><span class="keyword">final</span><span></span><span class="keyword">int</span><span>HEADER_SIZE=</span><span class="number">1</span><span>+</span><span class="number">8</span><span>+</span><span class="number">4</span><span>+</span><span class="number">8</span><span>;</span></li><li class="alt"><span></span><span class="keyword">private</span><span>UrimUri;</span></li><li><span></span><span class="keyword">private</span><span>RandomAccessFilemMiniThumbFile;</span></li><li class="alt"><span>Map<Long,RandomAccessFile>mMiniThumbFilesMap=Collections.synchronizedMap(</span><span class="keyword">new</span><span>HashMap<Long,RandomAccessFile>(</span><span class="number">5</span><span>));</span></li><li><span></span><span class="keyword">private</span><span>FileChannelmChannel;</span></li><li class="alt"><span></span><span class="keyword">private</span><span>ByteBuffermBuffer;</span></li><li><span></span><span class="keyword">private</span><span></span><span class="keyword">static</span><span>Hashtable<String,MiniThumbFile>sThumbFiles=</span></li><li class="alt"><span></span><span class="keyword">new</span><span>Hashtable<String,MiniThumbFile>();</span></li><li><span></span><span class="keyword">private</span><span></span><span class="keyword">static</span><span>java.util.zip.Adler32sChecker=</span><span class="keyword">new</span><span>Adler32();</span></li><li class="alt"><span></span><span class="keyword">private</span><span></span><span class="keyword">static</span><span></span><span class="keyword">final</span><span></span><span class="keyword">long</span><span>UNKNOWN_CHECK_CODE=-</span><span class="number">1</span><span>;</span></li><li><span></span><span class="keyword">final</span><span></span><span class="keyword">static</span><span></span><span class="keyword">char</span><span>SEPERATE_CHAR=</span><span class="string">'_'</span><span>;</span></li><li class="alt"><span></span><span class="keyword">public</span><span></span><span class="keyword">static</span><span>String[]parseFileName(StringfileName)</span></li><li><span>{</span></li><li class="alt"><span>Stringstr=fileName;</span></li><li><span></span><span class="keyword">if</span><span>(fileName==</span><span class="keyword">null</span><span>)</span></li><li class="alt"><span></span><span class="keyword">return</span><span></span><span class="keyword">null</span><span>;</span></li><li><span></span><span class="keyword">int</span><span>index=fileName.lastIndexOf(</span><span class="string">"/"</span><span>);</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(index!=-</span><span class="number">1</span><span>)</span></li><li><span>{</span></li><li class="alt"><span>str=fileName.substring(index+</span><span class="number">1</span><span>);</span></li><li><span>}</span></li><li class="alt"><span>Stringstrs[]=str.split(SEPERATE_CHAR+</span><span class="string">""</span><span>);</span></li><li><span></span><span class="keyword">if</span><span>(strs==</span><span class="keyword">null</span><span>||strs.length!=</span><span class="number">4</span><span>||(!str.startsWith(</span><span class="string">".thumbdata"</span><span>)))</span></li><li class="alt"><span>{</span></li><li><span></span><span class="keyword">return</span><span></span><span class="keyword">null</span><span>;</span></li><li class="alt"><span>}</span></li><li><span></span><span class="keyword">return</span><span>strs;</span></li><li class="alt"><span>}</span></li><li><span></span><span class="comment">/**</span></li><li class="alt"><span><span class="comment">*Westoredifferenttypesofthumbnailsindifferentfiles.Toremainbackwardcompatibility,</span></span></li><li><span><span class="comment">*weshouldhashcodeofcontent://media/external/images/mediaremainsthesame.</span></span></li><li class="alt"><span><span class="comment">@@-105,7+127,18@@publicclassMiniThumbFile{</span></span></li><li><span><span class="comment">}</span></span></li><li class="alt"><span><span class="comment">sThumbFiles.clear();</span></span></li><li><span><span class="comment">}</span></span></li><li class="alt"><span><span class="comment"></span></span></li><li><span><span class="comment">privatefinalstaticlonggetMiniThumbFileId(longid)</span></span></li><li class="alt"><span><span class="comment">{</span></span></li><li><span><span class="comment">return(id>>8);</span></span></li><li class="alt"><span><span class="comment">}</span></span></li><li><span><span class="comment">publicfinalstaticintgetMiniThumbDataFileBlockNum()</span></span></li><li class="alt"><span><span class="comment">{</span></span></li><li><span><span class="comment">return(1<<8);</span></span></li><li class="alt"><span><span class="comment">}</span></span></li><li><span><span class="comment">privatefinalstaticlonggetPositionInMiniThumbFile(longid)</span></span></li><li class="alt"><span><span class="comment">{</span></span></li><li><span><span class="comment">return(id&0xff)*BYTES_PER_MINTHUMB;</span></span></li><li class="alt"><span><span class="comment">}</span></span></li><li><span><span class="comment">publicstaticsynchronizedMiniThumbFileinstance(Uriuri){</span></span></li><li class="alt"><span><span class="comment">Stringtype=uri.getPathSegments().get(1);</span></span></li><li><span><span class="comment">MiniThumbFilefile=sThumbFiles.get(type);</span></span></li><li class="alt"><span><span class="comment">@@-120,10+153,11@@publicclassMiniThumbFile{</span></span></li><li><span><span class="comment">}</span></span></li><li class="alt"><span><span class="comment">privateStringrandomAccessFilePath(intversion){</span></span></li><li><span><span class="comment">Stringtype=mUri.getPathSegments().get(1);</span></span></li><li class="alt"><span><span class="comment">StringdirectoryName=</span></span></li><li><span><span class="comment">Environment.getExternalStorageDirectory().toString()+"/DCIM/.thumbnails";</span></span></li><li class="alt"><span><span class="comment">returndirectoryName+"/.thumbdata"+version+"-"+mUri.hashCode();</span></span></li><li><span><span class="comment">returndirectoryName+"/.thumbdata"+version+SEPERATE_CHAR+mUri.hashCode()+SEPERATE_CHAR+type;</span></span></li><li class="alt"><span><span class="comment">}</span></span></li><li><span><span class="comment">/**</span></span></li><li class="alt"><span><span class="comment">@@-131,18+165,18@@publicclassMiniThumbFile{</span></span></li><li><span><span class="comment">*@paramuritheUrisameasinstance(Uriuri).</span></span></li><li class="alt"><span><span class="comment">*@return</span></span></li><li><span><span class="comment">*/</span><span></span></span></li><li class="alt"><span></span><span class="keyword">public</span><span></span><span class="keyword">static</span><span>StringgetThumbdataPath(Uriuri){</span></li><li><span></span><span class="comment">/*publicstaticStringgetThumbdataPath(Uriuri){</span></li><li class="alt"><span><span class="comment">Stringtype=uri.getPathSegments().get(1);</span></span></li><li><span><span class="comment">UrithumbFileUri=Uri.parse("content://media/external/"+type+"/media");</span></span></li><li class="alt"><span><span class="comment">StringdirectoryName=Environment.getExternalStorageDirectory().toString()</span></span></li><li><span><span class="comment">+"/DCIM/.thumbnails";</span></span></li><li class="alt"><span><span class="comment">Stringpath=directoryName+"/.thumbdata"+MINI_THUMB_DATA_FILE_VERSION+"-"+thumbFileUri.hashCode();</span></span></li><li><span><span class="comment">Stringpath=directoryName+"/.thumbdata"+MINI_THUMB_DATA_FILE_VERSION+SEPERATE_CHAR+thumbFileUri.hashCode()+SEPERATE_CHAR+type;</span></span></li><li class="alt"><span><span class="comment">if(LOG)Log.i(TAG,"getThumbdataPath("+uri+")return"+path);</span></span></li><li><span><span class="comment">returnpath;</span></span></li><li class="alt"><span><span class="comment">}</span></span></li><li><span><span class="comment">}*/</span><span></span></span></li><li class="alt"><span></span><span class="keyword">private</span><span></span><span class="keyword">void</span><span>removeOldFile(){</span></li><li><span>StringoldPath=randomAccessFilePath(MINI_THUMB_DATA_FILE_VERSION-</span><span class="number">1</span><span>);</span></li><li class="alt"><span></span><span class="keyword">private</span><span></span><span class="keyword">void</span><span>removeOldMiniThumbDataFile(</span><span class="keyword">long</span><span>miniThumbDataFileId){</span></li><li><span>StringoldPath=getMiniThumbDataFilePath(MINI_THUMB_DATA_FILE_VERSION-</span><span class="number">1</span><span>,miniThumbDataFileId);</span></li><li class="alt"><span>FileoldFile=</span><span class="keyword">new</span><span>File(oldPath);</span></li><li><span></span><span class="keyword">if</span><span>(oldFile.exists()){</span></li><li class="alt"><span></span><span class="keyword">try</span><span>{</span></li><li><span>@@-</span><span class="number">152</span><span>,</span><span class="number">35</span><span>+</span><span class="number">186</span><span>,</span><span class="number">43</span><span>@@</span><span class="keyword">public</span><span></span><span class="keyword">class</span><span>MiniThumbFile{</span></li><li class="alt"><span>}</span></li><li><span>}</span></li><li class="alt"><span>}</span></li><li><span></span></li><li class="alt"><span></span><span class="keyword">private</span><span>RandomAccessFileminiThumbDataFile(){</span></li><li><span></span><span class="keyword">if</span><span>(mMiniThumbFile==</span><span class="keyword">null</span><span>){</span></li><li class="alt"><span>removeOldFile();</span></li><li><span>Stringpath=randomAccessFilePath(MINI_THUMB_DATA_FILE_VERSION);</span></li><li class="alt"><span>Filedirectory=</span><span class="keyword">new</span><span>File(path).getParentFile();</span></li><li><span></span><span class="keyword">if</span><span>(!directory.isDirectory()){</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(!directory.mkdirs()){</span></li><li><span>Log.e(TAG,</span><span class="string">"Unabletocreate.thumbnailsdirectory"</span><span></span></li><li class="alt"><span>+directory.toString());</span></li><li><span>}</span></li><li class="alt"><span>}</span></li><li><span></span><span class="keyword">final</span><span></span><span class="keyword">private</span><span>StringgetMiniThumbDataFilePath(</span><span class="keyword">int</span><span>version,</span><span class="keyword">long</span><span>miniThumbDataFileId)</span></li><li class="alt"><span>{</span></li><li><span></span><span class="keyword">return</span><span>randomAccessFilePath(version)+SEPERATE_CHAR+miniThumbDataFileId;</span></li><li class="alt"><span>}</span></li><li><span></span><span class="keyword">private</span><span>RandomAccessFileminiThumbDataFile(</span><span class="keyword">final</span><span></span><span class="keyword">long</span><span>miniThumbDataFileId){</span></li><li class="alt"><span></span><span class="keyword">return</span><span>miniThumbDataFile(miniThumbDataFileId,</span><span class="keyword">false</span><span>);</span></li><li><span>}</span></li><li class="alt"><span></span><span class="keyword">private</span><span>RandomAccessFileminiThumbDataFile(</span><span class="keyword">final</span><span></span><span class="keyword">long</span><span>miniThumbDataFileId,</span><span class="keyword">boolean</span><span>onlyRead){</span></li><li><span>RandomAccessFileminiThumbFile=mMiniThumbFilesMap.get(miniThumbDataFileId);</span></li><li class="alt"><span>Stringpath=getMiniThumbDataFilePath(MINI_THUMB_DATA_FILE_VERSION,miniThumbDataFileId);</span></li><li><span>Filef=</span><span class="keyword">new</span><span>File(path);</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(miniThumbFile==</span><span class="keyword">null</span><span>||!f.exists()){</span></li><li><span></span><span class="keyword">if</span><span>(onlyRead)</span></li><li class="alt"><span></span><span class="keyword">return</span><span></span><span class="keyword">null</span><span>;</span></li><li><span>removeOldMiniThumbDataFile(miniThumbDataFileId);</span></li><li class="alt"><span>Filedirectory=</span><span class="keyword">new</span><span>File(path).getParentFile();</span></li><li><span></span><span class="keyword">if</span><span>(!directory.isDirectory()){</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(!directory.mkdirs()){</span></li><li><span>Log.e(TAG,</span><span class="string">"Unabletocreate.thumbnailsdirectory"</span><span></span></li><li class="alt"><span>+directory.toString());</span></li><li><span>}</span></li><li class="alt"><span>}</span></li><li><span></span></li><li class="alt"><span></span><span class="keyword">try</span><span>{</span></li><li><span>mMiniThumbFile=</span><span class="keyword">new</span><span>RandomAccessFile(f,</span><span class="string">"rw"</span><span>);</span></li><li class="alt"><span>miniThumbFile=</span><span class="keyword">new</span><span>RandomAccessFile(f,</span><span class="string">"rw"</span><span>);</span></li><li><span>}</span><span class="keyword">catch</span><span>(IOExceptionex){</span></li><li class="alt"><span></span><span class="comment">//Openasread-onlysowecanatleastreadtheexisting </span><span></span></li><li><span></span><span class="comment">//thumbnails. </span><span></span></li><li class="alt"><span></span><span class="keyword">try</span><span>{</span></li><li><span>mMiniThumbFile=</span><span class="keyword">new</span><span>RandomAccessFile(f,</span><span class="string">"r"</span><span>);</span></li><li class="alt"><span>miniThumbFile=</span><span class="keyword">new</span><span>RandomAccessFile(f,</span><span class="string">"r"</span><span>);</span></li><li><span>}</span><span class="keyword">catch</span><span>(IOExceptionex2){</span></li><li class="alt"><span>}</span></li><li><span>}</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(mMiniThumbFile!=</span><span class="keyword">null</span><span>){</span></li><li><span>mChannel=mMiniThumbFile.getChannel();</span></li><li class="alt"><span>}</span></li><li><span>mMiniThumbFilesMap.put(miniThumbDataFileId,miniThumbFile);</span></li><li class="alt"><span>}</span></li><li><span></span><span class="keyword">return</span><span>mMiniThumbFile;</span></li><li class="alt"><span></span><span class="keyword">return</span><span>miniThumbFile;</span></li><li><span>}</span></li><li class="alt"><span></span><span class="keyword">public</span><span>MiniThumbFile(Uriuri){</span></li><li><span>@@-</span><span class="number">189</span><span>,</span><span class="number">10</span><span>+</span><span class="number">231</span><span>,</span><span class="number">19</span><span>@@</span><span class="keyword">public</span><span></span><span class="keyword">class</span><span>MiniThumbFile{</span></li><li class="alt"><span>}</span></li><li><span></span><span class="keyword">public</span><span></span><span class="keyword">synchronized</span><span></span><span class="keyword">void</span><span>deactivate(){</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(mMiniThumbFile!=</span><span class="keyword">null</span><span>){</span></li><li><span></span><span class="keyword">if</span><span>(mMiniThumbFilesMap!=</span><span class="keyword">null</span><span>){</span></li><li class="alt"><span>Set<Long>keySet=mMiniThumbFilesMap.keySet();</span></li><li><span></span><span class="keyword">try</span><span>{</span></li><li class="alt"><span>mMiniThumbFile.close();</span></li><li><span>mMiniThumbFile=</span><span class="keyword">null</span><span>;</span></li><li class="alt"><span></span><span class="keyword">for</span><span>(Longkey:keySet)</span></li><li><span>{</span></li><li class="alt"><span>RandomAccessFilefile=mMiniThumbFilesMap.get(key);</span></li><li><span></span><span class="keyword">if</span><span>(file!=</span><span class="keyword">null</span><span>)</span></li><li class="alt"><span>{</span></li><li><span>mMiniThumbFilesMap.put(key,</span><span class="keyword">null</span><span>);</span></li><li class="alt"><span>file.close();</span></li><li><span>}</span></li><li class="alt"><span>}</span></li><li><span>mMiniThumbFilesMap.clear();</span></li><li class="alt"><span>}</span><span class="keyword">catch</span><span>(IOExceptionex){</span></li><li><span></span><span class="comment">//ignoreexception </span><span></span></li><li class="alt"><span>}</span></li><li><span>@@-</span><span class="number">205</span><span>,</span><span class="number">18</span><span>+</span><span class="number">256</span><span>,</span><span class="number">20</span><span>@@</span><span class="keyword">public</span><span></span><span class="keyword">class</span><span>MiniThumbFile{</span></li><li class="alt"><span></span><span class="comment">//checktheminithumbfilefortherightdata.Rightis </span><span></span></li><li><span></span><span class="comment">//definedashavingtherightmagicnumberattheoffset </span><span></span></li><li class="alt"><span></span><span class="comment">//reservedforthis"id". </span><span></span></li><li><span>RandomAccessFiler=miniThumbDataFile();</span></li><li class="alt"><span></span><span class="keyword">final</span><span></span><span class="keyword">long</span><span>miniThumbDataFileId=getMiniThumbFileId(id);</span></li><li><span>RandomAccessFiler=miniThumbDataFile(miniThumbDataFileId,</span><span class="keyword">true</span><span>);</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(r!=</span><span class="keyword">null</span><span>){</span></li><li><span></span><span class="keyword">long</span><span>pos=id*BYTES_PER_MINTHUMB;</span></li><li class="alt"><span>FileChannelchannel=r.getChannel();</span></li><li><span></span><span class="keyword">long</span><span>pos=getPositionInMiniThumbFile(id);</span></li><li class="alt"><span>FileLocklock=</span><span class="keyword">null</span><span>;</span></li><li><span></span><span class="keyword">try</span><span>{</span></li><li class="alt"><span>mBuffer.clear();</span></li><li><span>mBuffer.limit(</span><span class="number">1</span><span>+</span><span class="number">8</span><span>);</span></li><li class="alt"><span>lock=mChannel.lock(pos,</span><span class="number">1</span><span>+</span><span class="number">8</span><span>,</span><span class="keyword">true</span><span>);</span></li><li><span>lock=channel.lock(pos,</span><span class="number">1</span><span>+</span><span class="number">8</span><span>,</span><span class="keyword">true</span><span>);</span></li><li class="alt"><span></span><span class="comment">//checkthatwecanreadthefollowing9bytes </span><span></span></li><li><span></span><span class="comment">//(1forthe"status"and8forthelong) </span><span></span></li><li class="alt"><span></span><span class="keyword">if</span><span>(mChannel.read(mBuffer,pos)==</span><span class="number">9</span><span>){</span></li><li><span></span><span class="keyword">if</span><span>(channel.read(mBuffer,pos)==</span><span class="number">9</span><span>){</span></li><li class="alt"><span>mBuffer.position(</span><span class="number">0</span><span>);</span></li><li><span></span><span class="keyword">if</span><span>(mBuffer.get()==</span><span class="number">1</span><span>){</span></li><li class="alt"><span></span><span class="keyword">return</span><span>mBuffer.getLong();</span></li><li><span>@@-</span><span class="number">242</span><span>,</span><span class="number">10</span><span>+</span><span class="number">295</span><span>,</span><span class="number">12</span><span>@@</span><span class="keyword">public</span><span></span><span class="keyword">class</span><span>MiniThumbFile{</span></li><li class="alt"><span></span><span class="keyword">public</span><span></span><span class="keyword">synchronized</span><span></span><span class="keyword">void</span><span>saveMiniThumbToFile(</span><span class="keyword">byte</span><span>[]data,</span><span class="keyword">long</span><span>id,</span><span class="keyword">long</span><span>magic)</span></li><li><span></span><span class="keyword">throws</span><span>IOException{</span></li><li class="alt"><span>RandomAccessFiler=miniThumbDataFile();</span></li><li><span></span><span class="keyword">final</span><span></span><span class="keyword">long</span><span>miniThumbDataFileId=getMiniThumbFileId(id);</span></li><li class="alt"><span>RandomAccessFiler=miniThumbDataFile(miniThumbDataFileId);</span></li><li><span></span><span class="keyword">if</span><span>(r==</span><span class="keyword">null</span><span>)</span><span class="keyword">return</span><span>;</span></li><li class="alt"><span></span><span class="keyword">long</span><span>pos=id*BYTES_PER_MINTHUMB;</span></li><li><span></span><span class="keyword">final</span><span></span><span class="keyword">long</span><span>pos=getPositionInMiniThumbFile(id);</span></li><li class="alt"><span>FileChannelchannel=r.getChannel();</span></li><li><span>FileLocklock=</span><span class="keyword">null</span><span>;</span></li><li class="alt"><span></span><span class="keyword">try</span><span>{</span></li><li><span></span><span class="keyword">if</span><span>(data!=</span><span class="keyword">null</span><span>){</span></li><li class="alt"><span>@@-</span><span class="number">266</span><span>,</span><span class="number">14</span><span>+</span><span class="number">321</span><span>,</span><span class="number">13</span><span>@@</span><span class="keyword">public</span><span></span><span class="keyword">class</span><span>MiniThumbFile{</span></li><li><span>check=sChecker.getValue();</span></li><li class="alt"><span>}</span></li><li><span>mBuffer.putLong(check);</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(LOG)Log.i(TAG,</span><span class="string">"saveMiniThumbToFile("</span><span>+id+</span><span class="string">")flag=1,magic="</span><span></span></li><li><span>+magic+</span><span class="string">",length="</span><span>+data.length+</span><span class="string">",check="</span><span>+check);</span></li><li class="alt"><span></span></li><li><span>mBuffer.put(data);</span></li><li class="alt"><span>mBuffer.flip();</span></li><li><span>lock=mChannel.lock(pos,BYTES_PER_MINTHUMB,</span><span class="keyword">false</span><span>);</span></li><li class="alt"><span>mChannel.write(mBuffer,pos);</span></li><li><span>lock=channel.lock(pos,BYTES_PER_MINTHUMB,</span><span class="keyword">false</span><span>);</span></li><li class="alt"><span>channel.write(mBuffer,pos);</span></li><li><span></span><span class="keyword">if</span><span>(LOG)Log.i(TAG,</span><span class="string">"saveMiniThumbToFile("</span><span>+id+</span><span class="string">")flag=1,magic="</span><span></span></li><li class="alt"><span>+magic+</span><span class="string">",length="</span><span>+data.length+</span><span class="string">",check="</span><span>+check);</span></li><li><span>}</span></li><li class="alt"><span>}</span><span class="keyword">catch</span><span>(IOExceptionex){</span></li><li><span>Log.e(TAG,</span><span class="string">"couldn'tsaveminithumbnaildatafor"</span><span></span></li><li class="alt"><span>@@-</span><span class="number">319</span><span>,</span><span class="number">27</span><span>+</span><span class="number">373</span><span>,</span><span class="number">29</span><span>@@</span><span class="keyword">public</span><span></span><span class="keyword">class</span><span>MiniThumbFile{</span></li><li><span>*</span><span class="annotation">@return</span><span></span></li><li class="alt"><span>*/</span></li><li><span></span><span class="keyword">public</span><span></span><span class="keyword">synchronized</span><span></span><span class="keyword">byte</span><span>[]getMiniThumbFromFile(</span><span class="keyword">long</span><span>id,</span><span class="keyword">byte</span><span>[]data,ThumbResultresult){</span></li><li class="alt"><span>RandomAccessFiler=miniThumbDataFile();</span></li><li><span></span><span class="keyword">final</span><span></span><span class="keyword">long</span><span>miniThumbDataFileId=getMiniThumbFileId(id);</span></li><li class="alt"><span>RandomAccessFiler=miniThumbDataFile(miniThumbDataFileId,</span><span class="keyword">true</span><span>);</span></li><li><span></span><span class="keyword">if</span><span>(r==</span><span class="keyword">null</span><span>)</span><span class="keyword">return</span><span></span><span class="keyword">null</span><span>;</span></li><li class="alt"><span></span><span class="keyword">long</span><span>pos=id*BYTES_PER_MINTHUMB;</span></li><li><span></span><span class="keyword">long</span><span>pos=getPositionInMiniThumbFile(id);</span></li><li class="alt"><span>FileChannelchannel=r.getChannel();</span></li><li><span>FileLocklock=</span><span class="keyword">null</span><span>;</span></li><li class="alt"><span></span><span class="keyword">try</span><span>{</span></li><li><span>mBuffer.clear();</span></li><li class="alt"><span>lock=mChannel.lock(pos,BYTES_PER_MINTHUMB,</span><span class="keyword">true</span><span>);</span></li><li><span></span><span class="keyword">int</span><span>size=mChannel.read(mBuffer,pos);</span></li><li class="alt"><span>lock=channel.lock(pos,BYTES_PER_MINTHUMB,</span><span class="keyword">true</span><span>);</span></li><li><span></span><span class="keyword">int</span><span>size=channel.read(mBuffer,pos);</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(size></span><span class="number">1</span><span>+</span><span class="number">8</span><span>+</span><span class="number">4</span><span>+</span><span class="number">8</span><span>){</span><span class="comment">//flag,magic,length,checkcode </span><span></span></li><li><span>mBuffer.position(</span><span class="number">0</span><span>);</span></li><li class="alt"><span></span><span class="keyword">byte</span><span>flag=mBuffer.get();</span></li><li><span></span><span class="keyword">long</span><span>magic=mBuffer.getLong();</span></li><li class="alt"><span></span><span class="keyword">int</span><span>length=mBuffer.getInt();</span></li><li><span></span><span class="keyword">long</span><span>check=mBuffer.getLong();</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(LOG)Log.i(TAG,</span><span class="string">"getMiniThumbFromFile("</span><span>+id+</span><span class="string">")flag="</span><span>+flag</span></li><li><span>+</span><span class="string">",magic="</span><span>+magic+</span><span class="string">",length="</span><span>+length+</span><span class="string">",check="</span><span>+check);</span></li><li class="alt"><span></span></li><li><span></span><span class="keyword">long</span><span>newCheck=UNKNOWN_CHECK_CODE;</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(size>=</span><span class="number">1</span><span>+</span><span class="number">8</span><span>+</span><span class="number">4</span><span>+</span><span class="number">8</span><span>+length&&data.length>=length){</span></li><li><span>mBuffer.get(data,</span><span class="number">0</span><span>,length);</span></li><li class="alt"><span>Log.i(TAG,</span><span class="string">"successtogetMiniThumbFromFile("</span><span>+id+</span><span class="string">")flag="</span><span>+flag</span></li><li><span>+</span><span class="string">",magic="</span><span>+magic+</span><span class="string">",length="</span><span>+length+</span><span class="string">",check="</span><span>+check);</span></li><li class="alt"><span></span><span class="keyword">synchronized</span><span>(sChecker){</span></li><li><span>sChecker.reset();</span></li><li class="alt"><span>sChecker.update(data,</span><span class="number">0</span><span>,length);</PRE><BR></span></li></ol></div><pre class="java" style="DISPLAY: none" sizcache="27" sizset="64" name="code"><div class="dp-highlighter bg_java" sizcache="27" sizset="64"><div class="bar" sizcache="27" sizset="64"><div class="tools" sizcache="27" sizset="64"><strong>[java]</strong> <a target=_blank title="view plain" class="ViewSource" href="http://blog.csdn.net/fengye810130/article/details/9118221#">view plain</a><a target=_blank title="copy" class="CopyToClipboard" href="http://blog.csdn.net/fengye810130/article/details/9118221#">copy</a><a target=_blank title="print" class="PrintSource" href="http://blog.csdn.net/fengye810130/article/details/9118221#">print</a><a target=_blank title="?" class="About" href="http://blog.csdn.net/fengye810130/article/details/9118221#">?</a></div></div><ol class="dp-j"><li class="alt"><span><span class="comment">/**</span></span></li><li><span><span class="comment">@@-85,16+89,34@@publicclassMiniThumbFile{</span></span></li><li class="alt"><span><span class="comment">/*add1ongoogle'sversion.*/</span><span></span></span></li><li><span></span><span class="comment">/*thisversionaddcheckcodeforthumbdata.*/</span><span></span></li><li class="alt"><span></span><span class="keyword">private</span><span></span><span class="keyword">static</span><span></span><span class="keyword">final</span><span></span><span class="keyword">int</span><span>MINI_THUMB_DATA_FILE_VERSION=</span><span class="number">3</span><span>+</span><span class="number">1</span><span>;</span></li><li><span></span><span class="keyword">public</span><span></span><span class="keyword">static</span><span></span><span class="keyword">final</span><span></span><span class="keyword">int</span><span>BYTES_PER_MINTHUMB=</span><span class="number">17000</span><span>;</span></li><li class="alt"><span></span><span class="keyword">public</span><span></span><span class="keyword">static</span><span></span><span class="keyword">final</span><span></span><span class="keyword">int</span><span>BYTES_PER_MINTHUMB=</span><span class="number">17000</span><span>;</span></li><li><span></span><span class="keyword">private</span><span></span><span class="keyword">static</span><span></span><span class="keyword">final</span><span></span><span class="keyword">int</span><span>HEADER_SIZE=</span><span class="number">1</span><span>+</span><span class="number">8</span><span>+</span><span class="number">4</span><span>+</span><span class="number">8</span><span>;</span></li><li class="alt"><span></span><span class="keyword">private</span><span>UrimUri;</span></li><li><span></span><span class="keyword">private</span><span>RandomAccessFilemMiniThumbFile;</span></li><li class="alt"><span>Map<Long,RandomAccessFile>mMiniThumbFilesMap=Collections.synchronizedMap(</span><span class="keyword">new</span><span>HashMap<Long,RandomAccessFile>(</span><span class="number">5</span><span>));</span></li><li><span></span><span class="keyword">private</span><span>FileChannelmChannel;</span></li><li class="alt"><span></span><span class="keyword">private</span><span>ByteBuffermBuffer;</span></li><li><span></span><span class="keyword">private</span><span></span><span class="keyword">static</span><span>Hashtable<String,MiniThumbFile>sThumbFiles=</span></li><li class="alt"><span></span><span class="keyword">new</span><span>Hashtable<String,MiniThumbFile>();</span></li><li><span></span><span class="keyword">private</span><span></span><span class="keyword">static</span><span>java.util.zip.Adler32sChecker=</span><span class="keyword">new</span><span>Adler32();</span></li><li class="alt"><span></span><span class="keyword">private</span><span></span><span class="keyword">static</span><span></span><span class="keyword">final</span><span></span><span class="keyword">long</span><span>UNKNOWN_CHECK_CODE=-</span><span class="number">1</span><span>;</span></li><li><span></span><span class="keyword">final</span><span></span><span class="keyword">static</span><span></span><span class="keyword">char</span><span>SEPERATE_CHAR=</span><span class="string">'_'</span><span>;</span></li><li class="alt"><span></span><span class="keyword">public</span><span></span><span class="keyword">static</span><span>String[]parseFileName(StringfileName)</span></li><li><span>{</span></li><li class="alt"><span>Stringstr=fileName;</span></li><li><span></span><span class="keyword">if</span><span>(fileName==</span><span class="keyword">null</span><span>)</span></li><li class="alt"><span></span><span class="keyword">return</span><span></span><span class="keyword">null</span><span>;</span></li><li><span></span><span class="keyword">int</span><span>index=fileName.lastIndexOf(</span><span class="string">"/"</span><span>);</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(index!=-</span><span class="number">1</span><span>)</span></li><li><span>{</span></li><li class="alt"><span>str=fileName.substring(index+</span><span class="number">1</span><span>);</span></li><li><span>}</span></li><li class="alt"><span>Stringstrs[]=str.split(SEPERATE_CHAR+</span><span class="string">""</span><span>);</span></li><li><span></span><span class="keyword">if</span><span>(strs==</span><span class="keyword">null</span><span>||strs.length!=</span><span class="number">4</span><span>||(!str.startsWith(</span><span class="string">".thumbdata"</span><span>)))</span></li><li class="alt"><span>{</span></li><li><span></span><span class="keyword">return</span><span></span><span class="keyword">null</span><span>;</span></li><li class="alt"><span>}</span></li><li><span></span><span class="keyword">return</span><span>strs;</span></li><li class="alt"><span>}</span></li><li><span></span><span class="comment">/**</span></li><li class="alt"><span><span class="comment">*Westoredifferenttypesofthumbnailsindifferentfiles.Toremainbackwardcompatibility,</span></span></li><li><span><span class="comment">*weshouldhashcodeofcontent://media/external/images/mediaremainsthesame.</span></span></li><li class="alt"><span><span class="comment">@@-105,7+127,18@@publicclassMiniThumbFile{</span></span></li><li><span><span class="comment">}</span></span></li><li class="alt"><span><span class="comment">sThumbFiles.clear();</span></span></li><li><span><span class="comment">}</span></span></li><li class="alt"><span><span class="comment"></span></span></li><li><span><span class="comment">privatefinalstaticlonggetMiniThumbFileId(longid)</span></span></li><li class="alt"><span><span class="comment">{</span></span></li><li><span><span class="comment">return(id>>8);</span></span></li><li class="alt"><span><span class="comment">}</span></span></li><li><span><span class="comment">publicfinalstaticintgetMiniThumbDataFileBlockNum()</span></span></li><li class="alt"><span><span class="comment">{</span></span></li><li><span><span class="comment">return(1<<8);</span></span></li><li class="alt"><span><span class="comment">}</span></span></li><li><span><span class="comment">privatefinalstaticlonggetPositionInMiniThumbFile(longid)</span></span></li><li class="alt"><span><span class="comment">{</span></span></li><li><span><span class="comment">return(id&0xff)*BYTES_PER_MINTHUMB;</span></span></li><li class="alt"><span><span class="comment">}</span></span></li><li><span><span class="comment">publicstaticsynchronizedMiniThumbFileinstance(Uriuri){</span></span></li><li class="alt"><span><span class="comment">Stringtype=uri.getPathSegments().get(1);</span></span></li><li><span><span class="comment">MiniThumbFilefile=sThumbFiles.get(type);</span></span></li><li class="alt"><span><span class="comment">@@-120,10+153,11@@publicclassMiniThumbFile{</span></span></li><li><span><span class="comment">}</span></span></li><li class="alt"><span><span class="comment">privateStringrandomAccessFilePath(intversion){</span></span></li><li><span><span class="comment">Stringtype=mUri.getPathSegments().get(1);</span></span></li><li class="alt"><span><span class="comment">StringdirectoryName=</span></span></li><li><span><span class="comment">Environment.getExternalStorageDirectory().toString()+"/DCIM/.thumbnails";</span></span></li><li class="alt"><span><span class="comment">returndirectoryName+"/.thumbdata"+version+"-"+mUri.hashCode();</span></span></li><li><span><span class="comment">returndirectoryName+"/.thumbdata"+version+SEPERATE_CHAR+mUri.hashCode()+SEPERATE_CHAR+type;</span></span></li><li class="alt"><span><span class="comment">}</span></span></li><li><span><span class="comment">/**</span></span></li><li class="alt"><span><span class="comment">@@-131,18+165,18@@publicclassMiniThumbFile{</span></span></li><li><span><span class="comment">*@paramuritheUrisameasinstance(Uriuri).</span></span></li><li class="alt"><span><span class="comment">*@return</span></span></li><li><span><span class="comment">*/</span><span></span></span></li><li class="alt"><span></span><span class="keyword">public</span><span></span><span class="keyword">static</span><span>StringgetThumbdataPath(Uriuri){</span></li><li><span></span><span class="comment">/*publicstaticStringgetThumbdataPath(Uriuri){</span></li><li class="alt"><span><span class="comment">Stringtype=uri.getPathSegments().get(1);</span></span></li><li><span><span class="comment">UrithumbFileUri=Uri.parse("content://media/external/"+type+"/media");</span></span></li><li class="alt"><span><span class="comment">StringdirectoryName=Environment.getExternalStorageDirectory().toString()</span></span></li><li><span><span class="comment">+"/DCIM/.thumbnails";</span></span></li><li class="alt"><span><span class="comment">Stringpath=directoryName+"/.thumbdata"+MINI_THUMB_DATA_FILE_VERSION+"-"+thumbFileUri.hashCode();</span></span></li><li><span><span class="comment">Stringpath=directoryName+"/.thumbdata"+MINI_THUMB_DATA_FILE_VERSION+SEPERATE_CHAR+thumbFileUri.hashCode()+SEPERATE_CHAR+type;</span></span></li><li class="alt"><span><span class="comment">if(LOG)Log.i(TAG,"getThumbdataPath("+uri+")return"+path);</span></span></li><li><span><span class="comment">returnpath;</span></span></li><li class="alt"><span><span class="comment">}</span></span></li><li><span><span class="comment">}*/</span><span></span></span></li><li class="alt"><span></span><span class="keyword">private</span><span></span><span class="keyword">void</span><span>removeOldFile(){</span></li><li><span>StringoldPath=randomAccessFilePath(MINI_THUMB_DATA_FILE_VERSION-</span><span class="number">1</span><span>);</span></li><li class="alt"><span></span><span class="keyword">private</span><span></span><span class="keyword">void</span><span>removeOldMiniThumbDataFile(</span><span class="keyword">long</span><span>miniThumbDataFileId){</span></li><li><span>StringoldPath=getMiniThumbDataFilePath(MINI_THUMB_DATA_FILE_VERSION-</span><span class="number">1</span><span>,miniThumbDataFileId);</span></li><li class="alt"><span>FileoldFile=</span><span class="keyword">new</span><span>File(oldPath);</span></li><li><span></span><span class="keyword">if</span><span>(oldFile.exists()){</span></li><li class="alt"><span></span><span class="keyword">try</span><span>{</span></li><li><span>@@-</span><span class="number">152</span><span>,</span><span class="number">35</span><span>+</span><span class="number">186</span><span>,</span><span class="number">43</span><span>@@</span><span class="keyword">public</span><span></span><span class="keyword">class</span><span>MiniThumbFile{</span></li><li class="alt"><span>}</span></li><li><span>}</span></li><li class="alt"><span>}</span></li><li><span></span></li><li class="alt"><span></span><span class="keyword">private</span><span>RandomAccessFileminiThumbDataFile(){</span></li><li><span></span><span class="keyword">if</span><span>(mMiniThumbFile==</span><span class="keyword">null</span><span>){</span></li><li class="alt"><span>removeOldFile();</span></li><li><span>Stringpath=randomAccessFilePath(MINI_THUMB_DATA_FILE_VERSION);</span></li><li class="alt"><span>Filedirectory=</span><span class="keyword">new</span><span>File(path).getParentFile();</span></li><li><span></span><span class="keyword">if</span><span>(!directory.isDirectory()){</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(!directory.mkdirs()){</span></li><li><span>Log.e(TAG,</span><span class="string">"Unabletocreate.thumbnailsdirectory"</span><span></span></li><li class="alt"><span>+directory.toString());</span></li><li><span>}</span></li><li class="alt"><span>}</span></li><li><span></span><span class="keyword">final</span><span></span><span class="keyword">private</span><span>StringgetMiniThumbDataFilePath(</span><span class="keyword">int</span><span>version,</span><span class="keyword">long</span><span>miniThumbDataFileId)</span></li><li class="alt"><span>{</span></li><li><span></span><span class="keyword">return</span><span>randomAccessFilePath(version)+SEPERATE_CHAR+miniThumbDataFileId;</span></li><li class="alt"><span>}</span></li><li><span></span><span class="keyword">private</span><span>RandomAccessFileminiThumbDataFile(</span><span class="keyword">final</span><span></span><span class="keyword">long</span><span>miniThumbDataFileId){</span></li><li class="alt"><span></span><span class="keyword">return</span><span>miniThumbDataFile(miniThumbDataFileId,</span><span class="keyword">false</span><span>);</span></li><li><span>}</span></li><li class="alt"><span></span><span class="keyword">private</span><span>RandomAccessFileminiThumbDataFile(</span><span class="keyword">final</span><span></span><span class="keyword">long</span><span>miniThumbDataFileId,</span><span class="keyword">boolean</span><span>onlyRead){</span></li><li><span>RandomAccessFileminiThumbFile=mMiniThumbFilesMap.get(miniThumbDataFileId);</span></li><li class="alt"><span>Stringpath=getMiniThumbDataFilePath(MINI_THUMB_DATA_FILE_VERSION,miniThumbDataFileId);</span></li><li><span>Filef=</span><span class="keyword">new</span><span>File(path);</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(miniThumbFile==</span><span class="keyword">null</span><span>||!f.exists()){</span></li><li><span></span><span class="keyword">if</span><span>(onlyRead)</span></li><li class="alt"><span></span><span class="keyword">return</span><span></span><span class="keyword">null</span><span>;</span></li><li><span>removeOldMiniThumbDataFile(miniThumbDataFileId);</span></li><li class="alt"><span>Filedirectory=</span><span class="keyword">new</span><span>File(path).getParentFile();</span></li><li><span></span><span class="keyword">if</span><span>(!directory.isDirectory()){</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(!directory.mkdirs()){</span></li><li><span>Log.e(TAG,</span><span class="string">"Unabletocreate.thumbnailsdirectory"</span><span></span></li><li class="alt"><span>+directory.toString());</span></li><li><span>}</span></li><li class="alt"><span>}</span></li><li><span></span></li><li class="alt"><span></span><span class="keyword">try</span><span>{</span></li><li><span>mMiniThumbFile=</span><span class="keyword">new</span><span>RandomAccessFile(f,</span><span class="string">"rw"</span><span>);</span></li><li class="alt"><span>miniThumbFile=</span><span class="keyword">new</span><span>RandomAccessFile(f,</span><span class="string">"rw"</span><span>);</span></li><li><span>}</span><span class="keyword">catch</span><span>(IOExceptionex){</span></li><li class="alt"><span></span><span class="comment">//Openasread-onlysowecanatleastreadtheexisting </span><span></span></li><li><span></span><span class="comment">//thumbnails. </span><span></span></li><li class="alt"><span></span><span class="keyword">try</span><span>{</span></li><li><span>mMiniThumbFile=</span><span class="keyword">new</span><span>RandomAccessFile(f,</span><span class="string">"r"</span><span>);</span></li><li class="alt"><span>miniThumbFile=</span><span class="keyword">new</span><span>RandomAccessFile(f,</span><span class="string">"r"</span><span>);</span></li><li><span>}</span><span class="keyword">catch</span><span>(IOExceptionex2){</span></li><li class="alt"><span>}</span></li><li><span>}</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(mMiniThumbFile!=</span><span class="keyword">null</span><span>){</span></li><li><span>mChannel=mMiniThumbFile.getChannel();</span></li><li class="alt"><span>}</span></li><li><span>mMiniThumbFilesMap.put(miniThumbDataFileId,miniThumbFile);</span></li><li class="alt"><span>}</span></li><li><span></span><span class="keyword">return</span><span>mMiniThumbFile;</span></li><li class="alt"><span></span><span class="keyword">return</span><span>miniThumbFile;</span></li><li><span>}</span></li><li class="alt"><span></span><span class="keyword">public</span><span>MiniThumbFile(Uriuri){</span></li><li><span>@@-</span><span class="number">189</span><span>,</span><span class="number">10</span><span>+</span><span class="number">231</span><span>,</span><span class="number">19</span><span>@@</span><span class="keyword">public</span><span></span><span class="keyword">class</span><span>MiniThumbFile{</span></li><li class="alt"><span>}</span></li><li><span></span><span class="keyword">public</span><span></span><span class="keyword">synchronized</span><span></span><span class="keyword">void</span><span>deactivate(){</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(mMiniThumbFile!=</span><span class="keyword">null</span><span>){</span></li><li><span></span><span class="keyword">if</span><span>(mMiniThumbFilesMap!=</span><span class="keyword">null</span><span>){</span></li><li class="alt"><span>Set<Long>keySet=mMiniThumbFilesMap.keySet();</span></li><li><span></span><span class="keyword">try</span><span>{</span></li><li class="alt"><span>mMiniThumbFile.close();</span></li><li><span>mMiniThumbFile=</span><span class="keyword">null</span><span>;</span></li><li class="alt"><span></span><span class="keyword">for</span><span>(Longkey:keySet)</span></li><li><span>{</span></li><li class="alt"><span>RandomAccessFilefile=mMiniThumbFilesMap.get(key);</span></li><li><span></span><span class="keyword">if</span><span>(file!=</span><span class="keyword">null</span><span>)</span></li><li class="alt"><span>{</span></li><li><span>mMiniThumbFilesMap.put(key,</span><span class="keyword">null</span><span>);</span></li><li class="alt"><span>file.close();</span></li><li><span>}</span></li><li class="alt"><span>}</span></li><li><span>mMiniThumbFilesMap.clear();</span></li><li class="alt"><span>}</span><span class="keyword">catch</span><span>(IOExceptionex){</span></li><li><span></span><span class="comment">//ignoreexception </span><span></span></li><li class="alt"><span>}</span></li><li><span>@@-</span><span class="number">205</span><span>,</span><span class="number">18</span><span>+</span><span class="number">256</span><span>,</span><span class="number">20</span><span>@@</span><span class="keyword">public</span><span></span><span class="keyword">class</span><span>MiniThumbFile{</span></li><li class="alt"><span></span><span class="comment">//checktheminithumbfilefortherightdata.Rightis </span><span></span></li><li><span></span><span class="comment">//definedashavingtherightmagicnumberattheoffset </span><span></span></li><li class="alt"><span></span><span class="comment">//reservedforthis"id". </span><span></span></li><li><span>RandomAccessFiler=miniThumbDataFile();</span></li><li class="alt"><span></span><span class="keyword">final</span><span></span><span class="keyword">long</span><span>miniThumbDataFileId=getMiniThumbFileId(id);</span></li><li><span>RandomAccessFiler=miniThumbDataFile(miniThumbDataFileId,</span><span class="keyword">true</span><span>);</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(r!=</span><span class="keyword">null</span><span>){</span></li><li><span></span><span class="keyword">long</span><span>pos=id*BYTES_PER_MINTHUMB;</span></li><li class="alt"><span>FileChannelchannel=r.getChannel();</span></li><li><span></span><span class="keyword">long</span><span>pos=getPositionInMiniThumbFile(id);</span></li><li class="alt"><span>FileLocklock=</span><span class="keyword">null</span><span>;</span></li><li><span></span><span class="keyword">try</span><span>{</span></li><li class="alt"><span>mBuffer.clear();</span></li><li><span>mBuffer.limit(</span><span class="number">1</span><span>+</span><span class="number">8</span><span>);</span></li><li class="alt"><span>lock=mChannel.lock(pos,</span><span class="number">1</span><span>+</span><span class="number">8</span><span>,</span><span class="keyword">true</span><span>);</span></li><li><span>lock=channel.lock(pos,</span><span class="number">1</span><span>+</span><span class="number">8</span><span>,</span><span class="keyword">true</span><span>);</span></li><li class="alt"><span></span><span class="comment">//checkthatwecanreadthefollowing9bytes </span><span></span></li><li><span></span><span class="comment">//(1forthe"status"and8forthelong) </span><span></span></li><li class="alt"><span></span><span class="keyword">if</span><span>(mChannel.read(mBuffer,pos)==</span><span class="number">9</span><span>){</span></li><li><span></span><span class="keyword">if</span><span>(channel.read(mBuffer,pos)==</span><span class="number">9</span><span>){</span></li><li class="alt"><span>mBuffer.position(</span><span class="number">0</span><span>);</span></li><li><span></span><span class="keyword">if</span><span>(mBuffer.get()==</span><span class="number">1</span><span>){</span></li><li class="alt"><span></span><span class="keyword">return</span><span>mBuffer.getLong();</span></li><li><span>@@-</span><span class="number">242</span><span>,</span><span class="number">10</span><span>+</span><span class="number">295</span><span>,</span><span class="number">12</span><span>@@</span><span class="keyword">public</span><span></span><span class="keyword">class</span><span>MiniThumbFile{</span></li><li class="alt"><span></span><span class="keyword">public</span><span></span><span class="keyword">synchronized</span><span></span><span class="keyword">void</span><span>saveMiniThumbToFile(</span><span class="keyword">byte</span><span>[]data,</span><span class="keyword">long</span><span>id,</span><span class="keyword">long</span><span>magic)</span></li><li><span></span><span class="keyword">throws</span><span>IOException{</span></li><li class="alt"><span>RandomAccessFiler=miniThumbDataFile();</span></li><li><span></span><span class="keyword">final</span><span></span><span class="keyword">long</span><span>miniThumbDataFileId=getMiniThumbFileId(id);</span></li><li class="alt"><span>RandomAccessFiler=miniThumbDataFile(miniThumbDataFileId);</span></li><li><span></span><span class="keyword">if</span><span>(r==</span><span class="keyword">null</span><span>)</span><span class="keyword">return</span><span>;</span></li><li class="alt"><span></span><span class="keyword">long</span><span>pos=id*BYTES_PER_MINTHUMB;</span></li><li><span></span><span class="keyword">final</span><span></span><span class="keyword">long</span><span>pos=getPositionInMiniThumbFile(id);</span></li><li class="alt"><span>FileChannelchannel=r.getChannel();</span></li><li><span>FileLocklock=</span><span class="keyword">null</span><span>;</span></li><li class="alt"><span></span><span class="keyword">try</span><span>{</span></li><li><span></span><span class="keyword">if</span><span>(data!=</span><span class="keyword">null</span><span>){</span></li><li class="alt"><span>@@-</span><span class="number">266</span><span>,</span><span class="number">14</span><span>+</span><span class="number">321</span><span>,</span><span class="number">13</span><span>@@</span><span class="keyword">public</span><span></span><span class="keyword">class</span><span>MiniThumbFile{</span></li><li><span>check=sChecker.getValue();</span></li><li class="alt"><span>}</span></li><li><span>mBuffer.putLong(check);</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(LOG)Log.i(TAG,</span><span class="string">"saveMiniThumbToFile("</span><span>+id+</span><span class="string">")flag=1,magic="</span><span></span></li><li><span>+magic+</span><span class="string">",length="</span><span>+data.length+</span><span class="string">",check="</span><span>+check);</span></li><li class="alt"><span></span></li><li><span>mBuffer.put(data);</span></li><li class="alt"><span>mBuffer.flip();</span></li><li><span>lock=mChannel.lock(pos,BYTES_PER_MINTHUMB,</span><span class="keyword">false</span><span>);</span></li><li class="alt"><span>mChannel.write(mBuffer,pos);</span></li><li><span>lock=channel.lock(pos,BYTES_PER_MINTHUMB,</span><span class="keyword">false</span><span>);</span></li><li class="alt"><span>channel.write(mBuffer,pos);</span></li><li><span></span><span class="keyword">if</span><span>(LOG)Log.i(TAG,</span><span class="string">"saveMiniThumbToFile("</span><span>+id+</span><span class="string">")flag=1,magic="</span><span></span></li><li class="alt"><span>+magic+</span><span class="string">",length="</span><span>+data.length+</span><span class="string">",check="</span><span>+check);</span></li><li><span>}</span></li><li class="alt"><span>}</span><span class="keyword">catch</span><span>(IOExceptionex){</span></li><li><span>Log.e(TAG,</span><span class="string">"couldn'tsaveminithumbnaildatafor"</span><span></span></li><li class="alt"><span>@@-</span><span class="number">319</span><span>,</span><span class="number">27</span><span>+</span><span class="number">373</span><span>,</span><span class="number">29</span><span>@@</span><span class="keyword">public</span><span></span><span class="keyword">class</span><span>MiniThumbFile{</span></li><li><span>*</span><span class="annotation">@return</span><span></span></li><li class="alt"><span>*/</span></li><li><span></span><span class="keyword">public</span><span></span><span class="keyword">synchronized</span><span></span><span class="keyword">byte</span><span>[]getMiniThumbFromFile(</span><span class="keyword">long</span><span>id,</span><span class="keyword">byte</span><span>[]data,ThumbResultresult){</span></li><li class="alt"><span>RandomAccessFiler=miniThumbDataFile();</span></li><li><span></span><span class="keyword">final</span><span></span><span class="keyword">long</span><span>miniThumbDataFileId=getMiniThumbFileId(id);</span></li><li class="alt"><span>RandomAccessFiler=miniThumbDataFile(miniThumbDataFileId,</span><span class="keyword">true</span><span>);</span></li><li><span></span><span class="keyword">if</span><span>(r==</span><span class="keyword">null</span><span>)</span><span class="keyword">return</span><span></span><span class="keyword">null</span><span>;</span></li><li class="alt"><span></span><span class="keyword">long</span><span>pos=id*BYTES_PER_MINTHUMB;</span></li><li><span></span><span class="keyword">long</span><span>pos=getPositionInMiniThumbFile(id);</span></li><li class="alt"><span>FileChannelchannel=r.getChannel();</span></li><li><span>FileLocklock=</span><span class="keyword">null</span><span>;</span></li><li class="alt"><span></span><span class="keyword">try</span><span>{</span></li><li><span>mBuffer.clear();</span></li><li class="alt"><span>lock=mChannel.lock(pos,BYTES_PER_MINTHUMB,</span><span class="keyword">true</span><span>);</span></li><li><span></span><span class="keyword">int</span><span>size=mChannel.read(mBuffer,pos);</span></li><li class="alt"><span>lock=channel.lock(pos,BYTES_PER_MINTHUMB,</span><span class="keyword">true</span><span>);</span></li><li><span></span><span class="keyword">int</span><span>size=channel.read(mBuffer,pos);</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(size></span><span class="number">1</span><span>+</span><span class="number">8</span><span>+</span><span class="number">4</span><span>+</span><span class="number">8</span><span>){</span><span class="comment">//flag,magic,length,checkcode </span><span></span></li><li><span>mBuffer.position(</span><span class="number">0</span><span>);</span></li><li class="alt"><span></span><span class="keyword">byte</span><span>flag=mBuffer.get();</span></li><li><span></span><span class="keyword">long</span><span>magic=mBuffer.getLong();</span></li><li class="alt"><span></span><span class="keyword">int</span><span>length=mBuffer.getInt();</span></li><li><span></span><span class="keyword">long</span><span>check=mBuffer.getLong();</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(LOG)Log.i(TAG,</span><span class="string">"getMiniThumbFromFile("</span><span>+id+</span><span class="string">")flag="</span><span>+flag</span></li><li><span>+</span><span class="string">",magic="</span><span>+magic+</span><span class="string">",length="</span><span>+length+</span><span class="string">",check="</span><span>+check);</span></li><li class="alt"><span></span></li><li><span></span><span class="keyword">long</span><span>newCheck=UNKNOWN_CHECK_CODE;</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(size>=</span><span class="number">1</span><span>+</span><span class="number">8</span><span>+</span><span class="number">4</span><span>+</span><span class="number">8</span><span>+length&&data.length>=length){</span></li><li><span>mBuffer.get(data,</span><span class="number">0</span><span>,length);</span></li><li class="alt"><span>Log.i(TAG,</span><span class="string">"successtogetMiniThumbFromFile("</span><span>+id+</span><span class="string">")flag="</span><span>+flag</span></li><li><span>+</span><span class="string">",magic="</span><span>+magic+</span><span class="string">",length="</span><span>+length+</span><span class="string">",check="</span><span>+check);</span></li><li class="alt"><span></span><span class="keyword">synchronized</span><span>(sChecker){</span></li><li><span>sChecker.reset();</span></li><li class="alt"><span>sChecker.update(data,</span><span class="number">0</span><span>,length);</span></li></ol></div><pre class="java" style="DISPLAY: none" name="code">/**@@ -85,16 +89,34 @@ public class MiniThumbFile {     /*add 1 on google's version.*/     /*this version add check code for thumbdata.*/    private static final int MINI_THUMB_DATA_FILE_VERSION = 3 + 1;    public static final int BYTES_PER_MINTHUMB = 17000;    public static final int BYTES_PER_MINTHUMB = 17000;    private static final int HEADER_SIZE = 1 + 8 + 4 + 8;    private Uri mUri;    private RandomAccessFile mMiniThumbFile;    Map<Long,RandomAccessFile> mMiniThumbFilesMap = Collections.synchronizedMap(new HashMap<Long,RandomAccessFile>(5));    private FileChannel mChannel;    private ByteBuffer mBuffer;    private static Hashtable<String, MiniThumbFile> sThumbFiles =         new Hashtable<String, MiniThumbFile>();    private static java.util.zip.Adler32 sChecker = new Adler32();    private static final long UNKNOWN_CHECK_CODE = -1;    final static char SEPERATE_CHAR='_';    public static String[] parseFileName(String fileName)    {       String str=fileName;       if(fileName==null)             return null;       int index=fileName.lastIndexOf("/");       if(index!=-1)       {             str=fileName.substring(index+1);       }       String strs[]=str.split(SEPERATE_CHAR+"");       if(strs==null||strs.length!=4||(!str.startsWith(".thumbdata")))       {             return null;       }       return strs;    }     /**      * We store different types of thumbnails in different files. To remain backward compatibility,      * we should hashcode of content://media/external/images/media remains the same.@@ -105,7 +127,18 @@ public class MiniThumbFile {        }         sThumbFiles.clear();    }    private final static long getMiniThumbFileId(long id)    {       return (id>>8);    }    public final static int getMiniThumbDataFileBlockNum()    {       return (1<<8);    }    private final static long getPositionInMiniThumbFile(long id)    {       return (id&0xff)*BYTES_PER_MINTHUMB;    }    public static synchronized MiniThumbFile instance(Uri uri) {        String type = uri.getPathSegments().get(1);        MiniThumbFile file = sThumbFiles.get(type);@@ -120,10 +153,11 @@ public class MiniThumbFile {    }    private String randomAccessFilePath(int version) {        String type = mUri.getPathSegments().get(1);        String directoryName =                 Environment.getExternalStorageDirectory().toString() + "/DCIM/.thumbnails";        return directoryName + "/.thumbdata" + version + "-" + mUri.hashCode();        return directoryName + "/.thumbdata" + version + SEPERATE_CHAR + mUri.hashCode()+SEPERATE_CHAR+type;    }    /**@@ -131,18 +165,18 @@ public class MiniThumbFile {      * @param uri the Uri same as instance(Uri uri).      * @return      */    public static String getThumbdataPath(Uri uri) {    /*public static String getThumbdataPath(Uri uri) {        String type = uri.getPathSegments().get(1);        Uri thumbFileUri = Uri.parse("content://media/external/" + type + "/media");        String directoryName = Environment.getExternalStorageDirectory().toString()            + "/DCIM/.thumbnails";        String path = directoryName + "/.thumbdata" + MINI_THUMB_DATA_FILE_VERSION + "-" + thumbFileUri.hashCode();        String path = directoryName + "/.thumbdata" + MINI_THUMB_DATA_FILE_VERSION +SEPERATE_CHAR + thumbFileUri.hashCode()+SEPERATE_CHAR+type;        if (LOG) Log.i(TAG, "getThumbdataPath(" + uri + ") return " + path);        return path;    }    }*/    private void removeOldFile() {        String oldPath = randomAccessFilePath(MINI_THUMB_DATA_FILE_VERSION - 1);    private void removeOldMiniThumbDataFile(long miniThumbDataFileId) {        String oldPath =getMiniThumbDataFilePath(MINI_THUMB_DATA_FILE_VERSION - 1,miniThumbDataFileId);        File oldFile = new File(oldPath);        if (oldFile.exists()) {            try {@@ -152,35 +186,43 @@ public class MiniThumbFile {            }        }    }    private RandomAccessFile miniThumbDataFile() {        if (mMiniThumbFile == null) {            removeOldFile();            String path = randomAccessFilePath(MINI_THUMB_DATA_FILE_VERSION);            File directory = new File(path).getParentFile();            if (!directory.isDirectory()) {                if (!directory.mkdirs()) {                    Log.e(TAG, "Unable to create .thumbnails directory "                            + directory.toString());                }            }    final private String getMiniThumbDataFilePath(int version,long miniThumbDataFileId)    {       return randomAccessFilePath(version)+SEPERATE_CHAR+miniThumbDataFileId;    }    private RandomAccessFile miniThumbDataFile(final long miniThumbDataFileId) {       return miniThumbDataFile(miniThumbDataFileId,false);    }    private RandomAccessFile miniThumbDataFile(final long miniThumbDataFileId,boolean onlyRead) {            RandomAccessFile miniThumbFile=mMiniThumbFilesMap.get(miniThumbDataFileId);            String path = getMiniThumbDataFilePath(MINI_THUMB_DATA_FILE_VERSION,miniThumbDataFileId);            File f = new File(path);            if (miniThumbFile == null||!f.exists()) {if(onlyRead)return null;            removeOldMiniThumbDataFile(miniThumbDataFileId);                File directory = new File(path).getParentFile();                if (!directory.isDirectory()) {                    if (!directory.mkdirs()) {                        Log.e(TAG, "Unable to create .thumbnails directory "                                + directory.toString());                    }                }                       try {                mMiniThumbFile = new RandomAccessFile(f, "rw");                miniThumbFile = new RandomAccessFile(f, "rw");            } catch (IOException ex) {                 // Open as read-only so we can at least read the existing                 // thumbnails.                try {                    mMiniThumbFile = new RandomAccessFile(f, "r");miniThumbFile = new RandomAccessFile(f, "r");                } catch (IOException ex2) {                }            }            if (mMiniThumbFile != null) {                mChannel = mMiniThumbFile.getChannel();            }            mMiniThumbFilesMap.put(miniThumbDataFileId, miniThumbFile);        }        return mMiniThumbFile;        return miniThumbFile;    }     public MiniThumbFile(Uri uri) {@@ -189,10 +231,19 @@ public class MiniThumbFile {     }     public synchronized void deactivate() {        if (mMiniThumbFile != null) {        if (mMiniThumbFilesMap != null) {              Set<Long> keySet=mMiniThumbFilesMap.keySet();            try {                mMiniThumbFile.close();                mMiniThumbFile = null;for(Long key:keySet){                    RandomAccessFile file=mMiniThumbFilesMap.get(key);                    if(file!=null)                    {                        mMiniThumbFilesMap.put(key, null);                        file.close();                    }}mMiniThumbFilesMap.clear();             } catch (IOException ex) {                 // ignore exception             }@@ -205,18 +256,20 @@ public class MiniThumbFile {         // check the mini thumb file for the right data.  Right is         // defined as having the right magic number at the offset         // reserved for this "id".        RandomAccessFile r = miniThumbDataFile();        final long miniThumbDataFileId=getMiniThumbFileId(id);        RandomAccessFile r = miniThumbDataFile(miniThumbDataFileId,true);        if (r != null) {            long pos = id * BYTES_PER_MINTHUMB;            FileChannel channel=r.getChannel();            long pos = getPositionInMiniThumbFile(id);            FileLock lock = null;            try {                mBuffer.clear();                mBuffer.limit(1 + 8);                lock = mChannel.lock(pos, 1 + 8, true);                lock = channel.lock(pos, 1 + 8, true);                // check that we can read the following 9 bytes                // (1 for the "status" and 8 for the long)                if (mChannel.read(mBuffer, pos) == 9) {                if (channel.read(mBuffer, pos) == 9) {                    mBuffer.position(0);                    if (mBuffer.get() == 1) {                        return mBuffer.getLong();@@ -242,10 +295,12 @@ public class MiniThumbFile {     public synchronized void saveMiniThumbToFile(byte[] data, long id, long magic)            throws IOException {        RandomAccessFile r = miniThumbDataFile();       final long miniThumbDataFileId=getMiniThumbFileId(id);        RandomAccessFile r = miniThumbDataFile(miniThumbDataFileId);        if (r == null) return;        long pos = id * BYTES_PER_MINTHUMB;        final long pos = getPositionInMiniThumbFile(id);        FileChannel channel=r.getChannel();        FileLock lock = null;        try {            if (data != null) {@@ -266,14 +321,13 @@ public class MiniThumbFile {check = sChecker.getValue();                }                mBuffer.putLong(check);                if (LOG) Log.i(TAG, "saveMiniThumbToFile(" + id + ") flag=1, magic="                        + magic + ", length=" + data.length + ", check=" + check);                                mBuffer.put(data);                mBuffer.flip();                lock = mChannel.lock(pos, BYTES_PER_MINTHUMB, false);                mChannel.write(mBuffer, pos);                lock = channel.lock(pos, BYTES_PER_MINTHUMB, false);                channel.write(mBuffer, pos);                if (LOG) Log.i(TAG, "saveMiniThumbToFile(" + id + ") flag=1, magic="                        + magic + ", length=" + data.length + ", check=" + check);            }        } catch (IOException ex) {            Log.e(TAG, "couldn't save mini thumbnail data for "@@ -319,27 +373,29 @@ public class MiniThumbFile {      * @return      */     public synchronized byte[] getMiniThumbFromFile(long id, byte [] data, ThumbResult result) {        RandomAccessFile r = miniThumbDataFile();        final long miniThumbDataFileId=getMiniThumbFileId(id);        RandomAccessFile r = miniThumbDataFile(miniThumbDataFileId,true);        if (r == null) return null;        long pos = id * BYTES_PER_MINTHUMB;        long pos = getPositionInMiniThumbFile(id);        FileChannel channel=r.getChannel();        FileLock lock = null;        try {            mBuffer.clear();            lock = mChannel.lock(pos, BYTES_PER_MINTHUMB, true);            int size = mChannel.read(mBuffer, pos);            lock = channel.lock(pos, BYTES_PER_MINTHUMB, true);            int size = channel.read(mBuffer, pos);            if (size > 1 + 8 + 4 + 8) { // flag, magic, length, check code                mBuffer.position(0);                byte flag = mBuffer.get();                long magic = mBuffer.getLong();                int length = mBuffer.getInt();                long check = mBuffer.getLong();                if (LOG) Log.i(TAG, "getMiniThumbFromFile(" + id + ") flag=" + flag                        + ", magic=" + magic + ", length=" + length + ", check=" + check);                               long newCheck = UNKNOWN_CHECK_CODE;                if (size >= 1 + 8 + 4 + 8 + length && data.length >= length) {                    mBuffer.get(data, 0, length);                    Log.i(TAG, " success to getMiniThumbFromFile(" + id + ") flag=" + flag                            + ", magic=" + magic + ", length=" + length + ", check=" + check);                    synchronized (sChecker) {                        sChecker.reset();                        sChecker.update(data, 0, length);

     
     
             MediaScanner.java文件的修改如下:             
<div class="dp-highlighter bg_java" sizcache="27" sizset="68"><div class="bar" sizcache="27" sizset="68"><div class="tools" sizcache="27" sizset="68"><strong>[java]</strong> <a target=_blank title="view plain" class="ViewSource" href="http://blog.csdn.net/fengye810130/article/details/9118221#">view plain</a><a target=_blank title="copy" class="CopyToClipboard" href="http://blog.csdn.net/fengye810130/article/details/9118221#">copy</a><a target=_blank title="print" class="PrintSource" href="http://blog.csdn.net/fengye810130/article/details/9118221#">print</a><a target=_blank title="?" class="About" href="http://blog.csdn.net/fengye810130/article/details/9118221#">?</a></div></div><ol class="dp-j"><li class="alt"><span><span>@@-</span><span class="number">1224</span><span>,</span><span class="number">14</span><span>+</span><span class="number">1224</span><span>,</span><span class="number">14</span><span>@@</span><span class="keyword">public</span><span></span><span class="keyword">class</span><span>MediaScanner</span></span></li><li><span>c.close();</span></li><li class="alt"><span>}</span></li><li><span></span><span class="keyword">if</span><span>(videoCount!=</span><span class="number">0</span><span>){</span></li><li class="alt"><span></span><span class="comment">/*if(videoCount!=0){</span></li><li><span><span class="comment">StringfullPathString=MiniThumbFile.getThumbdataPath(mVideoThumbsUri);</span></span></li><li class="alt"><span><span class="comment">existingFiles.remove(fullPathString);</span></span></li><li><span><span class="comment">}</span></span></li><li class="alt"><span><span class="comment">if(imageCount!=0){</span></span></li><li><span><span class="comment">StringfullPathString=MiniThumbFile.getThumbdataPath(mThumbsUri);</span></span></li><li class="alt"><span><span class="comment">existingFiles.remove(fullPathString);</span></span></li><li><span><span class="comment">}</span></span></li><li class="alt"><span><span class="comment">}*/</span><span></span></span></li><li><span></span><span class="keyword">for</span><span>(StringfileToDelete:existingFiles){</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(LOG)</span></li><li><span>Log.v(TAG,</span><span class="string">"fileToDeleteis"</span><span>+fileToDelete);</span></li><li class="alt"><span>@@-</span><span class="number">1247</span><span>,</span><span class="number">7</span><span>+</span><span class="number">1247</span><span>,</span><span class="number">163</span><span>@@</span><span class="keyword">public</span><span></span><span class="keyword">class</span><span>MediaScanner</span></li><li><span>e.printStackTrace();</span></li><li class="alt"><span>}</span></li><li><span>}</span></li><li class="alt"><span></span><span class="comment">/*[robin_20120511*/</span><span></span></li><li><span></span><span class="keyword">private</span><span></span><span class="keyword">void</span><span>pruneDeadMiniThumbnailFiles(){</span></li><li class="alt"><span>HashSet<String>existingFiles=</span><span class="keyword">new</span><span>HashSet<String>();</span></li><li><span>Stringdirectory=Environment.getExternalStorageDirectory().toString()+</span><span class="string">"/DCIM/.thumbnails"</span><span>;</span></li><li class="alt"><span>Filefile=</span><span class="keyword">new</span><span>File(directory);</span></li><li><span>String[]files=(file).list();</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(files==</span><span class="keyword">null</span><span>){</span></li><li><span>files=</span><span class="keyword">new</span><span>String[</span><span class="number">0</span><span>];</span></li><li class="alt"><span>}</span></li><li><span></span><span class="keyword">for</span><span>(</span><span class="keyword">int</span><span>i=</span><span class="number">0</span><span>;i<files.length;i++){</span></li><li class="alt"><span>StringfullPathString=directory+</span><span class="string">"/"</span><span>+files[i];</span></li><li><span>existingFiles.add(fullPathString);</span></li><li class="alt"><span>}</span></li><li><span></span><span class="keyword">try</span><span>{</span></li><li class="alt"><span>Cursorc=mMediaProvider.query(</span></li><li><span>mThumbsUri,</span></li><li class="alt"><span></span><span class="keyword">new</span><span>String[]{</span><span class="string">"_data"</span><span>},</span></li><li><span></span><span class="keyword">null</span><span>,</span></li><li class="alt"><span></span><span class="keyword">null</span><span>,</span></li><li><span></span><span class="keyword">null</span><span>);</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(</span><span class="keyword">null</span><span>!=c){</span></li><li><span></span><span class="keyword">if</span><span>(c.moveToFirst()){</span></li><li class="alt"><span></span><span class="keyword">do</span><span>{</span></li><li><span>StringfullPathString=c.getString(</span><span class="number">0</span><span>);</span></li><li class="alt"><span>existingFiles.remove(fullPathString);</span></li><li><span>}</span><span class="keyword">while</span><span>(c.moveToNext());</span></li><li class="alt"><span>}</span></li><li><span>c.close();</span></li><li class="alt"><span>}</span></li><li><span>c=mMediaProvider.query(</span></li><li class="alt"><span>mVideoThumbsUri,</span></li><li><span></span><span class="keyword">new</span><span>String[]{</span><span class="string">"_data"</span><span>},</span></li><li class="alt"><span></span><span class="keyword">null</span><span>,</span></li><li><span></span><span class="keyword">null</span><span>,</span></li><li class="alt"><span></span><span class="keyword">null</span><span>);</span></li><li><span></span><span class="keyword">if</span><span>(</span><span class="keyword">null</span><span>!=c){</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(c.moveToFirst()){</span></li><li><span></span><span class="keyword">do</span><span>{</span></li><li class="alt"><span>StringfullPathString=c.getString(</span><span class="number">0</span><span>);</span></li><li><span>existingFiles.remove(fullPathString);</span></li><li class="alt"><span>}</span><span class="keyword">while</span><span>(c.moveToNext());</span></li><li><span>}</span></li><li class="alt"><span>c.close();</span></li><li><span>}</span></li><li class="alt"><span>Stringstrs[];</span></li><li><span></span><span class="keyword">long</span><span>fileSN;</span></li><li class="alt"><span></span><span class="keyword">long</span><span>id0;</span></li><li><span></span><span class="keyword">long</span><span>id1;</span></li><li class="alt"><span></span><span class="keyword">int</span><span>blockNum=MiniThumbFile.getMiniThumbDataFileBlockNum();</span></li><li><span></span><span class="keyword">final</span><span>Stringselection_IMAGE=</span><span class="string">""</span><span>+Images.Thumbnails.IMAGE_ID+</span><span class="string">">=?AND"</span><span>+Images.Thumbnails.IMAGE_ID+</span><span class="string">"<?"</span><span>;</span></li><li class="alt"><span></span><span class="keyword">final</span><span>StringsortOrder_IMAGE=Images.Thumbnails.IMAGE_ID;</span></li><li><span></span><span class="keyword">final</span><span>Stringselection_VIDEO=</span><span class="string">""</span><span>+Video.Thumbnails.VIDEO_ID+</span><span class="string">">=?AND"</span><span>+Video.Thumbnails.VIDEO_ID+</span><span class="string">"<?"</span><span>;</span></li><li class="alt"><span></span><span class="keyword">final</span><span>StringsortOrder_VIDEO=Video.Thumbnails.VIDEO_ID;</span></li><li><span>HashSet<String>fileSet=</span><span class="keyword">new</span><span>HashSet<String>(existingFiles);</span></li><li class="alt"><span></span><span class="keyword">for</span><span>(StringfileToDelete:fileSet){</span></li><li><span>strs=MiniThumbFile.parseFileName(fileToDelete);</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(strs==</span><span class="keyword">null</span><span>||strs.length!=</span><span class="number">4</span><span>)</span></li><li><span>{</span></li><li class="alt"><span>existingFiles.remove(fileToDelete);</span></li><li><span></span><span class="keyword">continue</span><span>;</span></li><li class="alt"><span>}</span></li><li><span></span><span class="keyword">if</span><span>(</span><span class="string">"images"</span><span>.equals(strs[</span><span class="number">2</span><span>])||</span><span class="string">"video"</span><span>.equals(strs[</span><span class="number">2</span><span>]))</span></li><li class="alt"><span>{</span></li><li><span>fileSN=Long.parseLong(strs[</span><span class="number">3</span><span>]);</span></li><li class="alt"><span>id0=blockNum*fileSN;</span></li><li><span>id1=blockNum*(fileSN+</span><span class="number">1</span><span>);</span></li><li class="alt"><span></span><span class="keyword">final</span><span>String[]selectionArgs=</span><span class="keyword">new</span><span>String[]{id0+</span><span class="string">""</span><span>,id1+</span><span class="string">""</span><span>};</span></li><li><span></span><span class="keyword">if</span><span>(</span><span class="string">"images"</span><span>.equals(strs[</span><span class="number">2</span><span>]))</span></li><li class="alt"><span>{</span></li><li><span></span></li><li class="alt"><span>c=mMediaProvider.query(</span></li><li><span>mThumbsUri,</span></li><li class="alt"><span></span><span class="keyword">new</span><span>String[]{Images.Thumbnails.IMAGE_ID},</span></li><li><span>selection_IMAGE,</span></li><li class="alt"><span>selectionArgs,</span></li><li><span>sortOrder_IMAGE);</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(</span><span class="keyword">null</span><span>!=c){</span></li><li><span></span><span class="keyword">if</span><span>(c.getCount()></span><span class="number">0</span><span>){</span></li><li class="alt"><span></span></li><li><span>existingFiles.remove(fileToDelete);</span></li><li class="alt"><span>}</span></li><li><span>c.close();</span></li><li class="alt"><span>}</span></li><li><span>}</span></li><li class="alt"><span></span><span class="keyword">else</span><span></span><span class="keyword">if</span><span>(</span><span class="string">"video"</span><span>.equals(strs[</span><span class="number">2</span><span>]))</span></li><li><span>{</span></li><li class="alt"><span>c=mMediaProvider.query(</span></li><li><span>mVideoThumbsUri,</span></li><li class="alt"><span></span><span class="keyword">new</span><span>String[]{Video.Thumbnails.VIDEO_ID},</span></li><li><span>selection_VIDEO,</span></li><li class="alt"><span>selectionArgs,</span></li><li><span>sortOrder_VIDEO);</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(</span><span class="keyword">null</span><span>!=c){</span></li><li><span></span><span class="keyword">if</span><span>(c.getCount()></span><span class="number">0</span><span>){</span></li><li class="alt"><span>existingFiles.remove(fileToDelete);</span></li><li><span>}</span></li><li class="alt"><span>c.close();</span></li><li><span>}</span></li><li class="alt"><span>}</span></li><li><span>}</span></li><li class="alt"><span></span><span class="keyword">else</span><span></span></li><li><span>{</span></li><li class="alt"><span>existingFiles.remove(fileToDelete);</span></li><li><span>}</span></li><li class="alt"><span>}</span></li><li><span></span><span class="keyword">for</span><span>(StringfileToDelete:existingFiles){</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(LOG)</span></li><li><span>Log.v(TAG,</span><span class="string">"fileToDeleteis"</span><span>+fileToDelete);</span></li><li class="alt"><span></span><span class="keyword">try</span><span>{</span></li><li><span>(</span><span class="keyword">new</span><span>File(fileToDelete)).delete();</span></li><li class="alt"><span>}</span><span class="keyword">catch</span><span>(SecurityExceptionex){</span></li><li><span>ex.printStackTrace();</span></li><li class="alt"><span>}</span></li><li><span>}</span></li><li class="alt"><span>file=</span><span class="keyword">new</span><span>File(directory);</span></li><li><span></span><span class="keyword">long</span><span>freeDiskSpape=(file.getUsableSpace()>></span><span class="number">20</span><span>);</span></li><li class="alt"><span></span><span class="comment">/*</span></li><li><span><span class="comment">*whenthefreeDiskisverylow(<100M),deleteallMiniThumbFile</span></span></li><li class="alt"><span><span class="comment">*/</span><span></span></span></li><li><span></span><span class="keyword">if</span><span>(freeDiskSpape<</span><span class="number">100</span><span>)</span></li><li class="alt"><span>{</span></li><li><span>files=(file).list();</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(files==</span><span class="keyword">null</span><span>){</span></li><li><span>files=</span><span class="keyword">new</span><span>String[</span><span class="number">0</span><span>];</span></li><li class="alt"><span>}</span></li><li><span></span><span class="keyword">for</span><span>(</span><span class="keyword">int</span><span>i=</span><span class="number">0</span><span>;i<files.length;i++){</span></li><li class="alt"><span>StringfullPathString=directory+</span><span class="string">"/"</span><span>+files[i];</span></li><li><span>existingFiles.add(fullPathString);</span></li><li class="alt"><span>}</span></li><li><span>fileSet=</span><span class="keyword">new</span><span>HashSet<String>(existingFiles);</span></li><li class="alt"><span></span><span class="keyword">for</span><span>(StringfileToDelete:fileSet){</span></li><li><span>strs=MiniThumbFile.parseFileName(fileToDelete);</span></li><li class="alt"><span></span><span class="keyword">if</span><span>(strs==</span><span class="keyword">null</span><span>||strs.length!=</span><span class="number">4</span><span>)</span></li><li><span>{</span></li><li class="alt"><span>existingFiles.remove(fileToDelete);</span></li><li><span></span><span class="keyword">continue</span><span>;</span></li><li class="alt"><span>}</span></li><li><span>}</span></li><li class="alt"><span></span><span class="keyword">for</span><span>(StringfileToDelete:existingFiles){</span></li><li><span></span><span class="keyword">if</span><span>(LOG)</span></li><li class="alt"><span>Log.v(TAG,</span><span class="string">"MemeroyisveryLow.deleteMiniThumbFile:"</span><span>+fileToDelete);</span></li><li><span></span><span class="keyword">try</span><span>{</span></li><li class="alt"><span>(</span><span class="keyword">new</span><span>File(fileToDelete)).delete();</span></li><li><span>}</span><span class="keyword">catch</span><span>(SecurityExceptionex){</span></li><li class="alt"><span>ex.printStackTrace();</span></li><li><span>}</span></li><li class="alt"><span>}</span></li><li><span></span></li><li class="alt"><span>}</span></li><li><span>Log.v(TAG,</span><span class="string">"pruneDeadMiniThumbnailFiles..."</span><span>+c);</span></li><li class="alt"><span>}</span><span class="keyword">catch</span><span>(RemoteExceptione){</span></li><li><span></span><span class="comment">/*Wewillsoonbekilled...*/</span><span></span></li><li class="alt"><span>e.printStackTrace();</span></li><li><span>}</span></li><li class="alt"><span>}</span></li><li><span></span><span class="comment">/*robin_20120511]*/</span><span></span></li><li class="alt"><span></span><span class="keyword">private</span><span></span><span class="keyword">void</span><span>postscan(String[]directories)</span><span class="keyword">throws</span><span>RemoteException{</span></li><li><span>Iterator<FileCacheEntry>iterator=mFileCache.values().iterator();</span></li><li class="alt"><span>@@-</span><span class="number">1306</span><span>,</span><span class="number">8</span><span>+</span><span class="number">1462</span><span>,</span><span class="number">12</span><span>@@</span><span class="keyword">public</span><span></span><span class="keyword">class</span><span>MediaScanner</span></li><li><span></span><span class="keyword">if</span><span>((mOriginalCount==</span><span class="number">0</span><span>||mOriginalVideoCount==</span><span class="number">0</span><span>)</span></li><li class="alt"><span>&&mImagesUri.equals(Images.Media.getContentUri(</span><span class="string">"external"</span><span>))){</span></li><li><span>pruneDeadThumbnailFiles();</span></li><li class="alt"><span>}</span><span class="comment">/*[robin_20120511*/</span><span></span></li><li><span></span><span class="keyword">else</span><span></span><span class="keyword">if</span><span>(mImagesUri.equals(Images.Media.getContentUri(</span><span class="string">"external"</span><span>)))</span></li><li class="alt"><span>{</span></li><li><span>pruneDeadMiniThumbnailFiles();</span></li><li class="alt"><span>}</span></li><li><span></span></li><li class="alt"><span></span><span class="comment">/*robin_20120511]*/</span><span></span></li><li><span></span><span class="comment">/*allowGCtocleanup*/</span><span></span></li><li class="alt"><span>mPlayLists=</span><span class="keyword">null</span><span>;</span></li><li><span>mFileCache=</span><span class="keyword">null</span><span>;</span></li><li class="alt"><span>@@-</span><span class="number">1399</span><span>,</span><span class="number">7</span><span>+</span><span class="number">1559</span><span>,</span><span class="number">12</span><span>@@</span><span class="keyword">public</span><span></span><span class="keyword">class</span><span>MediaScanner</span></li><li><span></span><span class="keyword">long</span><span>prune=System.currentTimeMillis();</span></li><li class="alt"><span>pruneDeadThumbnailFiles();</span></li><li><span></span><span class="keyword">if</span><span>(LOG)Log.d(TAG,</span><span class="string">"mtkPostscan:pruneDeadThumbnailFilestakes"</span><span>+(System.currentTimeMillis()-prune)+</span><span class="string">"ms."</span><span>);</span></li><li class="alt"><span>}</span><span class="comment">/*[robin_20120511*/</span><span></span></li><li><span></span><span class="keyword">else</span><span></span><span class="keyword">if</span><span>(mImagesUri.equals(Images.Media.getContentUri(</span><span class="string">"external"</span><span>)))</span></li><li class="alt"><span>{</span></li><li><span>pruneDeadMiniThumbnailFiles();</span></li><li class="alt"><span>}</span></li><li><span></span><span class="comment">/*robin_20120511]*/</span><span></span></li><li class="alt"><span></span></li><li><span></span><span class="comment">//allowGCtocleanup </span><span></span></li><li class="alt"><span>mPlayLists=</span><span class="keyword">null</span><span>;</span></li></ol></div><pre class="java" style="DISPLAY: none" name="code">@@ -1224,14 +1224,14 @@ public class MediaScanner                c.close();             }            if (videoCount != 0) {            /*if (videoCount != 0) {                 String fullPathString = MiniThumbFile.getThumbdataPath(mVideoThumbsUri);                 existingFiles.remove(fullPathString);             }             if (imageCount != 0) {                 String fullPathString = MiniThumbFile.getThumbdataPath(mThumbsUri);                 existingFiles.remove(fullPathString);            }            }*/             for (String fileToDelete : existingFiles) {                 if (LOG)                     Log.v(TAG, "fileToDelete is " + fileToDelete);@@ -1247,7 +1247,163 @@ public class MediaScanner             e.printStackTrace();         }     }    /*[robin_20120511*/    private void pruneDeadMiniThumbnailFiles() {        HashSet<String> existingFiles = new HashSet<String>();        String directory = Environment.getExternalStorageDirectory().toString() + "/DCIM/.thumbnails";        File file=new File(directory);        String [] files = (file).list();        if (files == null) {            files = new String[0];        }        for (int i=0; i < files.length; i++) {            String fullPathString = directory + "/" + files[i];            existingFiles.add(fullPathString);        }        try {            Cursor c = mMediaProvider.query(                    mThumbsUri,                    new String [] { "_data" },                    null,                    null,                    null);             if (null != c) {                if (c.moveToFirst()) {                    do {                        String fullPathString = c.getString(0);                        existingFiles.remove(fullPathString);                    } while (c.moveToNext());                }                c.close();            }            c = mMediaProvider.query(                    mVideoThumbsUri,                    new String [] { "_data" },                    null,                    null,                    null);            if (null != c) {                if (c.moveToFirst()) {                    do {                        String fullPathString = c.getString(0);                        existingFiles.remove(fullPathString);                    } while (c.moveToNext());                }                c.close();            }            String strs[];            long fileSN;            long id0;            long id1;            int blockNum=MiniThumbFile.getMiniThumbDataFileBlockNum();            final String selection_IMAGE=" "+Images.Thumbnails.IMAGE_ID+">=? AND "+Images.Thumbnails.IMAGE_ID+"<?";            final String sortOrder_IMAGE=Images.Thumbnails.IMAGE_ID;            final String selection_VIDEO=" "+Video.Thumbnails.VIDEO_ID+">=? AND "+Video.Thumbnails.VIDEO_ID+"<?";            final String sortOrder_VIDEO=Video.Thumbnails.VIDEO_ID;            HashSet<String> fileSet=new HashSet<String>(existingFiles);            for (String fileToDelete : fileSet) {              strs=MiniThumbFile.parseFileName(fileToDelete);                if(strs==null||strs.length!=4)                {                      existingFiles.remove(fileToDelete);                      continue;                }                if("images".equals(strs[2])||"video".equals(strs[2]))                {                    fileSN=Long.parseLong(strs[3]);                    id0=blockNum*fileSN;                    id1=blockNum*(fileSN+1);                    final String[] selectionArgs= new String[]{id0+"",id1+""};                    if("images".equals(strs[2]))                    {                                               c = mMediaProvider.query(                                mThumbsUri,                               new String [] { Images.Thumbnails.IMAGE_ID },                               selection_IMAGE,                                selectionArgs,                                sortOrder_IMAGE);                        if (null != c) {                            if (c.getCount()>0) {                                                           existingFiles.remove(fileToDelete);                                   }                            c.close();                        }                    }                    else if ("video".equals(strs[2]))                    {                        c = mMediaProvider.query(                                mVideoThumbsUri,                                new String [] { Video.Thumbnails.VIDEO_ID },                                selection_VIDEO,                                selectionArgs,                                sortOrder_VIDEO);                        if (null != c) {                            if (c.getCount()>0) {                              existingFiles.remove(fileToDelete);                            }                            c.close();                        }                                       }                }                else                {                      existingFiles.remove(fileToDelete);                }            }            for (String fileToDelete : existingFiles) {                if (LOG)                    Log.v(TAG, "fileToDelete is " + fileToDelete);                try {                    (new File(fileToDelete)).delete();                } catch (SecurityException ex) {                    ex.printStackTrace();                }            }            file=new File(directory);            long freeDiskSpape=(file.getUsableSpace()>>20);            /*             * when the free Disk is very low(<100M),delete all MiniThumbFile             */            if(freeDiskSpape<100)            {files = (file).list();                if (files == null) {                    files = new String[0];                }                for (int i=0; i < files.length; i++) {                    String fullPathString = directory + "/" + files[i];                    existingFiles.add(fullPathString);                }                fileSet=new HashSet<String>(existingFiles);                for (String fileToDelete : fileSet) {                      strs=MiniThumbFile.parseFileName(fileToDelete);                    if(strs==null||strs.length!=4)                    {existingFiles.remove(fileToDelete);continue;                    }                }                for (String fileToDelete : existingFiles) {                    if (LOG)                        Log.v(TAG, "Memeroy is very Low.delete MiniThumbFile:" + fileToDelete);                    try {                        (new File(fileToDelete)).delete();                    } catch (SecurityException ex) {                        ex.printStackTrace();                    }                }                           }            Log.v(TAG, "pruneDeadMiniThumbnailFiles... " + c);        } catch (RemoteException e) {            /* We will soon be killed...*/            e.printStackTrace();        }    }    /*robin_20120511]*/     private void postscan(String[] directories) throws RemoteException {         Iterator<FileCacheEntry> iterator = mFileCache.values().iterator();@@ -1306,8 +1462,12 @@ public class MediaScanner         if ((mOriginalCount == 0 || mOriginalVideoCount == 0)                 && mImagesUri.equals(Images.Media.getContentUri("external"))) {            pruneDeadThumbnailFiles();        }/*[robin_20120511*/        else if (mImagesUri.equals(Images.Media.getContentUri("external")))        {            pruneDeadMiniThumbnailFiles();        }        /*robin_20120511]*/        /* allow GC to clean up*/        mPlayLists = null;        mFileCache = null;@@ -1399,7 +1559,12 @@ public class MediaScanner             long prune = System.currentTimeMillis();             pruneDeadThumbnailFiles();             if (LOG) Log.d(TAG, "mtkPostscan: pruneDeadThumbnailFiles takes " + (System.currentTimeMillis() - prune) + "ms.");        }/*[robin_20120511*/        else if (mImagesUri.equals(Images.Media.getContentUri("external")))        {             pruneDeadMiniThumbnailFiles();        }        /*robin_20120511]*/               // allow GC to clean up         mPlayLists = null;


             
结束!

更多相关文章

  1. Android视频文件格式解析相关分析
  2. 使用SAX或者DOM或者pull解析XML文件
  3. Android读取文件方法总结
  4. Android使用PULL解析和生成XML文件
  5. android中svg文件的使用
  6. android资源文件之:shape详解
  7. Android 通过命令将文件导出
  8. Android开发8――利用pull解析器读写XML文件

随机推荐

  1. Android学习笔记(4)---模拟手机拨号器
  2. 关于Android的组件名
  3. Android使用 LruCache 缓存图片
  4. 避免内存泄漏
  5. Android中@+id和@id的区别
  6. 使用Android模拟器测试Linux驱动(1)
  7. android的开发耗电量需要注意哪些
  8. Android(安卓)性能优化之内存泄漏检测以
  9. Android应用资源的使用方法(数组、颜色、
  10. iTestin云测试工具之我见