Symbian中的gprs串連關斷方法

來源:互聯網
上載者:User

北京理工大學%20陳罡

 

 
在Symbian開發中,很多朋友都提出了gprs串連無法關斷的問題。
這種問題的主要表象是——
當我們關閉gprs串連的時候,程式就發生異常退出了。(屢試不爽)
這是為什麼呢?
我做了很多實驗 ,都一樣的效果,即使採用Nokia論壇提供的例子也是同樣的結果。
只要把socket engine一刪除,整個程式就退出了。
就拿HttpExample為例,我們看看它的解構函式是如何操作的吧:
CClientEngine::~CClientEngine()  {
                iSession.Close();
                iSocketServ.Close() ;
                delete iPostData;
                iPostData = NULL;
}
我試過這個解構函式,如果直接delete掉CClientEngine引擎對象,那麼程式會毫不猶豫的
退出,而不是關掉串連。如果把iSocketServ.Close()這句注釋掉,就像下面這樣:
CClientEngine::~CClientEngine()  {
                iSession.Close();
        //        iSocketServ.Close() ;     <------ 注釋掉
                delete iPostData;
                iPostData = NULL;
}
那麼程式的gprs串連根本不會斷開。
這可如何是好呢?我們知道symbian系統也是運行在arm處理器上的,而iSession是包含有
flash晶片上的檔案操作的。那麼會不會是由於晶片處理速度太慢或者由於關斷iSession
需要一段時間(其實也就是1~2秒鐘的時間),而這個操作恰恰是非同步行為導致的呢?

我們假設一下,如果iSession.Close()的操作是非同步,在Symbian系統還沒有把iSession關閉
之前,我們調用了iSockServ.Close(),這樣就導致了錯誤。

出於這個疑問,我開始了實驗,我先手工添加如下函數:
void CClientEngine::CloseSockSvr()
{
        iSocketServ.Close() ;
        if(iCurConn == EConnected) iCurConn = ENotConnected ;
}

void CClientEngine::CloseSession()
{
        iSession.Close() ;
}
也就是不從解構函式中直接關閉iSession和iSocketServ,而是把這兩個關閉函數
獨立出來,變成公有函數,由CClientEngine引擎的外部來逐一關閉。
實驗證明,這樣從菜單上,先手工關閉iSession,然後等一至兩秒鐘後,再手工
關閉iSocketServ,是完全可以實現gprs串連關閉的,而且程式也不會退出。

那麼如何讓程式自動關閉gprs串連呢?
我考慮採用timer,一個使用中的物件,來完成這個任務。
標頭檔定義:
#include <e32base.h>
class CMbAppUi ;
class CCloseTimer : public CTimer 
{
protected:
        CMbAppUi * m_ui ;
        TInt       m_sec_count ;

private: // from CActive
        void RunL();
        void Queue() ;  // inner time delay function

public:
        CCloseTimer();
        virtual ~CCloseTimer();
        void ConstructL(CMbAppUi * pui) ;
};
下面是cpp檔案定義:
#include <coemain.h>
#include "CloseTimer.h"
#include "MbAppUi.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
const TInt KIntervalTime = 1000000 ; // 2 second

CCloseTimer::CCloseTimer():CTimer(EActivePriorityLogonA)   //  -------> 這裡把優先順序定成最低
{                                                                                                // 保證系統只有再閒置時候才運行Timer
        m_ui = NULL ;
        m_sec_count = 0 ;
}

CCloseTimer::~CCloseTimer()
{

}

void CCloseTimer::RunL()
{
        Queue();             //   ---------->   這裡就是延時操作了
        m_sec_count++ ;
        if(m_sec_count == 1 ) m_ui->CloseSession() ;     //  ------> 這裡關閉了iSession,
        else if(m_sec_count == 3) m_ui->CloseSockSvr() ;  // ---->兩秒鐘後,我們關閉iSocketServ
        else if(m_sec_count == 4) {                                      // 至此,外部的gprs串連已經完全關閉了。
                if(m_ui->iMsgCount) m_ui->ShowGlobalNote() ;
        } else if(m_sec_count >= 5) {
                Cancel() ;
                if(m_ui->iMsgCount)        m_ui->StopCloseTimer() ;
                else m_ui->HandleCommandL(EEikCmdExit) ;
        }
}

void CCloseTimer::Queue() {
        After(KIntervalTime) ; 
}

void CCloseTimer::ConstructL(CMbAppUi * pui)
{
        CTimer::ConstructL() ;
          CActiveScheduler::Add( this ) ;   // ------>這句是把當前timer加入到Active Object的調度器中去
        if(pui != NULL) m_ui = pui ;
        Queue() ;                                     // ------->這句必須要加,否則調度器不會有機會運行喔!
}

嗯,這個技術大概就是這個樣子了。
上述的代碼是在Symbian S60 2.1 sdk下面調試通過。在6600,6670,7610,6681等真機上測試通過。
 
 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.