Android中Activity频繁进入再退出时程序崩溃的解决方案

最近在对一款开发中的游戏进行压力测试时会出现崩溃的问题,具体场景是 在进入一个Activity时立即按返回键退出该Activity再迅速进入该Activity,进入退出的时间间隔越短越容易发生崩溃,后来打印日志发现,由于Activity进入需要加载资源,退出需要释放资源,这两个操作都需要一定的时间,照以上场景进行压力测试就会出现 Activity在资源还没加载完之前然后程序就会去释放资源,这样就会出现空指针而崩溃;另一种情况是程序加载资源比较多,这样耗费的时间会比较久,同样释放资源也会比较久,在立即退出Activity再迅速进入该Activity的时候就会出现Activity的资源还没来得及释放,然后就再次加载了一遍资源,这样就会出现内存溢出异常。

解决问题一定要从根源出发,这样才能确保问题被彻底解决。上述问题的根源就是 由于用户操作太快导致资源在未被加载完之前又开始释放,以及资源会被重复加载两次。从问题根源出发,我们只要保证资源在加载完成之前确保资源不会被释放,以及资源不会被重复加载,这样问题就可以迎刃而解了。

解决方案有两种:一是加Loading页面,强制用户等待,这种方式在很多比较大型的游戏里很常见。二,是设置标志位在Activity资源加载完成之前禁止用户退出Activity, 这个适用于一些资源不太多,没有Loading页面的的情况,本质上也是强制用户等待(一些小的游戏常常没有loading页面 ,资源加载也加载也比较快,所以常常忽略了压力测试)

第一种方案,相信做游戏的朋友们都很熟悉,这里就不细讲了。

第二中方案,这里给出个一个框架,如下:

public class Test1 extends Activity

{

public static final int MSG_INIT_COMPLETE = 1;

public static final int MSG_DELAYED = 200;

private boolean isResume;



@Override

protected void onCreate(Bundle savedInstanceState)

{



// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

initRes();

isResume = false;

mHandler.sendEmptyMessageDelayed(MSG_INIT_COMPLETE, MSG_DELAYED);



}



public Handler mHandler = new Handler()

{



@Override

public void handleMessage(Message msg)

{



// TODO Auto-generated method stub

super.handleMessage(msg);

switch (msg.what)

{



case MSG_INIT_COMPLETE:

isResume = true;

break;



}

}

};

protected void onDestroy()

{



// TODO Auto-generated method stub

super.onDestroy();

recycleRes();

}



@Override

public boolean onKeyDown(int keyCode, KeyEvent event)

{



// TODO Auto-generated method stub

if (keyCode == KeyEvent.KEYCODE_BACK)

{

if (isResume)

{

startActivity(new Intent(this,Test2.class));

finish();

}

else

return false;

}

return super.onKeyDown(keyCode, event);

}

}

以上代码框架是防止Test1的资源被加载完成之前开始释放资源,即在资源加载完成之前屏蔽返回键事件。为了保险起见,在不影响用户体验的前提下大家可以把MSG_DELAYED的值再设置的大些。

public class Test extends Activity implements OnClickListener

{



public static final int MSG_INIT_COMPLETE = 1;

public static final int MSG_DELAYED = 200;

private boolean isResume;



@Override

protected void onCreate(Bundle savedInstanceState)

{



// TODO Auto-generated method stub

super.onCreate(savedInstanceState);

isResume = false;

mHandler.sendEmptyMessageDelayed(MSG_INIT_COMPLETE, MSG_DELAYED);



}



public Handler mHandler = new Handler()

{



@Override

public void handleMessage(Message msg)

{



// TODO Auto-generated method stub

super.handleMessage(msg);

switch (msg.what)

{



case MSG_INIT_COMPLETE:

isResume = true;

break;



}

}

};



@Override

public void onClick(View v)

{



// TODO Auto-generated method stub

case TAG_GOTO_TEST1:

if(isResume)

{

startActivity(this,test1.class);

finish();

}

break;



}

}

这段代码是防止Test1的资源在释放完之前再次进入Test1造成内存溢出,同样,在不影响用户体验的前提下进入Test1的延迟时间可以再长久一些。

-------------------------------------------------------------------------------------

本文出自http://labs.easymobi.cn/?p=4386

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值