歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Android原理之動態牆紙

Livewallpaper,即動態牆紙,是Android的一大3D特色功能,用戶可以在桌面選擇加載動態牆紙,讓自己的手機桌面背景旋動起來。

相對於靜態桌面壁紙,動態牆紙可以展示各種動態變化的背景,而與傳統手機系統采用GIF作為動態背景不同的是,Android的動態牆紙並不是GIF圖片,而是一個標准的Android應用程序,也就是APK。既然是應用程序,當然意味著天生具有有GIF圖片不具備的功能——能與用戶發生交互,而且動態的背景變化絕不僅僅局限於GIF圖片那般只能是固定的幾張圖片的循環播放。

需要指出的是,標准的Android系統可以支持將動態的GIF圖片設置為靜態牆紙,但並不能將GIF圖片動態的運行起來。也就是說,如果你將GIF圖片作為靜態牆紙,你只能看到一幀靜態的圖片,不能像很多其他系統的山寨機那樣能夠在桌面看到GIF圖片動態效果。這種局限是Android的一大缺陷,這個缺陷是Android牆紙框架設計缺陷有關。當然了,既然你可以加載豐富類型的旋動的具有交互效果的Android動態牆紙,那麼GIF圖片的少許遺憾完全可以接受。

Android內置的動態牆紙都是基於RenderScript實現的,RenderScript是Google用於Android的一種類C語言,其與C語言語言結構很類似,其對OpenGL的標准API進行了簡單的封裝,可以在運行時再加載RenderScript文件運行。也就是說,如果你想基於RenderScript開發新的動態牆紙,你應該對OpenGL的常用API有一定的了解。此外,Google目前對RenderScript的開發資料還不是很完善,在公開發布的SDK裡也暫時沒有把RenderScript繼承進ADT,換言之,如果你想用RenderScript開發新動態牆紙,你不能基於ADT和SDK在Eclipse下進行開發,而應該下載完整源代碼並編譯整個框架,然後在自己的Linux編譯環境裡去寫新應用。因為RenderScript是要調用OpenGL接口的,你開發的應用要能在真機上運行起來,你的機子必須支持3D,也就是OpenGL。如果你發現有的廠商的手機桌面並沒有加載動態牆紙的入口,那麼不用多說,那一定是該手機根本不支持3D,這一點對於想購買真機來學習Andoid開發的朋友來說就一定要當心了。

Google在發布的各個Android版本裡都內置了一定數量的動態牆紙,各個版本的動態牆紙代碼有少許差別,但是動態牆紙的名稱、視效、個數基本都是一樣的。下面我們看下這些動態牆紙的代碼在什麼位置。我們打開Google的Android源代碼地址:http://android.git.kernel.org/

可以看到,Android內置的動態牆紙都在packages/wallpapers/這個目錄裡,通過git clone方法(參見博文“Android源碼下載——用git clone實現單個目錄下載”,http://www.linuxidc.com/Linux/2011-07/38953.htm )快速的下載各個子目錄各個Android版本的Android內置動態牆紙代碼。其中,Basic、MusicVisualization兩個目錄裡都包括了多個相同代碼框架的多個動態牆紙,MagicSmoke目錄只包含魔幻煙霧一個動態牆紙,LivePicker目錄裡包含的是動態牆紙的選擇列表的代碼,也就是你在桌面選擇添加動態牆紙時出現的系統裡所有動態牆紙的那個列表的實現代碼。

那麼,動態牆紙的本質是什麼呢?前文已述,是APK,不過是比較特殊的APK。我們不妨打開MagicSomke的AndroidManifest.xml文件:

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!--  
  3. /*  
  4. **  
  5. ** Copyright 2008, The Android Open Source Project  
  6. **  
  7. ** Licensed under the Apache License, Version 2.0 (the "License");  
  8. ** you may not use this file except in compliance with the License.  
  9. ** You may obtain a copy of the License at  
  10. **  
  11. **     http://www.apache.org/licenses/LICENSE-2.0  
  12. **  
  13. ** Unless required by applicable law or agreed to in writing, software  
  14. ** distributed under the License is distributed on an "AS IS" BASIS,  
  15. ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
  16. ** See the License for the specific language governing permissions and  
  17. ** limitations under the License.  
  18. */  
  19. -->  
  20. <manifest  
  21.     xmlns:android="http://schemas.android.com/apk/res/android"  
  22.     package="com.android.magicsmoke">  
  23.   
  24.     <original-package android:name="com.android.magicsmoke" />  
  25.   
  26.     <uses-feature android:name="android.software.live_wallpaper" />  
  27.   
  28.     <uses-permission android:name="android.permission.SET_WALLPAPER_COMPONENT" />  
  29.     <uses-permission android:name="android.permission.BIND_WALLPAPER" />  
  30.   
  31.     <application  
  32.         android:label="@string/wallpapers"  
  33.         android:icon="@drawable/ic_launcher_wallpaper">  
  34.   
  35.         <service  
  36.             android:label="@string/wallpaper_magicsmoke"  
  37.             android:name="MagicSmoke"  
  38.             android:permission="android.permission.BIND_WALLPAPER">  
  39.             <intent-filter>  
  40.                 <action android:name="android.service.wallpaper.WallpaperService" />  
  41.             </intent-filter>  
  42.             <meta-data android:name="android.service.wallpaper" android:resource="@xml/magicsmoke" />  
  43.         </service>  
  44.   
  45.         <activity  
  46.             android:name="com.android.magicsmoke.MagicSmokeSelector"  
  47.             android:theme="@style/Preview"  
  48.             android:exported="true">  
  49.         </activity>  
  50.   
  51.     </application>  
  52.   
  53. </manifest>  

我想細心的朋友已經猜出來了,Android動態牆紙的本質是一個“Service”,這個Service能夠被主界面Launcher加載。那麼Launcher是如何能識別這個包含動態牆紙Service的APK的呢?上面這個AndroidManifest.xml文件的intent-filter的action洩露了天機:

<action android:name="android.service.wallpaper.WallpaperService" />

不錯,系統正式通過APK的這個action把其當做一個動態牆紙加載進LivePicker列表,用戶在LivePicker列表裡選擇自己喜歡的動態牆紙,進而將動態牆紙顯示進Launcher的背後。

需要指出的是,Android的動態牆紙雖然似乎是顯示在Launcher的背景裡,但其實這只是假象,動態牆紙和Launcher是完全不同的兩個進程,只不過Launcher和動態牆紙的進程可以通過框架裡的WallpaperManager進行進程間通信罷了,用戶在Launcher桌面滑動、點擊屏幕時有的動態牆紙能產生交互效果,實際上就是這個進程通信完成的。如果你通過代碼將Launcher的背景設置為非透明的,比如以不透明的圖片或者顏色作為背景,那麼,你將看不到任何動態牆紙效果,當然,這樣的話,靜態牆紙你也不會看到了。

Copyright © Linux教程網 All Rights Reserved