国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院

首頁 > 系統 > Android > 正文

仿墨跡天氣在Android App中實現自定義zip皮膚更換

2020-01-02 07:03:37
字體:
來源:轉載
供稿:網友

在這里談一下墨跡天氣的換膚實現方式,不過首先聲明我只是通過反編譯以及參考了一些網上其他資料的方式推測出的換膚原理, 在這里只供參考. 若大家有更好的方式, 歡迎交流.
墨跡天氣下載的皮膚就是一個zip格式的壓縮包,在應用的時候把皮膚資源釋放到墨跡天氣應用的目錄下,更換皮膚時新的皮膚資源會替換掉老的皮膚資源每次加載的時候就是從手機硬盤上讀取圖片,這些圖片資源的命名和程序中的資源的命名保持一致,一旦找不到這些資源,可以選擇到系統默認中查找。這種實現是直接讀取了外部資源文件,在程序運行時通過代碼顯示的替換界面的背景資源。這種方式的優點是:皮膚資源的格式定義很隨意可以是zip也可以是自定義的格式,只要程序中能夠解析到資源就行,缺點是效率上的問題.

這里需要注意的一點是,再這里對壓縮包的解壓,借助了第三方工具: ant. jar進行解壓和壓縮文件. 關于ant工具的使用,我在稍后的文章中會具體介紹.

主要技術點:
如何去讀取zip文件中的資源以及皮膚文件存放方式

實現方案:如果軟件每次啟動都去讀取SD卡上的皮膚文件,速度會比較慢。較好的做法是提供一個皮膚設置的界面,用戶選擇了哪一個皮膚,就把那個皮膚文件解壓縮到”/data/data/[package name]/skin”路徑下(讀取的快速及安全性),這樣不需要跨存儲器讀取,速度較快,而且不需要每次都去zip壓縮包中讀取,不依賴SD卡中的文件,即使皮膚壓縮包文件被刪除了也沒有關系。
實現方法:
1. 在軟件的幫助或者官網的幫助中提示用戶將皮膚文件拷貝到SD卡指定路徑下。
2. 在軟件中提供皮膚設置界面。可以在菜單或者在設置中。可參考墨跡、搜狗輸入法、QQ等支持換膚的軟件。
3. 加載指定路徑下的皮膚文件,讀取其中的縮略圖,在皮膚設置界面中顯示,將用戶選中的皮膚文件解壓縮到”/data/data/[package name]/skin”路徑下。
4. 軟件中優先讀取”/data/data/[package name]/skin/”路徑下的資源。如果沒有則使用apk中的資源。

效果圖:

2016226153459744.jpg (375×517)

具體代碼:
1. AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"   package="com.tony.skin" android:versionCode="1" android:versionName="1.0">   <uses-sdk android:minSdkVersion="7" />   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />   <application android:icon="@drawable/icon" android:label="@string/app_name">     <activity android:name=".Re_Skin2Activity"          android:label="@string/app_name">       <intent-filter>         <action android:name="android.intent.action.MAIN" />         <category android:name="android.intent.category.LAUNCHER" />       </intent-filter>     </activity>    </application> </manifest> 

2.布局文件main.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   android:orientation="vertical"   android:layout_width="fill_parent"   android:layout_height="fill_parent"   android:background="#d2d2d2"   android:id="@+id/layout">   <Button android:text="導入皮膚" android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>   <Button android:text="換膚" android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>   <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content"      android:text="請先點擊“導入皮膚”,會將/sdcard/skin.zip導入到/sdcard/Skin_kris目錄下,然后點擊‘換膚'會將sdcard里面的素材用作皮膚"      android:textColor="#000"></TextView> </LinearLayout> 

3. Re_Skin2Activity:

package com.tony.skin;  import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.LinearLayout; import android.widget.Toast;  import com.tony.skin.utils.ZipUtil;  /**  *  * @author Tony  *  */ public class Re_Skin2Activity extends Activity implements OnClickListener{   private Button btnSet;   private Button btnImport;   private LinearLayout layout;   /** Called when the activity is first created. */   @Override   public void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.main);     btnSet = (Button)findViewById(R.id.button1);     btnSet.setOnClickListener(this);      btnImport = (Button)findViewById(R.id.button2);     btnImport.setOnClickListener(this);     layout = (LinearLayout)findViewById(R.id.layout);   }   @Override   public void onClick(View v) {     switch (v.getId()) {     case R.id.button1:       Bitmap bitmap= BitmapFactory.decodeFile("/sdcard/tony/skin/skin.png");               BitmapDrawable bd=new BitmapDrawable(bitmap);       btnSet.setBackgroundDrawable(bd);              layout.setBackgroundDrawable(new BitmapDrawable(BitmapFactory.decodeFile("/sdcard/Skin_kris/skin/bg/bg.png")));              break;     case R.id.button2:       ZipUtil zipp = new ZipUtil(2049);       System.out.println("begin do zip");       zipp.unZip("/sdcard/skin.zip","/sdcard/Skin_kris");       Toast.makeText(this, "導入成功", Toast.LENGTH_SHORT).show();       break;     default:       break;     }   } } 

