歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android應用實例之動態展示assets下圖片

Android應用實例之動態展示assets下圖片

日期:2017/3/1 11:18:11   编辑:Linux編程

實現的功能:在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文件,代碼如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical" android:layout_width="fill_parent"
  4. android:layout_height="fill_parent">
  5. <ImageView android:id="@+id/image" android:layout_width="fill_parent"
  6. android:layout_height="wrap_content" android:padding="5px"
  7. android:layout_weight="1" />
  8. <LinearLayout style="@android:style/ButtonBar"
  9. android:layout_width="fill_parent" android:layout_height="wrap_content"
  10. android:orientation="horizontal">
  11. <Button android:id="@+id/btnStart" android:text="開始播放"
  12. android:layout_width="0dip" android:layout_height="wrap_content"
  13. android:layout_weight="1" />
  14. <Button android:id="@+id/btnStop" android:text="停止播放"
  15. android:layout_width="0dip" android:layout_height="wrap_content"
  16. android:layout_weight="1" />
  17. </LinearLayout>
  18. </LinearLayout>

第3步:修改DisplayImagesActivity,代碼如下

  1. package com.zyg.demo.assets;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import android.app.Activity;
  5. import android.content.res.AssetManager;
  6. import android.graphics.BitmapFactory;
  7. import android.graphics.drawable.BitmapDrawable;
  8. import android.os.Bundle;
  9. import android.os.Handler;
  10. import android.os.Message;
  11. import android.view.View;
  12. import android.view.View.OnClickListener;
  13. import android.widget.Button;
  14. import android.widget.ImageView;
  15. public class DisplayImagesActivity extends Activity {
  16. private AssetManager assets = null;
  17. private String[] images = null;
  18. private int currentImg = 0;
  19. private ImageView image;
  20. private Button btnStart;
  21. private Button btnStop;
  22. // 定義一個負責更新圖片的Handler
  23. private Handler handler = null;
  24. private Thread thread = null;
  25. @Override
  26. public void onCreate(Bundle savedInstanceState) {
  27. super.onCreate(savedInstanceState);
  28. setContentView(R.layout.main);
  29. //初始化視圖
  30. onInitView();
  31. //獲取assets下圖片
  32. images = getImages();
  33. //displayAssets();
  34. }
  35. private void onInitView(){
  36. image = (ImageView) findViewById(R.id.image);
  37. btnStart = (Button) findViewById(R.id.btnStart);
  38. btnStart.setOnClickListener(listener);
  39. btnStop = (Button) findViewById(R.id.btnStop);
  40. btnStop.setOnClickListener(listener);
  41. handler = new Handler() {
  42. public void handleMessage(android.os.Message msg) {
  43. // 表明消息是該程序發出的
  44. if (msg.what == 0x110) {
  45. // 展示下一張圖片
  46. dispalyNextImage();
  47. }
  48. };
  49. };
  50. }
  51. private String[] getImages(){
  52. String[] tempImages = null;
  53. try {
  54. assets = getAssets();
  55. // 獲取/assets/目錄下所有文件
  56. if(null!=assets){
  57. tempImages = assets.list("");
  58. }
  59. } catch (IOException e) {
  60. e.printStackTrace();
  61. }finally{
  62. return tempImages;
  63. }
  64. }
  65. View.OnClickListener listener = new OnClickListener() {
  66. @Override
  67. public void onClick(View v) {
  68. if (v == btnStart) {
  69. if(thread==null){
  70. thread = new Thread() {
  71. @Override
  72. public void run() {
  73. Thread curThread = Thread.currentThread();
  74. while (thread!=null && thread == curThread) {
  75. try {
  76. Thread.sleep(100);
  77. Message msg = new Message();
  78. msg.what = 0x110;
  79. handler.sendMessage(msg);
  80. } catch (InterruptedException e) {
  81. e.printStackTrace();
  82. }
  83. }
  84. }
  85. };
  86. thread.start();
  87. }
  88. } else if (v == btnStop) {
  89. Thread temp = thread;
  90. thread = null;
  91. temp.interrupt();
  92. }
  93. }
  94. };
  95. // 展示assets內容
  96. private void displayAssets() {
  97. int length = images.length;
  98. String str = null;
  99. for (int i = 0; i < length; i++) {
  100. str = images[i];
  101. System.out.println(i + "=" + str);
  102. }
  103. }
  104. // 展示下一張圖片
  105. private void dispalyNextImage() {
  106. // 如果發生數組越界
  107. if (currentImg >= images.length) {
  108. currentImg = 0;
  109. }
  110. //備注1
  111. // 找到下一個圖片文件
  112. while (!images[currentImg].endsWith(".png")
  113. && !images[currentImg].endsWith(".jpg")
  114. && !images[currentImg].endsWith(".gif")) {
  115. currentImg++;
  116. // 如果已發生數組越界
  117. if (currentImg >= images.length) {
  118. currentImg = 0;
  119. }
  120. }
  121. InputStream assetFile = null;
  122. try {
  123. // 打開指定資源對應的輸入流
  124. assetFile = assets.open(images[currentImg++]);
  125. } catch (IOException e) {
  126. e.printStackTrace();
  127. }
  128. BitmapDrawable bitmapDrawable = (BitmapDrawable) image.getDrawable();
  129. //備注2
  130. // 如果圖片還未回收,先強制回收該圖片
  131. if (bitmapDrawable != null && !bitmapDrawable.getBitmap().isRecycled()){
  132. bitmapDrawable.getBitmap().recycle();
  133. }
  134. // 改變ImageView顯示的圖片
  135. image.setImageBitmap(BitmapFactory.decodeStream(assetFile));
  136. }
  137. }

備注1:

之所以如此處理是因為assets下除了圖片資源還有images、sounds和webkit,打開onCreate下的displayAssets()方法,可以看到輸出日志。

備注2:

如果系統頻繁地去解析、創建Bitmap對象,可能由於前面創建的Bitmap所占用的內存還沒有回收(手機系統本身的內容就比較小),而導致程序運行時引發OutOfMemory錯誤。

事實上,如果將備注2回收Bitmap對象的語句注釋掉,圖片動態展示若干張(視具體情況而定,我在模擬器裡運行只展示了4張就掛掉了),錯誤日志為:

INFO/ActivityManager(73): Low Memory: No more background processes.

第4步:運行程序,效果如下:

Copyright © Linux教程網 All Rights Reserved