首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > Symbian >

调用AO的有关问题,各位大侠伸手

2012-12-25 
调用AO的问题,各位大侠伸手啊小弟本来想用了两个活动对象来同时做不同的事情,但两个AO一起执行时,先执行的

调用AO的问题,各位大侠伸手啊
小弟本来想用了两个活动对象来同时做不同的事情,但两个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;


        if(iStatus==KErrNone)
                {
                switch ( iState )
                    {
                        case EStateBatteryInfo:
                                batteryStrength=iBatteryInfoV1.iChargeLevel;
                               if(iBattery!=batteryStrength)
                               {
                                       iBattery =iBatteryInfoV1.iChargeLevel;        
                                       iState = EStateNetworkInfo;
                               }
                               iState = EStateNetworkInfo;
                                break ;
                        case EStateNetworkInfo:
                                if(iNetwork != iSigStrengthV1.iBar)
                                        {
                                       iNetwork = iSigStrengthV1.iBar;
                                       iState = EStateBatteryInfo;
                                        }
                                iState = EStateBatteryInfo;


                                break ;
                        default:
                    break;
                }
        }
        HandleAsyncCalls();
        }
[其他解释]
可以每隔一段时间获取系统信号和电量
当获取后,通知视图调用刷新接口

应该是太频繁刷新,导致AO超时

[其他解释]

引用:
可以每隔一段时间获取系统信号和电量
当获取后,通知视图调用刷新接口

应该是太频繁刷新,导致AO超时

那为什么第一个AO正常?启动第一个AO的时候已经在刷屏了啊
[其他解释]
是第一个AO的第二次转换后的RunL
[其他解释]

转码是长线任务,即使在正常情况下,和频繁请求的AO在一起,也不会得到响应。将转码放到另外一个线程,或者伪同步

热点排行