讀寫Android中assets目錄下的檔案的方法詳解_Android

來源:互聯網
上載者:User

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)

具體實現程式碼片段,由於使用系統許可權,產生的路徑可以自己改一下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();    }  }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.