Android apk攜帶資源之raw & assets

 /res/raw & /assets 攜帶資源

   在android開發中,總有一些資源是想要隨着安裝包apk攜帶的,這些資源如數據庫文件,文本,mp3等等。最早的做法是,在prebulid過程 中,修改mk文件,將指定文件提前拷貝到系統某一文件夾目錄下。這樣的做法,既不科學也不美觀還不安全,處於對代碼的潔癖,我終於在不太忙的時候把這些資 源文件帶在自己的apk下。

   之前說過沒,由於提升速度,從文本解析調整爲數據庫查詢。在攜帶文件時,這兩種文件本沒有不同,只是這裏要講一點inputstream的時候,二進制 文件的db文件,和純文本文件txt的方式可以不同,原因好像是,純文本是按照unicode編碼的,是16位16位的傳的,二進制文件是8位傳的。又想 到之前ftp傳輸的時候,也是寫的二進制傳輸。

  言歸正傳,無論是raw文件夾還是assets文件夾,都是在生成apk的時候不編譯而直接攜帶在apk的壓縮包中的,這可以打開apk檢驗。這想必也是raw的得名。

  提取的方法都是從inputstream轉,轉成什麼形式的,要看對inputstream的操作,下篇也許會講。具體的過程是:

  Java代碼

  private void getRaw(){

  File target = new File("/data/data/com.android.");

  // InputStream in = this.getResources().openRawResource(R.raw.weather_db);

  // try {

  // } catch (IOException e1) {

  // // TODO Auto-generated catch block

  // e1.printStackTrace();

  // }

  InputStream in = null;

  OutputStream out = null;

  BufferedInputStream bin = null;

  BufferedOutputStream bout = null;

  try{

  //////////////////////////////////////////////////////////////////////

  int xx = 1;//R.raw.parse_weather_db_aa;

  xx+=1;

  try{

  in = getResources().openRawResource(xx);

  }catch(Exception e){

  e.printStackTrace();

  }

  out = new FileOutputStream(target);

  bin = new BufferedInputStream(in);

  bout = new BufferedOutputStream(out);

  byte[] b = new byte[1024];

  int len = bin.read(b);

  while (len != -1){

  bout.write(b, 0, len);

  len = bin.read(b);

  }

  // exec("chmod 777 "+target.getAbsolutePath());

  }

  catch (FileNotFoundException e){

  e.printStackTrace();

  }

  catch (IOException e)

  {

  e.printStackTrace();

  }

  finally

  {

  try{

  if (bin != null){

  bin.close();

  }

  if (bout != null){

  bout.close();

  }

  }

  catch (IOException e){

  e.printStackTrace();

  }

  }

  }

  private void getAsset(){

  // if(WeatherWidget.loadRunning(this, "FirstSetup")){

  if(true){

  WeatherWidget.saveRunning(this, false, "FirstSetup");

  File databs = new File("/data/data/com.android.");

  if(!databs.exists()){

  databs.mkdir();

  }

  InputStream in = null;

  OutputStream out = null;

  BufferedInputStream bin = null;

  BufferedOutputStream bout = null;

  AssetManager am = getAssets();

  String asName = "parse_weather_db_aa";

  while(true){

  try{

  in = am.open(asName);

  out = new FileOutputStream(databs.getPath()+"/weather_db");

  asName = nextAsset(asName);

  bin = new BufferedInputStream(in);

  bout = new BufferedOutputStream(out);

  byte[] b = new byte[8192];

  int len = bin.read();

  while (len != -1){

  bout.write(b, 0, len);

  len = bin.read(b);

  }

  continue;

  }

  catch (FileNotFoundException e){

  e.printStackTrace();

  try{

  if (bin != null){

  bin.close();

  }

  if (bout != null){

  bout.close();

  }

  break;

  }

  catch (IOException ee){

  ee.printStackTrace();

  }

  break;

  }

  catch (IOException e){

  e.printStackTrace();

  try{

  if (bin != null){

  bin.close();

  }

  if (bout != null){

  bout.close();

  }

  break;

  }

  catch (IOException eee){

  eee.printStackTrace();

  }

  break;

  }

  }

  }

  }

  private void getRaw(){

  File target = new File("/data/data/com.android.");

  // InputStream in = this.getResources().openRawResource(R.raw.weather_db);

  // try {

  // } catch (IOException e1) {

  // // TODO Auto-generated catch block

  // e1.printStackTrace();

  // }

  InputStream in = null;

  OutputStream out = null;

  BufferedInputStream bin = null;

  BufferedOutputStream bout = null;

  try{

  //////////////////////////////////////////////////////////////////////

  int xx = 1;//R.raw.parse_weather_db_aa;

  xx+=1;

  try{

  in = getResources().openRawResource(xx);

  }catch(Exception e){

  e.printStackTrace();

  }

  out = new FileOutputStream(target);

  bin = new BufferedInputStream(in);

  bout = new BufferedOutputStream(out);

  byte[] b = new byte[1024];

  int len = bin.read(b);

  while (len != -1){

  bout.write(b, 0, len);

  len = bin.read(b);

  }

  // exec("chmod 777 "+target.getAbsolutePath());

  }

  catch (FileNotFoundException e){

  e.printStackTrace();

  }

  catch (IOException e)

  {

  e.printStackTrace();

  }

  finally

  {

  try{

  if (bin != null){

  bin.close();

  }

  if (bout != null){

  bout.close();

  }

  }

  catch (IOException e){

  e.printStackTrace();

  }

  }

  }

  private void getAsset(){

  // if(WeatherWidget.loadRunning(this, "FirstSetup")){

  if(true){

  WeatherWidget.saveRunning(this, false, "FirstSetup");

  File databs = new File("/data/data/com.android.");

  if(!databs.exists()){

  databs.mkdir();

  }

  InputStream in = null;

  OutputStream out = null;

  BufferedInputStream bin = null;

  BufferedOutputStream bout = null;

  AssetManager am = getAssets();

  String asName = "parse_weather_db_aa";

  while(true){

  try{

  in = am.open(asName);

  out = new FileOutputStream(databs.getPath()+"/weather_db");

  asName = nextAsset(asName);

  bin = new BufferedInputStream(in);

  bout = new BufferedOutputStream(out);

  byte[] b = new byte[8192];

  int len = bin.read();

  while (len != -1){

  bout.write(b, 0, len);

  len = bin.read(b);

  }

  continue;

  }

  catch (FileNotFoundException e){

  e.printStackTrace();

  try{

  if (bin != null){

  bin.close();

  }

  if (bout != null){

  bout.close();

  }

  break;

  }

  catch (IOException ee){

  ee.printStackTrace();

  }

  break;

  }

  catch (IOException e){

  e.printStackTrace();

  try{

  if (bin != null){

  bin.close();

  }

  if (bout != null){

  bout.close();

  }

  break;

  }

  catch (IOException eee){

  eee.printStackTrace();

  }

  break;

  }

  }

  }

  }

  代碼比較亂,有些東西講一遍不如需要的時候直接回來看一眼代碼,去僞存真吧。

  最後,講raw & assets資源比較重要的一點,就是文件的大小限制,單個文件的大小不可以大於1M,有人說這是android的bug,呵呵,解決的方法是:

  將文件split爲小於1M的文件,在讀取的時候outputstream不要close,而是合併寫這些文件,最後就得到原始文件。分割可以用ubuntu命令,

  split -b[byte] 512k [source] [prefix]

  也可以用windows下文件分割器,或者直接在android中製作,代碼inputstream的時候限制大小,分割存儲。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章