<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                MSS從Service派生,并且實現了Runnable接口。下面是它的定義: **MediaScannerService.java** ~~~ MediaScannerService extends Service implementsRunnable //MSS實現了Runnable接口,這表明它可能會創建工作線程 ~~~ 根據SDK中對Service生命周期的描述,Service剛創建時會調用onCreate函數,接著就是onStartCommand函數,之后外界每調用一次startService都會觸發onStartCommand函數。接下來去了解一下onCreate函數及onStartCommand函數。 1. onCreate的分析 onCreate函數的代碼如下所示:(這是MSS被系統創建時調用的,在它的整個生命周期內僅調用一次。) **MediaScannerService.java** ~~~ public void onCreate(){ //獲得電源鎖,防止在掃描過程中休眠 PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); //掃描工作是一個漫長的工程,所以這里單獨創建一個工作線程,線程函數就是 //MSS實現的Run函數 Threadthr = new Thread(null, this, "MediaScannerService"); thr.start(); | ~~~ onCreate將創建一個工作線程: ~~~ publicvoid run() { /* 設置本線程的優先級,這個函數的調用有很重要的作用,因為媒體掃描可能會耗費很長 時間,如果不調低優先級的話,CPU將一直被MSS占用,導致用戶感覺系統變得很慢 */ Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_LESS_FAVORABLE); Looper.prepare(); mServiceLooper = Looper.myLooper(); /* 創建一個Handler,以后發送給這個Handler的消息都會由工作線程處理。 這一部分內容,已在第5章Handler中分析過了。 */ mServiceHandler = new ServiceHandler(); Looper.loop(); } ~~~ onCreate后,MSS將會創建一個帶消息處理機制的工作線程,那么消息是怎么投遞到這個線程中的呢? 2. onStartCommand的分析 還記得MSR的scan函數嗎?如下所示: **MediaScannerReceiver.java::scan函數** ~~~ context.startService( new Intent(context, MediaScannerService.class).putExtras(args)); ~~~ 其中Intent包含了目錄掃描請求的目標/mnt/sdcard。這個Intent發出后,最終由MSS的onStartCommand收到并處理,其代碼如下所示: **MediaScannerService.java** ~~~ @Override publicint onStartCommand(Intent intent, int flags, int startId) { /* 等待mServiceHandler被創建。耕耘這段代碼的碼農難道不知道 HandlerThread這個類嗎?不熟悉它的讀者請再閱讀第5章的5.4節。 */ while(mServiceHandler == null) { synchronized (this) { try { wait(100); } catch (InterruptedException e) { } } } ...... Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; msg.obj = intent.getExtras(); //往這個Handler投遞消息,最終由工作線程處理。 mServiceHandler.sendMessage(msg); ...... } ~~~ onStartCommand將把掃描請求信息投遞到工作線程去處理。 3. 處理掃描請求 掃描請求由ServiceHandler的handleMessage函數處理,其代碼如下所示: **MediaScannerService.java** ~~~ private final class ServiceHandler extendsHandler { @Override public void handleMessage(Message msg) { Bundle arguments = (Bundle) msg.obj; String filePath = arguments.getString("filepath"); try { ...... } else { String volume =arguments.getString("volume"); String[] directories =null; if(MediaProvider.INTERNAL_VOLUME.equals(volume)) { //如果是掃描內部存儲的話,實際上掃描的目錄是/system/media directories = newString[] { Environment.getRootDirectory() + "/media", }; } else if (MediaProvider.EXTERNAL_VOLUME.equals(volume)){ //掃描外部存儲,設置掃描目標位/mnt/sdcard directories = new String[]{ Environment.getExternalStorageDirectory().getPath()}; } if (directories != null) { /* 調用scan函數開展文件夾掃描工作,可以一次為這個函數設置多個目標文件夾, 不過這里只有/mnt/sdcard一個目錄 */ scan(directories, volume); ...... stopSelf(msg.arg1); } } ~~~ 下面,單獨用一小節來分析這個scan函數。 4. MSS的scan函數分析 scan的代碼如下所示: **MediaScannerService.java** ~~~ private void scan(String[] directories, StringvolumeName) { mWakeLock.acquire(); ContentValuesvalues = new ContentValues(); values.put(MediaStore.MEDIA_SCANNER_VOLUME, volumeName); //MSS通過insert特殊Uri讓MediaProvider做一些準備工作 UriscanUri = getContentResolver().insert( MediaStore.getMediaScannerUri(), values); Uri uri= Uri.parse("file://" + directories[0]); //向系統發送一個MEDIA_SCANNER_STARTED廣播。 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_STARTED, uri)); try { //openDatabase函數也是通過insert特殊Uri讓MediaProvider打開數據庫 if (volumeName.equals(MediaProvider.EXTERNAL_VOLUME)) { openDatabase(volumeName); } //創建媒體掃描器,并調用它的scanDirectories函數掃描目標文件夾 MediaScanner scanner = createMediaScanner(); scanner.scanDirectories(directories,volumeName); } ...... //通過特殊Uri讓MediaProvider做一些清理工作 getContentResolver().delete(scanUri, null, null); //向系統發送MEDIA_SCANNER_FINISHED廣播 sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_FINISHED, uri)); mWakeLock.release(); } ~~~ 上面代碼中,比較復雜的是MSS和MP的交互。除了后文中即將看到的正常數據庫操作外,MSS還經常會使用一些特殊的Uri來做數據庫操作,而MP針對這些Uri會做一些特殊處理,例如打開數據庫文件等。 本章不擬對MediaProvider做過多的討論,這部分知識對那些讀完前9章的讀者來說,應該不是什么難題。如有可能,請讀者自己整理MediaProvider的工作流程,然后提供給大家一起學習,探討。 看MSS中創建媒體掃描器的函數createMediaScanner: ~~~ private MediaScanner createMediaScanner() { //下面這個MediaScanner是在framework/base/中,稍后再分析 MediaScanner scanner = new MediaScanner(this); //獲取當前系統使用的區域信息,掃描的時候將把媒體文件中的信息轉換成當前系統使用的語言 Locale locale = getResources().getConfiguration().locale; if(locale != null) { String language = locale.getLanguage(); String country = locale.getCountry(); String localeString = null; if (language != null) { if (country != null) { //為掃描器設置當前系統使用的國家和語言。 scanner.setLocale(language+ "_" + country); } else { scanner.setLocale(language); } } } return scanner; } ~~~ MSS模塊掃描的工作就到此為止了,下面輪到主角MediaScanner登場了。在介紹主角之前,不妨先總結一下本節的內容。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看