Android应用实例之动态展示assets下图片
Android应用实例之动态展示assets下图片
实现的功能:在ImageView中动态(每隔0.1秒)展示assets下图片,所有图片播放完毕后再重新开始播放。
实现思路:
1)通过AssetManager获取assets下资源,使用BitmapFactory将图片资源输入流转换为Bitmap对象,然后将Bitmap对象设置到ImageView组件中。
2)动态展示图片(模拟间隔0.1秒)在子线程中操作,Android子线程是不能更新UI的,需要借助Handler(运行在主线程中)与子线程通过Message传递数据,完成更新UI的操作。
关键技术点:AssetManager应用、Bitmap对象回收技术、Handler应用、多线程及线程的终止等。
第1步:新建一个工程,命名为DisplayImagesDemo,Activity命名为DisplayImagesActivity。
第2步:往assets下拷贝几张测试用图片,然后修改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">
- <ImageView android:id="@+id/image" android:layout_width="fill_parent"
- android:layout_height="wrap_content" android:padding="5px"
- android:layout_weight="1" />
- <LinearLayout style="@android:style/ButtonBar"
- android:layout_width="fill_parent" android:layout_height="wrap_content"
- android:orientation="horizontal">
- <Button android:id="@+id/btnStart" android:text="开始播放"
- android:layout_width="0dip" android:layout_height="wrap_content"
- android:layout_weight="1" />
- <Button android:id="@+id/btnStop" android:text="停止播放"
- android:layout_width="0dip" android:layout_height="wrap_content"
- android:layout_weight="1" />
- </LinearLayout>
- </LinearLayout>
第3步:修改DisplayImagesActivity,代码如下:
- package com.zyg.demo.assets;
- import java.io.IOException;
- import java.io.InputStream;
- import android.app.Activity;
- import android.content.res.AssetManager;
- import android.graphics.BitmapFactory;
- import android.graphics.drawable.BitmapDrawable;
- import android.os.Bundle;
- import android.os.Handler;
- import android.os.Message;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.ImageView;
- public class DisplayImagesActivity extends Activity {
- private AssetManager assets = null;
- private String[] images = null;
- private int currentImg = 0;
- private ImageView image;
- private Button btnStart;
- private Button btnStop;
- // 定义一个负责更新图片的Handler
- private Handler handler = null;
- private Thread thread = null;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- //初始化视图
- onInitView();
- //获取assets下图片
- images = getImages();
- //displayAssets();
- }
- private void onInitView(){
- image = (ImageView) findViewById(R.id.image);
- btnStart = (Button) findViewById(R.id.btnStart);
- btnStart.setOnClickListener(listener);
- btnStop = (Button) findViewById(R.id.btnStop);
- btnStop.setOnClickListener(listener);
- handler = new Handler() {
- public void handleMessage(android.os.Message msg) {
- // 表明消息是该程序发出的
- if (msg.what == 0x110) {
- // 展示下一张图片
- dispalyNextImage();
- }
- };
- };
- }
- private String[] getImages(){
- String[] tempImages = null;
- try {
- assets = getAssets();
- // 获取/assets/目录下所有文件
- if(null!=assets){
- tempImages = assets.list("");
- }
- } catch (IOException e) {
- e.printStackTrace();
- }finally{
- return tempImages;
- }
- }
- View.OnClickListener listener = new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (v == btnStart) {
- if(thread==null){
- thread = new Thread() {
- @Override
- public void run() {
- Thread curThread = Thread.currentThread();
- while (thread!=null && thread == curThread) {
- try {
- Thread.sleep(100);
- Message msg = new Message();
- msg.what = 0x110;
- handler.sendMessage(msg);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- };
- thread.start();
- }
- } else if (v == btnStop) {
- Thread temp = thread;
- thread = null;
- temp.interrupt();
- }
- }
- };
- // 展示assets内容
- private void displayAssets() {
- int length = images.length;
- String str = null;
- for (int i = 0; i < length; i++) {
- str = images[i];
- System.out.println(i + "=" + str);
- }
- }
- // 展示下一张图片
- private void dispalyNextImage() {
- // 如果发生数组越界
- if (currentImg >= images.length) {
- currentImg = 0;
- }
- //备注1
- // 找到下一个图片文件
- while (!images[currentImg].endsWith(".png")
- && !images[currentImg].endsWith(".jpg")
- && !images[currentImg].endsWith(".gif")) {
- currentImg++;
- // 如果已发生数组越界
- if (currentImg >= images.length) {
- currentImg = 0;
- }
- }
- InputStream assetFile = null;
- try {
- // 打开指定资源对应的输入流
- assetFile = assets.open(images[currentImg++]);
- } catch (IOException e) {
- e.printStackTrace();
- }
- BitmapDrawable bitmapDrawable = (BitmapDrawable) image.getDrawable();
- //备注2
- // 如果图片还未回收,先强制回收该图片
- if (bitmapDrawable != null && !bitmapDrawable.getBitmap().isRecycled()){
- bitmapDrawable.getBitmap().recycle();
- }
- // 改变ImageView显示的图片
- image.setImageBitmap(BitmapFactory.decodeStream(assetFile));
- }
- }
备注1:
之所以如此处理是因为assets下除了图片资源还有images、sounds和webkit,打开onCreate下的displayAssets()方法,可以看到输出日志。
备注2:
如果系统频繁地去解析、创建Bitmap对象,可能由于前面创建的Bitmap所占用的内存还没有回收(手机系统本身的内容就比较小),而导致程序运行时引发OutOfMemory错误。
事实上,如果将备注2回收Bitmap对象的语句注释掉,图片动态展示若干张(视具体情况而定,我在模拟器里运行只展示了4张就挂掉了),错误日志为:
INFO/ActivityManager(73): Low Memory: No more background processes.
第4步:运行程序,效果如下:
评论暂时关闭