Android(java)学习笔记77: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,它允许你以简单的字节流的形式打开和读取和应用程序绑定在一起的原始资源文件。
1. assets文件夹资源的访问
assets文件夹里面的文件都是保持原始的文件格式,需要用AssetManager以字节流的形式读取文件。
1. 先在Activity里面调用getAssets() 来获取AssetManager引用。
2. 再用AssetManager的open(String fileName, int accessMode) 方法则指定读取的文件以及访问模式就能得到输入流InputStream。
3. 然后就是用已经open file 的inputStream读取文件,读取完成后记得inputStream.close() 。
4. 调用AssetManager.close() 关闭AssetManager。
需要注意的是,来自Resources和Assets 中的文件只可以读取而不能进行写的操作
以下为从Raw文件中读取:
public String getFromRaw(){ try { InputStreamReader inputReader = new InputStreamReader( getResources().openRawResource(R.raw.test1)); BufferedReader bufReader = new BufferedReader(inputReader); String line=""; String Result=""; while((line = bufReader.readLine()) != null) Result += line; return Result; } catch (Exception e) { e.printStackTrace(); } }
以下为直接从assets读取:
public String getFromAssets(String fileName){ try { InputStreamReader inputReader = new InputStreamReader( getResources().getAssets().open(fileName) ); BufferedReader bufReader = new BufferedReader(inputReader); String line=""; String Result=""; while((line = bufReader.readLine()) != null) Result += line; return Result; } catch (Exception e) { e.printStackTrace(); } }
2. 接下来,我们新建一个工程文件,命名为AssetsProject:
(1)工程一览图:
(2)接下来是主布局文件activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <Button android:id="@+id/btn1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="获取assets目录下的文章" /> <Button android:id="@+id/btn2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="获取assets目录下的图片" /> </LinearLayout>
主布局效果图:
辅助布局文件get_img.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/btn5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="获取assets目录下的img文件" /> <Button android:id="@+id/btn6" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="返回" /> </LinearLayout> <ImageView android:id="@+id/imageView1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
效果图:
辅助布局文件get_text.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal" > <Button android:id="@+id/btn3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="获取assets目录下的txt文件" /> <Button android:id="@+id/btn4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="返回" /> </LinearLayout> <TextView android:id="@+id/textview1" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
效果图:
(3)MainActivity.java:
package com.himi.assetsproject; import java.io.IOException; import java.io.InputStream; import android.app.Activity; import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Typeface; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; import android.widget.TextView; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button txt_btn = (Button) findViewById(R.id.btn1); Button img_btn = (Button) findViewById(R.id.btn2); txt_btn.setOnClickListener(new Button01Listener()); img_btn.setOnClickListener(new Button02Listener()); } private class Button01Listener implements OnClickListener { public void onClick(View v) { setContentView(R.layout.get_text); Button get_txt_btn = (Button) findViewById(R.id.btn3); Button txt_back_btn = (Button) findViewById(R.id.btn4); get_txt_btn.setOnClickListener(new Button03Listener()); txt_back_btn.setOnClickListener(new Button04Listener()); } } private class Button02Listener implements OnClickListener { public void onClick(View v) { setContentView(R.layout.get_img); Button get_img_btn = (Button) findViewById(R.id.btn5); Button img_back_btn = (Button) findViewById(R.id.btn6); get_img_btn.setOnClickListener(new Button05Listener()); img_back_btn.setOnClickListener(new Button06Listener()); } } private class Button03Listener implements OnClickListener { public void onClick(View v) { TextView tv = (TextView) findViewById(R.id.textview1); AssetManager am = getAssets(); Typeface tf = Typeface.createFromAsset(am, "fonts/DroidSansFallback.ttf"); tv.setTypeface(tf); tv.setTextSize(15); tv.setText(readAssetsFileString()); } } private class Button04Listener implements OnClickListener { public void onClick(View v) { setContentView(R.layout.activity_main); // 一旦返回主页,之前设置Button监听就无效,所有要重新设置,但是这样代码重复出现,说明这样设计思路不佳 Button txt_btn = (Button) findViewById(R.id.btn1); Button img_btn = (Button) findViewById(R.id.btn2); txt_btn.setOnClickListener(new Button01Listener()); img_btn.setOnClickListener(new Button02Listener()); } } private class Button05Listener implements OnClickListener { public void onClick(View v) { ImageView img = (ImageView) findViewById(R.id.imageView1); InputStream bitmap = null; try { bitmap = getAssets().open("imgs/4.jpg"); Bitmap bit = BitmapFactory.decodeStream(bitmap); img.setImageBitmap(bit); } catch (Exception e) { e.printStackTrace(); } } } private class Button06Listener implements OnClickListener { public void onClick(View v) { setContentView(R.layout.activity_main); // 一旦返回主页,之前设置Button监听就无效,所有要重新设置,但是这样代码重复出现,说明这样设计思路不佳 Button txt_btn = (Button) findViewById(R.id.btn1); Button img_btn = (Button) findViewById(R.id.btn2); txt_btn.setOnClickListener(new Button01Listener()); img_btn.setOnClickListener(new Button02Listener()); } } public String readAssetsFileString() { String str = null; try { InputStream is = getAssets().open("txts/01.txt"); int size = is.available(); byte[] buffer = new byte[size]; is.read(buffer); is.close(); // public String(byte[] data, String // charsetName):转化对应的byte[]数据为对应编码的"GB2312"字符串 // UTF-8:是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24为(三个字节)来编码。是国际编码 // GB2312和GBK: 主要用于编解码常用汉字,GBK是一个改进版,所以能用GBK的时候一般不用GB2312 str = new String(buffer, "GBK"); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return str; } }
(4)运行效果图:
图1:
图2: