1

我是来自 web 开发的 Android 新手,所以如果这个问题有一个明显的答案,我深表歉意;谷歌无法为我提供一个。我有一个循环动画,我想把它变成一个可以放在应用商店的 Android 动态壁纸。

我在这里找到了有关创建基本动态壁纸的有用教程:http ://www.techrepublic.com/blog/android-app-builder/a-bare-bones-live-wallpaper-template-for-android/ ://www.techrepublic.com/blog/android-app-builder/a-bare-bones-live-wallpaper-template-for-android/ 。在构建了我自己版本的该模板之后,我想我可以用创建媒体播放器并在屏幕上播放 mpg 的功能替换“绘图”功能,但我没有找到一个教程来做到这一点。

然后我遇到了这个问题:Android video as a live wallpaper,这表明播放 mpg 可能比我最初想象的要困难得多,而且问题多多。这似乎提供了一个解决方案:How to play video as live wallpaper android? 但是,它需要使用一个外部 API,该 API 明确表示它将大大增加复杂性,这意味着它只能由有经验的开发人员使用。

所以我要回到这里的基础并问:新手开发人员如何从动画中创建动态壁纸?将视频格式与本机媒体播放器一起使用?将每一帧以png格式绘制到屏幕上?使用免费提供的 api?

编辑1:

自从我发布以来,我做了一些研究并开发了两个不同的应用程序,但都不能令人满意。

在第一个中,我解码每一帧(存储为 PNG 文件)并将它们存储在位图数组中。然后我每 50 毫秒循环一次,并将每一帧从数组中直接绘制到画布上。这种方法工作起来比较顺利,但是内存使用非常糟糕。由于每个 PNG 都经过解码然后存储为位图,因此我用 1-3 秒的视频(取决于设备)耗尽了内存。

在第二个中,我将每一帧读入一个字节数组作为 PNG 文件。这使我可以将它们存储在 RAM 中以便快速访问,但是通过将它们保留为压缩内存使用可以最小化。在循环期间,我从字节数组中动态解压缩每个字节,然后将其绘制到画布上。这种方法使用的内存不到第一种方法的一半。然而,动画是跳跃的,大概来自所有需要的 GC。

openGL 或通过媒体播放器播放 mpeg 会提供比这些更好的性能吗?或者有没有办法优化上述方法之一?

编辑2:

我对上面的方法2进行了进一步细化。我之前在绘图函数结束时设置了 40 毫秒的延迟,以便它再次调用自己。然而,由于解码和绘制动作花费了很多时间,而且它是不可预测的,它导致帧之间的延迟超过 40 毫秒。我已经将 40 毫秒的 postDelayed 调用移到了解码和绘制处理之前的过程开头。这导致播放更加流畅,尽管在可见的情况下以大约 50% 的处理器使用为代价。但是,到目前为止,这仅在高端 ICS 设备上进行了测试;我计划在接下来的一两天内在 Droid X 上试一试,看看会发生什么。

我仍然不相信这是最好的方法,并希望能提供意见。我有一种唠叨的感觉,我做错了。

编辑 3: 在高端设备上播放相对流畅,但不是我的 Droid X。我认为这可能是由于在以不同于其原始分辨率的分辨率显示图像时需要进行的所有推断。所以我构建了代码,以手机的精确分辨率将每一帧保存为 jpg。这会导致某些设备上出现 oom 错误,所以我切换到 1/2 分辨率。尽管内存使用率仍然很高,但这很有效。

我试图通过对动画的顶部 2/3 使用单个背景帧(大部分是静态的)来进一步解决问题,然后只为底部三分之一保存帧。但是,现在播放速度要慢得多,大约 10 FPS,即使在高端设备上也是如此。这大概是因为每一帧都需要整体重绘,现在画布上有两个位图。虽然这种方法的内存使用非常好。

编辑 4: 有人建议我启用硬件加速,我知道在这样的动态壁纸中发布到 surfaceView 时无法做到这一点。当我四处搜索时,我意识到图形引擎可能是一个很好的方向,并尝试了 AndEngine。我将帧转换为单个巨型 jpg(15,000 x 3080 像素)并使用以下代码将它们加载到精灵中:

waterTexture = new BitmapTextureAtlas(this.getTextureManager(), 15000, 3040, TextureOptions.BILINEAR);
waterRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(waterTexture, this.getAssets(), "wateranimation.jpg", 0, 0, 25, 16);
waterTexture.load();

我曾希望 AndEngine 能够以某种方式智能地加载它,但是我的壁纸要求不到 200 MB 的 RAM,但我却遇到了内存不足的错误。

这个项目现在已经花费了 50 多个小时,我觉得应该是一行代码:“backgroundHolder = movie.mpg”。我在 SO 和其他网站上都问了几个问题,关于如何用相对较少的回复来做到这一点。这让我质疑我正在尝试做的事情是否有可能,尽管十年前我在一台处理能力和内存都只有我的 Droid X 一小部分的 PC 上观看流畅的 800x600 电影。我知道硬件不是问题。是我糟糕的编码,还是 Java 的限制?这可能吗?只是发现这是不可能的,至少可以让我停止在这上面浪费时间。

我将尝试为这个问题添加赏金。

我已经开始关于这个项目的相关问题:

低帧率将位图写入画布

将图像存储在 byteArray 中时的内存问题

Bitmap.compress 导致文件太大

4

1 回答 1

3

要创建视频动态壁纸,您应该首先查看任何open-source项目,为此您可以查看此项目,对于任何教程,您可以查看此站点。

于 2013-08-22T14:53:10.233 回答