转载请注明出处,原文网址:http://blog.youkuaiyun.com/m_changgong/article/details/6807817 作者:张燕广
实现的功能:在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步:运行程序,效果如下: