之前看到过一些帖子播放gif图片的,大概看过两种版本,一种是使用把gif解码,分为一帧一帧的播放,另一种就是直接播放gif图片。可以使用Movie类来播放,一种是使用框架,一个是android-gifview,另一个是android-gif-drawable,前者加载小的gif图片没问题,但是gif图片大了就OOM,后者据说是不支持Android5.0,使用到了jni,对内存做了一定优化,倒是不会出现OOM的问题,具体可参考
Android开源项目:GifView——Android显示GIF动画。但如果是Eclipse的话配置环境需要SDK最低是4.3的版本,因为本人的SDK版本是4.2的,所以决定使用Movie来播放。
Movie有三个方法去加载gif图片,分别是
Movie.decodestream(InputStream is);
Movie.decodeFile(String pathName);
Movie.decodeByteArray(byte[] data, int offset,int length);
要从网上显示gif图片,肯定需要gif的url,所以我在构造方法里添加了url的参数,之后先从本地读取gif图片,如果本地不存在,就从网络上先下载到本地,随后从本地中读取,当然你可以直接从网络上得到一个InputStream流,但是为了省流量,做了一个一级缓存,下次访问的时候先从本地读取,没有的话再从网络上下下来。具体代码如下:

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Movie;
import android.graphics.Paint;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import cn.tedu.news.R;public class GifView extends View {private static final String TAG = GifView.class.getSimpleName();private Movie mMovie;private long mPlayMovieTime;private String DOWNLOAD_ADDR = "";private Context context;private int mViewWidth;private int mViewHeight;private boolean isPlaying;public GifView(Context context) {super(context);this.context = context;readGifFormNet();}public GifView(Context context, AttributeSet attrs) {super(context, attrs);this.context = context;}/*** 设置gif图片的url,开始播放gif* @param url*/public void setUrl(String url) {DOWNLOAD_ADDR = url;//先从本地读取,如果本地没有,在从网络上获取mMovie = readGifFormLoacl();if (mMovie == null) {//先下载只本地gifDownload();readGifFormNet();}}/*** 从资源文件中读取gif图片*/public void readGifFormNative() {InputStream in;in = context.getResources().openRawResource(R.drawable.dfsd8);mMovie = Movie.decodeStream(in);}/*** 加载本地图片*/public Movie readGifFormLoacl() {try {File dir = context.getCacheDir().getAbsoluteFile();String fileName = DOWNLOAD_ADDR.substring(DOWNLOAD_ADDR.lastIndexOf("/"), DOWNLOAD_ADDR.length());if (!dir.exists()) {dir.mkdirs();}File file = new File(dir, fileName);return mMovie = Movie.decodeFile(file.getAbsolutePath());} catch (Exception e) {e.printStackTrace();}return null;}/*** 下载网络图片*/private void readGifFormNet() {new AsyncTask<Void, Void, Void>() {@Overrideprotected Void doInBackground(Void... params) {httpTest();return null;}@Overrideprotected void onPostExecute(Void result) {mHandler.sendEmptyMessage(0);}}.execute();}public void setPlaying(boolean flag) {isPlaying = flag;}Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case 0:invalidate();break;default:break;}super.handleMessage(msg);}};/*** 下载网络图片到本地*/public void gifDownload() {new Thread() {public void run() {InputStream in = null;FileOutputStream fos = null;try {URL url = new URL(DOWNLOAD_ADDR);HttpURLConnection connection = (HttpURLConnection) url.openConnection();int size = connection.getContentLength();Log.e(TAG, "size = " + size);in = connection.getInputStream();File dir = context.getCacheDir().getAbsoluteFile();String fileName = DOWNLOAD_ADDR.substring(DOWNLOAD_ADDR.lastIndexOf("/"),DOWNLOAD_ADDR.length());if (!dir.exists()) {dir.mkdirs();}File file = new File(dir, fileName);Log.d("info", "file->" + file.getAbsolutePath());fos = new FileOutputStream(file);int len = -1;byte[] buffer = new byte[1024 * 8];while ((len = in.read(buffer)) != -1) {fos.write(buffer, 0, len);fos.flush();}} catch (MalformedURLException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {try {if (fos != null) {fos.close();}if (in != null) {in.close();}} catch (IOException e) {e.printStackTrace();}}};}.start();}/*** 下载网络图片*/private void httpTest() {try {URL url = new URL(DOWNLOAD_ADDR);HttpURLConnection connection = (HttpURLConnection) url.openConnection();// connection.setRequestMethod("GET");int size = connection.getContentLength();Log.e(TAG, "size = " + size);InputStream in = connection.getInputStream();byte[] array = streamToBytes(in);mMovie = Movie.decodeByteArray(array, 0, array.length);// 得到图片宽高if (mMovie != null) {mViewWidth = mMovie.width();mViewHeight = mMovie.height();}in.close();} catch (IOException e) {e.printStackTrace();}}private static byte[] streamToBytes(InputStream is) {ByteArrayOutputStream os = new ByteArrayOutputStream(1024);byte[] buffer = new byte[1024];int len;try {while ((len = is.read(buffer)) >= 0) {os.write(buffer, 0, len);}} catch (java.io.IOException e) {}return os.toByteArray();}@Overrideprotected void onDraw(Canvas canvas) {Paint p = new Paint();p.setAntiAlias(true);setLayerType(LAYER_TYPE_SOFTWARE, p);//获取屏幕宽高,将gif图片宽或高铺满屏幕WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);DisplayMetrics metrics = new DisplayMetrics();wm.getDefaultDisplay().getMetrics(metrics);if (mMovie != null) {mViewWidth = mMovie.width();mViewHeight = mMovie.height();float x = 0;float y = 0;//float width = getWidth();//float height = getHeight();float width = metrics.widthPixels;float height = metrics.heightPixels;float saclex = (float) width / (float) mViewWidth;float sacley = (float) height / (float) mViewHeight;float sameRate = saclex > sacley ? sacley : saclex;canvas.scale(sameRate, sameRate);x = ((width - mViewWidth * sameRate) / 2) / (metrics.density);y = ((height - mViewHeight * sameRate) / 2) / (sameRate);if (isPlaying) {long now = android.os.SystemClock.uptimeMillis();if (mPlayMovieTime == 0) { // first timemPlayMovieTime = now;}int dur = mMovie.duration();if (dur == 0) {dur = 1000;}int relTime = (int) ((now - mPlayMovieTime) % dur);mMovie.setTime(relTime);mMovie.draw(canvas, x, y);// if ((now - mPlayMovieTime) > dur) {// mPlayMovieTime = 0;// isPlaying = false;// }} else {mMovie.setTime(0);mMovie.draw(canvas, x, y);}invalidate();}}
}

本博客部分代码摘自:android 播放网络或本地gif格式的动态图片 ,本人做了一下优化,如有不足或不正确的地方,望指明改正!

Android自定义Movie播放网络gif图片相关推荐

  1. android 自定义MP4播放器

    昨天,在网上找了好多资料,终于做了一个自定义的播发器. 视频播放方式 在Android中播放视频的方式有两种: 1.使用MediaPlayer结合SurfaceView进行播放.其中通过Surface ...

  2. Android 自定义音乐播放器实现

    Android自定义音乐播放器 一:首先介绍用了哪些Android的知识点: 1 MediaPlayer工具来播放音乐 2 Handle.因为存在定时任务(歌词切换,动画,歌词进度条变换等)需要由Ha ...

  3. Android之MediaPlayer播放网络视频的实现方法

    前段时间忙于工作,现在有时间来分享一下: 这篇文章主要介绍了Android的MediaPlayer播放网络视频的实现方法,是一个非常实用的功能,需要的朋友可以参考下 前面讲解了MediaPlayer播 ...

  4. Android自定义View(七)_Canvas之图片文字

    在上一篇文章Canvas之画布操作中我们了解了画布的一些基本操作方法,本次了解一些绘制图片文字相关的内容.如果你对前几篇文章讲述的内容熟练掌握的话,那么恭喜你,本篇结束之后,大部分的自定义View已经 ...

  5. Android 使用MediaPlayer播放网络音频

    一.前言 MediaPlayer是Android自带的一个多媒体播放类,可以播放音视频流或者本地音视频文件.MediaPlayer方法的调用需要在一定的状态下,下图是一个MediaPlayer对象被支 ...

  6. Android 自定义 ListView 显示网络上 JSON 格式歌曲列表

    本文内容 环境 项目结构 演示自定义 ListView 显示网络上 JSON 歌曲列表 参考资料 本文最开始看的是一个国人翻译的文章,没有源代码可下载,根据文中提供的代码片段,自己新建的项目(比较可恶 ...

  7. Android VideoView无法播放网络视频

    今天学习Android播放视频和音频,其中在练习播放视频的时候无法播放网络视频,网络视频是别人发布在网上的,但是把视频放在本地是可以的,最后推测是没有开放网络的访问权限的问题,果然开放了之后就能正常访 ...

  8. android视频自动旋转,Android 使用PLDroidPlayer播放网络视频 根据视频角度自动旋转...

    最近因为项目需求 ,需要播放网络视频 ,于是乎 研究了一番 ,说说我遇到的那些坑 现在市面上有几个比较主流好用的第三方框架 当然还有很多别的视频播放框架 因为我只找到这几个= =! 因为项目比较急,所 ...

  9. Android 使用PLDroidPlayer播放网络视频 依据视频角度自己主动旋转

    近期由于项目需求 .须要播放网络视频 .于是乎 研究了一番 ,说说我遇到的那些坑 如今市面上有几个比較主流好用的第三方框架 Vitamio ( 体积比較大,有商业化风险 github:https:// ...

最新文章

  1. 解析C语言中的sizeof
  2. kvm虚拟化框架结构层次梳理及图形化的使用
  3. QT的QHash类的使用
  4. php备份和恢复源码,PHP数据库备份还原类
  5. F. Strange Array(Codeforces Round #727 (Div. 2))(主席树)
  6. BZOJ1652 [Usaco2006 Feb]Treats for the Cows
  7. ResNet网络详解与keras实现
  8. bzoj3231 [SDOI2008]递归数列 矩乘
  9. 服务器小白-MYSQL基础安装配置
  10. 3D MAX导出插件编写
  11. 第五章节 类的继承(继承的概述)
  12. 01.使用File类读写文件
  13. 69-Python的匿名函数1
  14. 《批判性思维》感1.1-[信念执念断言]
  15. python制作动态二维码
  16. 视频流中的DTS/PTS到底是什么?
  17. VR 终极选购指南:入门、进阶与高端
  18. 搜狗输入法2017老版本 v8.8.0.1814电脑版
  19. 教你如何写好商业计划书 赢得风险投资
  20. [计算机通信网络]以太网的帧格式详解

热门文章

  1. java parseint 负号_java.lang.Integer#parseInt() 源码分析
  2. bho是什么文件夹_BHO的完整形式是什么?
  3. 10几个国内AI大模型,让你的工作学习效率翻倍!
  4. 我们为什么应该坚持写博客(起点 :?)
  5. MAC、HMAC、CBC-MAC、OMAC的介绍
  6. 从Scanpy的Anndata对象提取信息并转成Seurat对象(适用于空间组且涉及h5文件读写)
  7. html实现在线搜歌,利用Ajax技术实现在线歌词搜索功能
  8. 无法播放 请确保您计算机的,Win10专业版系统groove无法播放音乐提示0x8007007e怎么办 - 系统之家...
  9. Win10系统自带Edge可上网,其他程序不能上网的解决方法(亲测有效)
  10. 使用Java开发绿色的桌面程序