Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 讀寫Android中assets目錄下的文件的方法詳解

讀寫Android中assets目錄下的文件的方法詳解

編輯:關於Android編程

Android資源文件大致可以分為兩種:

第一種是res目錄下存放的可編譯的資源文件:

這種資源文件系統會在R.java裡面自動生成該資源文件的ID,所以訪問這種資源文件比較簡單,通過R.XXX.ID即可;

第二種是assets目錄下存放的原生資源文件:

因為系統在編譯的時候不會編譯assets下的資源文件,所以我們不能通過R.XXX.ID的方式訪問它們。那我麼能不能通過該資源的絕對路徑去訪問它們呢?因為apk安裝之後會放在/data/app/**.apk目錄下,以apk形式存在,asset/res和被綁定在apk裡,並不會解壓到/data/data/YourApp目錄下去,所以我們無法直接獲取到assets的絕對路徑,因為它們根本就沒有。

還好Android系統為我們提供了一個AssetManager工具類。

查看官方API可知,AssetManager提供對應用程序的原始資源文件進行訪問;這個類提供了一個低級別的API,它允許你以簡單的字節流的形式打開和讀取和應用程序綁定在一起的原始資源文件。   

Android除了提供/res目錄存放資源文件外,在/assets目錄也會提供存放資源文件,在/assets目錄下面不會在R.java裡面自動生成ID,所以讀取assets目錄下面的資源文件需要提供路徑,我們可以通過AssetManager類來訪問這些文件。
    作者需要實現從 A.apk( 資源apk ,把所有的資源如:so、apk、可執行文件等放到assets目錄下面,apk沒有實現邏輯代碼)拷貝資源到指定目錄下,所以作者創建了一個實現資源拷貝邏輯的 B.apk( 一個Service,也可用Activity實現),由於拷貝路徑一般情況下是不可訪問或者創建的(每個apk安裝之後只能訪問/data/data/自己包名/下面的私有空間),作者需要這個apk能夠獲取系統權限(System權限),則必須在AndroidManifest.xml聲明shareduserid,具體如何操作下一節進行記錄。


一、AssetManager讀取文件常用的幾個API

    1.文件讀取方式
    AssetManager.open(String filename),返回的是一個InputSteam類型的字節流,這裡的filename必須是文件,而不能是文件夾,AssetManager打開資源文件的open方法是一個重載方法,可以添加一個打開方式的int參數,根據參數不同可做相應操作。具體請看官方文檔http://web.mit.edu/clio/MacData/afs/sipb/project/android/docs/reference/android/content/res/AssetManager.html
    2.資源文件是可以存在文件夾以及子目錄
    public final String[]list(String path),返回當前目錄下面的所有文件以及子目錄的名稱。可以通過遞歸遍歷整個文件目錄,實現所有資源文件的訪問。String[] Array of strings, one for each asset. These file names are relative to 'path'. You can open the file by concatenating 'path' and a name in the returned string (via File) and passing that to open().

二、相關實現代碼
資源APK(A.apk)

2016429155211907.png (332×379)

具體實現代碼片段,由於使用系統權限,生成的路徑可以自己改一下B.apk

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    try {
      ctxDealFile = this.createPackageContext("com.zlc.ipanel",
          Context.CONTEXT_IGNORE_SECURITY);
    } catch (NameNotFoundException e1) {
      // TODO Auto-generated catch block
      e1.printStackTrace();
    }
   
    btn3.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
        // TODO Auto-generated method stub
        try {
          String uiFileName = "ipanelJoin";
          deepFile(ctxDealFile, uiFileName);
        } catch (Exception e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
          textView.setText("file is wrong");
        }
      }
    });
    //
  }
  public void deepFile(Context ctxDealFile, String path) {
    try {
      String str[] = ctxDealFile.getAssets().list(path);
      if (str.length > 0) {//如果是目錄
        File file = new File("/data/" + path);
        file.mkdirs();
        for (String string : str) {
          path = path + "/" + string;
          System.out.println("zhoulc:\t" + path);
          // textView.setText(textView.getText()+"\t"+path+"\t");
          deepFile(ctxDealFile, path);
          path = path.substring(0, path.lastIndexOf('/'));
        }
      } else {//如果是文件
        InputStream is = ctxDealFile.getAssets().open(path);
        FileOutputStream fos = new FileOutputStream(new File("/data/"
            + path));
        byte[] buffer = new byte[1024];
        int count = 0;
        while (true) {
          count++;
          int len = is.read(buffer);
          if (len == -1) {
            break;
          }
          fos.write(buffer, 0, len);
        }
        is.close();
        fos.close();
      }
    } catch (IOException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved