您的位置:首页 > 移动开发

Android用WebView加载flash大文件偶然会出现内存溢出以及蓝色打问号小方块问题的解决方案

2015-02-11 17:07 816 查看
最近一直在做Android系统定制的项目,核心就是在Android系统中加载flash文件实现各种操作。先一步一步来说下整个方案吧,或许正是读者急需知道的思路。

1、预装Adobe Flash插件

到Adobe官网下载最新的Android Flash插件,拷贝到ROM包编译之后的out目录以下的systerm目录下,该目录是系统应用app,开机就会把插件装好了!

2、为Flash插件添加flash文件的安全路径

该步奏是为了实现flash文件能够与Android的APP交互实现,如果只是单单显示flash的话,可以省略。

在"/data/data/com.ideal.swfplayer/app_plugins/com.adobe.flashplayer/.macromedia/Flash_Player/

#Security/FlashPlayerTrust/flashplayer.txt"里面写入你所要加载的flash文件的完全路径。

3、Android加载flash动画

用html文件加载swf文件,然后Android中利用WebView加载该html文件,间接实现加载swf动画,其中的好处在于可以在html文件中嵌入javascript代码实现swf文件与Android App的交互。具体如何实现WebView加载flash文件以及如何进行交互的源码在我的博客:Android通过javascript与flash动画交互

4、加载flash文件蓝色打问号小方块界面

该方案正常运行,但是,有一个偶然现象:大概有5%的机会在加载flash文件时会出现一个蓝色打问号小方块界面,经过排除,确定时加载flash是Adobe Flash的插件没运行 起 来,但是咧,查看eclipse中的DDMS的进程列表确实存在Adobe Flash插件呀!再次排查之后确定问题出在时系统开机时flash插件以及我的flash APP的运行顺序的问题。 怎么说呢?首先我的APP我设置成系统应用,开机自启动,Adobe Flash插件也是系统应用,这样就存在谁先起来的问题了,假如我的APP先起来的话,当加载flash文件时发
现没有flash插件,当然会出现蓝色小方块了(加载失败)。所以理解了错误根源之后再想解决方案。

我的思路是:让我的APP代码中一运行就检查flash插件是否存在,不存在则延迟加载flash文件,直到检测到为止,代码如下:

//每500ms检测flash插件是否起来
Handler flash_handler = new Handler();
Runnable flash_Thread = new Runnable(){
public void run() {
CheckNumber++;
if(mFileOperation.CheckFlash()){
Log.e("flash_ok", "OK");
flash_handler.removeCallbacks(flash_Thread);
//1秒之后启动应用
loadSwf(FlashPath.MainPath);
}else{
Log.e("flashnone", "None");
flash_handler.postDelayed(flash_Thread, 500);
//提示重启机器
if(CheckNumber>=10){
mDialogOperation.ShowTips(R.drawable.reboot,10);
flash_handler.removeCallbacks(flash_Thread);
}
}
}
};


其中checkflash函数定义如下:

//判断flash插件是否存在
public boolean CheckFlash() {
PackageManager pm = mContext.getPackageManager();
List<PackageInfo> infoList = pm.getInstalledPackages(PackageManager.GET_SERVICES);
for (PackageInfo info : infoList) {
if ("com.adobe.flashplayer".equals(info.packageName)) {
return true;
}
}
return false;
}


然后在create函数启动该方法即可:

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flash);
//初始化UI界面
InitUI();
//初始化配置
InitConfig();
//启动定时检测flash插件是否存在,才能在则加载主界面
flash_handler.post(flash_Thread);
}
如此,该问题得到解决。经测试,大概开关机300次会出现一次该现象,已经不影响使用。

5、加载flash大文件偶然会出现内存溢出导致异常退出

Android中加载flash文件非常耗内存,而且会一直积累着,到达一定程度之后就会出现内存溢出,然后整个应用重启了。这个问题该如何解决呢?先普及一下Android的内存 管理机制吧~

Android系统每个正在运行的APP都是一个进程,APP里面可以分出很多线程。Android系统为每个进程分配了一个可以自适应伸缩但是最大值固定的堆,叫Heap,该堆是的 最大值是无法改变的,所以一旦在一个进程中的内存接近或者超过了该堆得大小,就会发生内存溢出的异常。我的情况是这样的:APP主界面加载一个比较大的flash,然后在这个界面上发送各种动作之后跳转到另外界面加载另外的flash文件,所以会导致一个进程多个flash文件堆积,时间一久堆内存就会满了。所以我们的解决方案就围绕着怎么利用单个进程单个堆的局限去优化。所以我选择跳转到另外界面加载flash时新开一个进程(即新开一堆),这样就解决了内存溢出的问题。怎么实现呢?

假如我的主进程名叫:com.ideal.swfplayer

新进程名叫:com.ideal.darlingcard

我要跳转加载另外flash的Activity名字叫:DarlingCardFlashActivity.java

(1)修改AndroidManifest.xml 的activity(com.ideal.darlingcard为新开辟的进程名)

<activity
android:name=".DarlingCardFlashActivity"
android:launchMode="singleTask"
android:process="com.ideal.darlingcard">
</activity>

(2)在AndroidManifest.xml 的application添加中添加硬件加速设置

android:largeHeap="true"
android:hardwareAccelerated="true"
(3)在DarlingCardFlashActivity.java最后代码中加入以下代码,让该Activity退出后自动杀死本进程

@Override
protected void onDestroy() {
super.onDestroy();
android.os.Process.killProcess(android.os.Process.myPid());
}
如上方式可以解决内存溢出的问题,大大降低了出现该问题的概率。具体两个进程的效果可以查看以下的效果图~

6、如何查看应用的内存使用情况

方式一:通过eclipse的DDMS查看,步奏如下:



方式二:通过adb调试工具查看

adb shell
procrank




方式一:通过eclipse的DDMS查看,步奏如下:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: