HardBirch

【Android应用实例之一】自动播放Assets下图片

时间:11-09-24 栏目:iOS移动应用开发技术 作者:张飞不张,文采横飞 评论:2 点击: 2,292 次

实现的功能:在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步:运行程序,效果如下:



声明: 本文由( 张飞不张,文采横飞 )原创编译,转载请保留链接: 【Android应用实例之一】自动播放Assets下图片

【Android应用实例之一】自动播放Assets下图片:目前有2 条留言

  1. 板凳
    peterli_xue:

    不错呀

    2012-07-10 16:04 [回复]
  2. 沙发
    M_ChangGong:

    谢谢,忙了好一阵一直没怎么写博客了,最近稍闲可以把产品中用到的技术总结一下[reply]peterli_xue[/reply]

    2012-07-11 10:01 [回复]

发表评论


QQ群互动

Linux系统与内核学习群:194051772

WP建站技术学习交流群:194062106

魔豆之路QR

魔豆的Linux内核之路

魔豆的Linux内核之路

优秀工程师当看优秀书籍

优秀程序员,要看优秀书!

赞助商广告

友荐云推荐