小弟本来想用了两个活动对象来同时做不同的事情,但两个AO一起执行时,先执行的会挂掉,进不到RunL里面。首先想问,可以在主线程里面可以同时使用多个AO吗?
后来想在主线程里面用一个AO,单开一个线程用一个AO,但是在线程里面AO的RunL执行十多次就不执行了,很郁闷!
请各位大哥指导指导!多谢!
------最佳解决方案--------------------------------------------------------
用AO必然会出现你这个情况,AO是抢占式的,先来先服务,同时来的才看优先级。一个AO的RunL执行完了,另一个AO的RunL才有机会执行。
RunL 的时间不能太长。
CActiveScheduler会等待活动对象绑定的异步函数返回的“完成”消息。收到完成消息后,调度器遍历所注册的活动对象,如果发现status != KRequestPending则找到该status对应的“活动对象”,调用其中的RunL方法,以事件的方式告知我们异步函数已经执行完成。
如果活动对象的iActive = ETrue且iStatus != KRequestPending则调用活动对象的RunL方法
另外,“进不到RunL里面”的原因有很多的:
1、只有注册了CActiveScheduler才能找到AO并调用该AO的RunL
2、SetActive
3、AO的异步函数没有能改iStatus 为非KRequestPending
4、将iStatus同时传给两个异步函数,要避免的话:if(IsActive()) { Cancel(); }
你的问题可能出在:你在执行png转换的异步函数前,没有检查if(IsActive())
第一次转换还没有执行到RunL时(这个时候可能在执行第二个AO的RunL) 第二次转换来了(SetActive使得iActive = ETrue)。
然后CActiveScheduler调用了AO(第一次转换)的RunL,RunL执行完后iActive = EFalse。
这个时候第二次转换的异步函数执行完了CActiveScheduler发现:iActive = EFalse且iStatus != KRequestPending,这个时候CActiveScheduler找不到符合iActive = ETrue且iStatus != KRequestPending的AO,出现了信号迷失,当然第一个AO的RunL也就没有执行了。
------其他解决方案--------------------------------------------------------
多个AO肯定是没问题的,请关注你自己AO的优先级,如有可能,贴出代码
------其他解决方案--------------------------------------------------------
能用AO尽量不用线程
------其他解决方案--------------------------------------------------------
HandleAsyncCalls处理了两个不同的异步请求,一个没执行完,另一个又进来了,这个有可能出错
------其他解决方案--------------------------------------------------------
AO的优先级都是EPriorityStandard,然后我把第一个的优先级设置为最高,后一个启动的优先级设置为最低进行测试,发现第一个启动的AO还是会挂掉
用线程也是没办法的事啊,用AO进行不断的回调刷屏的时候,模拟器上正常,真机上就死机,改成线程就好了,具体原因还没有深究
第一个AO是进行png转换,后一个AO是在主界面不断获取系统信号和电量。
获取信号和电量的代码:
void CSysInfoEngine::HandleAsyncCalls()
{
switch ( iState )
{
case EStateBatteryInfo:
iTelephony->GetBatteryInfo(iStatus, iBatteryInfoV1Pckg);
break ;
case EStateNetworkInfo:
iTelephony->GetSignalStrength(iStatus, iSigStrengthV1Pckg);
break ;
default:
break;
}
IssueRequest( );
}
void CSysInfoEngine::IssueRequest()
{
if( !IsActive() )
{
SetActive() ;
}
}
void CSysInfoEngine::RunL()
{
TInt state = 0;
TInt batteryStrength = 0;