4. ZipUtil 解壓縮處理ZIP包的工具類

package com.tony.skin.utils;  import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Enumeration; import java.util.zip.Deflater;  import org.apache.tools.zip.ZipEntry; import org.apache.tools.zip.ZipFile; import org.apache.tools.zip.ZipOutputStream;  /**  * Zip包壓縮,解壓處理工具類  * @author a  *  */ public class ZipUtil {   private ZipFile     zipFile;    private ZipOutputStream zipOut;   //壓縮Zip    private int      bufSize;  //size of bytes    private byte[]     buf;    private int       readedBytes;    public ZipUtil(){      this(512);    }     public ZipUtil(int bufSize){      this.bufSize = bufSize;      this.buf = new byte[this.bufSize];    }        /**    *    * @param srcFile 需要 壓縮的目錄或者文件    * @param destFile 壓縮文件的路徑    */   public void doZip(String srcFile, String destFile) {// zipDirectoryPath:需要壓縮的文件夾名     File zipDir;     String dirName;      zipDir = new File(srcFile);     dirName = zipDir.getName();     try {       this.zipOut = new ZipOutputStream(new BufferedOutputStream(           new FileOutputStream(destFile)));       //設置壓縮的注釋       zipOut.setComment("comment");       //設置壓縮的編碼,如果要壓縮的路徑中有中文,就用下面的編碼       zipOut.setEncoding("GBK");       //啟用壓縮        zipOut.setMethod(ZipOutputStream.DEFLATED);         //壓縮級別為最強壓縮,但時間要花得多一點        zipOut.setLevel(Deflater.BEST_COMPRESSION);               handleDir(zipDir, this.zipOut,dirName);       this.zipOut.close();     } catch (IOException ioe) {       ioe.printStackTrace();     }   }    /**    * 由doZip調用,遞歸完成目錄文件讀取    * @param dir    * @param zipOut    * @param dirName 這個主要是用來記錄壓縮文件的一個目錄層次結構的    * @throws IOException    */   private void handleDir(File dir, ZipOutputStream zipOut,String dirName) throws IOException {     System.out.println("遍歷目錄:"+dir.getName());     FileInputStream fileIn;     File[] files;      files = dir.listFiles();      if (files.length == 0) {// 如果目錄為空,則單獨創建之.       // ZipEntry的isDirectory()方法中,目錄以"/"結尾.       System.out.println("壓縮的 Name:"+dirName);       this.zipOut.putNextEntry(new ZipEntry(dirName));       this.zipOut.closeEntry();     } else {// 如果目錄不為空,則分別處理目錄和文件.       for (File fileName : files) {         // System.out.println(fileName);          if (fileName.isDirectory()) {           handleDir(fileName, this.zipOut,dirName+File.separator+fileName.getName()+File.separator);         } else {           System.out.println("壓縮的 Name:"+dirName + File.separator+fileName.getName());           fileIn = new FileInputStream(fileName);           this.zipOut.putNextEntry(new ZipEntry(dirName + File.separator+fileName.getName()));            while ((this.readedBytes = fileIn.read(this.buf)) > 0) {             this.zipOut.write(this.buf, 0, this.readedBytes);           }            this.zipOut.closeEntry();         }       }     }   }    /**    * 解壓指定zip文件    * @param unZipfile 壓縮文件的路徑    * @param destFile   解壓到的目錄     */   public void unZip(String unZipfile, String destFile) {// unZipfileName需要解壓的zip文件名     FileOutputStream fileOut;     File file;     InputStream inputStream;      try {       this.zipFile = new ZipFile(unZipfile);        for (Enumeration entries = this.zipFile.getEntries(); entries           .hasMoreElements();) {         ZipEntry entry = (ZipEntry) entries.nextElement();         file = new File(destFile+File.separator+entry.getName());          if (entry.isDirectory()) {           file.mkdirs();         } else {           // 如果指定文件的目錄不存在,則創建之.           File parent = file.getParentFile();           if (!parent.exists()) {             parent.mkdirs();           }            inputStream = zipFile.getInputStream(entry);            fileOut = new FileOutputStream(file);           while ((this.readedBytes = inputStream.read(this.buf)) > 0) {             fileOut.write(this.buf, 0, this.readedBytes);           }           fileOut.close();            inputStream.close();         }       }       this.zipFile.close();     } catch (IOException ioe) {       ioe.printStackTrace();     }   }    // 設置緩沖區大小   public void setBufSize(int bufSize) {     this.bufSize = bufSize;   } } 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
国产激情自拍_国产9色视频_丁香花在线电影小说观看 _久久久久国产精品嫩草影院
免费不卡中文字幕视频| 免费精品国产自产拍在| 国产永久免费高清在线观看| 国产99在线|亚洲| 99在线视频影院| 美女被人操视频在线观看| 欧美日韩性视频一区二区三区| 四虎成人精品在永久在线观看| 影音av资源站| 高清欧美精品xxxxx在线看| 国产午夜精品一区理论片| 国产成人精品久久一区二区小说| 国产白浆在线| 超碰免费在线观看| 91精选福利| 狠狠干天天爱| 香蕉视频网站在线观看| 国产丝袜在线| 超碰在线观看免费| free性亚洲| 96久久久久久| 国产色婷婷在线| 国产在线一二三| 青青国产在线| jizz在线视频| av在线1区2区| 在线免费观看黄色片| 最近中文av字幕在线中文| 四虎成人免费观看在线网址| 国产青青视频| 国产久草在线| 最好看更新中文字幕| 午夜影院免费| av高清在线| 一级黄色av| 在线观看的av| 亚洲高清在线免费| 在线免费观看污| 亚洲人成电影| 免费av不卡在线观看| 日韩国产成人| 久久99国产视频| 国产中文第一页| 最近中文字幕mv免费高清视频8| 免费在线黄色av| 免费不卡中文字幕视频| 日本国产在线| 国产在线视频福利| 国产专区在线| 国产桃色电影在线播放| 国产一级片在线| 国产成人福利| www.五月色.com| 天堂中文字幕在线| 国产高潮av| 亚洲国产成人综合| 国产中文字幕在线观看| 国产美女视频一区二区三区| 国产日产一区二区三区| 精品乱码一区二区三四区视频| av亚洲男人天堂| 久久久久久久久亚洲精品| 国产精品亚洲色图| 国产成人夜间影院在线观看| 在线观看av网站| 国产麻豆麻豆| 在线一二三区| 最近免费中文字幕大全免费第三页| 国产情侣高潮对白| 欧美艹逼视频| 在线观看免费高清完整| 国产乱妇乱子在线播视频播放网站| 中文字幕在线观看av| 中文av在线播放| 国产麻豆精品一区二区三区v视界| 1区2区3区在线| 亚洲伊人网在线观看| 天天操天天射天天色| 精品一区二区在线欧美| 久草国产视频| 日本h视频在线观看| 999精品网| 国产精品视频一区二区免费不卡| av网站大全在线观看| 中文字幕在线观看日本| 欧美激情福利视频在线观看免费| 国产对白在线| 国产69精品久久app免费版 | 日本免费黄色| 国产精品18久久久久久久久久| 四虎久久影院| 精品福利影院| 91九色在线看| 国产福利片在线| 国产精品久久久久久久牛牛| 五月亚洲综合| **三级三级97片毛片| 国产在线高潮| 国产九色在线| 国产免费福利网站| 成在线人视频免费视频| 青娱乐在线视频观看| 亚洲第一成年免费网站| 99热免费观看| 日本三级在线视频| 欧美日韩在线中文字幕| 欧美精品一区二区三区免费| 免费精品国产自产拍在| 久久久久国产精品嫩草影院| 另类综合图区| 综合激情丁香| 国产福利免费观看| 在线免费观看黄色av| av在线不卡免费| 国内自拍视频在线观看| √天堂8资源中文在线| 五月婷婷导航| 18av在线视频| 免费国产阿v视频在线观看| 激情丁香婷婷| 69国产精品| 女子免费在线观看视频www| 国产美女免费观看| 91高清国产| 久久国产精品久久久久久小说| 天天av综合网| av片在线观看永久免费| 黄色三级视频在线观看| 国产精品你懂的在线观看| av免费在线观| 国产一二三在线观看| 精品麻豆国产| 丁香婷婷在线| 亚洲综合色视频在线观看 | av资源网站在线观看| 国产在线视频福利| 中文天堂av| 国产美女视频一区二区二三区| 国产福利av网站| 国自产拍在线网站网址视频| 精品精品导航| 国产精品99999| 黄网址在线播放免费| 在线a人片免费观看视频| 中文字幕视频在线观看| 亚洲精品aaaa精品| 国产成人久久精品77777| 久久精品最新免费国产成人| 在线视频观看你懂的| 国产精品欧美色图| 国产精选在线观看| 久青青在线观看视频国产| 国产成人综合美国十次| 国产一级免费看| 99视频在线观看地址| 九九在线观看免费视频| 欧美日韩**字幕一区| 日韩在线天堂| 四虎www视频| av在线天堂| 亚洲www色| www在线视频观看| 日本不卡1区2区3区| 亚洲成人av高清| 日韩黄色成人| 高清色视频在线观看| 超碰免费在线播放| 成人超碰在线| 国产精品久久久久久久牛牛| 国产精品入口麻豆电影| 国产wwww| www.av在线| 国精一区二区三区| 国产一二三区在线视频| 国产人成高清视频观看| 国产成人午夜| 亚洲人av在线| 国产乱视频在线观看| 尤物免费看在线视频| 午夜视频99| 伊人影院蕉久影院在线播放| av在线网页| 天堂在线免费视频| 在线观看精品一区二区三区| 四虎a级欧美在线观看| 日本中文字幕视频在线| 国产成人亚洲欧美电影| av中文天堂在线| 国产乱xxⅹxx国语对白| 精品一区二区三区高清免费不卡| 永久免费av片在线观看全网站| 四虎国产精品永久在线| 国产另类图片| 亚色视频在线观看| 国产网红在线| 激情网站在线| 日本卡一卡2卡3卡4精品卡网站| 日本中文字幕在线播放| 羞羞视频在线免费看| 国产对白在线|