国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > iOS > 正文

android 和 ios中實現類似C#的BackgroundWorker接口

2019-11-06 09:49:45
字體:
來源:轉載
供稿:網友

移動應用為支持各種功能,大多采用了多線程技術。使用單獨的線程執行某些任務,同時不影響界面的刷新,在線程執行過程中,可能需要通知一些信息給界面線程,在線程結束之后,需要告訴界面線程執行的結果,這是較為通用的一種線程執行方式。

    在C#中,實現該功能的類是BackgroundWorker,而在android和ios中,并無類似的封裝好的類。通常在開發應用的時候需要考慮可移植性,存在為多種平臺開發相同應用的情況,為簡化不同平臺應用的開發,編程需要考慮相同的邏輯結構。因此在android和ios實現與BackgroundWorker類似的功能和接口。

1.C#的BackgroundWorker

    BackgroundWorker包含的主要屬性和接口說明如下:

   主要屬性:

    event DoWorkEventHandler DoWork;  //線程的主體    event PRogressChangedEventHandler ProgressChanged;  //線程運行過程中的消息    event RunWorkerCompletedEventHandler RunWorkerCompleted; //線程結束時的處理

    主要函數:

    void CancelAsync();  取消線程的運行    void ReportProgress(int percentProgress, object userState);  //報告線程的消息    void RunWorkerAsync(object argument);  //開始執行線程

    為了方面使用,可以將BackgroundWorker進行封裝如下

   

    public class StarBackgroundWorker    {        private BackgroundWorker m_worker;        public StarBackgroundWorker()        {            m_worker = new BackgroundWorker();        }        public void CancelAsync()        {            m_worker.CancelAsync();        }        public void RunAsync(DoWorkEventHandler DoWork, object userState, ProgressChangedEventHandler ProgressChanged, RunWorkerCompletedEventHandler RunWorkerCompleted)        {            m_worker.DoWork += DoWork;            m_worker.WorkerSupportsCancellation = true;            m_worker.RunWorkerCompleted += RunWorkerCompleted;            if (ProgressChanged != null)            {                m_worker.ProgressChanged += ProgressChanged;                m_worker.WorkerReportsProgress = true;            }            m_worker.RunWorkerAsync(userState);        }        public void ReportProgress(int percentProgress, object userState)        {            m_worker.ReportProgress(percentProgress, userState);        }    }

    使用方法:

StarCoreBackgroundWorker myworker = new StarCoreBackgroundWorker();myworker.RunAsync(    (object sender1, DoWorkEventArgs e1) =>    {        BackgroundWorker worker = sender1 as BackgroundWorker;        //線程的主體    },    null,    (object sender1, ProgressChangedEventArgs e1) =>    {        //--在界面線程中執行,可以刷新界面    },    (object sender1, RunWorkerCompletedEventArgs e1) =>    {        //--在界面線程中處理,線程運行結束后的處理    });

2.Android中實現類似BackgroundWorker的功能

Android中使用java編程,通常創建線程使用Thread和Runnable,線程與界面線程通信使用消息的方式,從界面線程中的handler獲取一條消息結構,填充參數,使用sendMessage將消息發送給界面線程。界面線程的Handler獲取消息隊列中的消息進行處理。利用這些方式,可以實現類似c# BackgroundWorker功能

a. 封裝Handler

    由于采用Handler處理所有BackgroundWorker線程中的消息,為了區分不同的線程,需要線程在創建時進行登記。代碼如下:

public class StarUIHander {    static public Handler handler;    static int InvokeTag = 0;    static HashMap<Integer,HandlerCallBack> CallBackList;    public interface HandlerCallBack {        void Invoke(Message msg);    }    static int Register(HandlerCallBack CallBack)    {        int Val = InvokeTag;        CallBackList.put(InvokeTag,CallBack);        InvokeTag ++;        return Val;    }    static void Remove(int Which)    {        CallBackList.remove(Which);    }    static void InitStarUIHander()    {        handler = new android.os.Handler() {            public void handleMessage(Message msg) {                HandlerCallBack CallBack = CallBackList.get(msg.what);                if( CallBack != null )                    CallBack.Invoke(msg);            }        };        CallBackList = new HashMap<Integer,HandlerCallBack>();    }}

    在android應用主Activity中,調用InitStarUIHander初始化Handler,對于創建的線程,調用Register注冊消息處理函數,獲取標識,使用該標識發送消息時。

b. 實現BackgroundWorker功能

    在實現BackgroundWorker之前,參照c#的定義,需要實現一些相關的接口。有以下幾個:    CancellationTokenSource, ProgressChangedEventArgs, DoWorkEventArgs,RunWorkerCompletedEventArgs,具體代碼可參考附件

   

public BackgroundWorker(){    //_dispatcher = this.Dispatcher;    cts = new CancellationTokenSource();    HandlerQueue = StarUIHander.Register(new StarUIHander.HandlerCallBack() {        @Override         public void Invoke(Message msg) {            Object[] Para = (Object[])msg.obj;            switch ((int)Para[0]) {            case Message_ReportProgress:                if (ProgressChanged != null ){                    ProgressChanged.Invoke(this,(ProgressChangedEventArgs)Para[1]);                }                break;            case Message_OnRunWorkerCompleted:                if (RunWorkerCompleted != null)                    RunWorkerCompleted.Invoke(this,(RunWorkerCompletedEventArgs)Para[1]);                break;            }        }    });}

    報告狀態:

public void ReportProgress(int percentProgress, Object userState){    if (ProgressChanged != null ){        Message message = StarUIHander.handler.obtainMessage();        message.what = HandlerQueue;        message.obj = new Object[]{Message_ReportProgress,new ProgressChangedEventArgs(percentProgress,userState)};        StarUIHander.handler.sendMessage(message);    }}

    創建線程執行:

public void RunWorkerAsync(Object userState){    final BackgroundWorker m_worker = this;    if (DoWork != null)    {        IsBusy = true;        try {            final DoWorkEventArgs args = new DoWorkEventArgs(userState);            new Thread(new Runnable(){                @Override                public void run() {                    DoWork.Invoke(m_worker, args);                    IsBusy = false;                    if (RunWorkerCompleted != null) {                        Message message = StarUIHander.handler.obtainMessage();                        message.what = HandlerQueue;                        message.obj = new Object[]{Message_OnRunWorkerCompleted, new RunWorkerCompletedEventArgs(args.Result, null, args.Cancel)};                        StarUIHander.handler.sendMessage(message);                    }                }            }).start();        }        catch (Exception ex) {            IsBusy = false;            if (RunWorkerCompleted != null) {                Message message = StarUIHander.handler.obtainMessage();                message.what = HandlerQueue;                message.obj = new Object[]{Message_OnRunWorkerCompleted, new RunWorkerCompletedEventArgs(false, ex, false)};                StarUIHander.handler.sendMessage(message);            }        }    }}

     為了方面使用,將BackgroundWorker進行封裝如下

    public static class StarCoreBackgroundWorker    {        private BackgroundWorker m_worker;        public StarCoreBackgroundWorker()        {            m_worker = new BackgroundWorker();        }        public void CancelAsync()        {            m_worker.CancelAsync();        }        public void RunAsync(DoWorkEventHandler DoWork, Object userState, ProgressChangedEventHandler ProgressChanged, RunWorkerCompletedEventHandler RunWorkerCompleted)        {            m_worker.DoWork = DoWork;            m_worker.WorkerSupportsCancellation = true;            m_worker.RunWorkerCompleted = RunWorkerCompleted;            if (ProgressChanged != null)            {                m_worker.ProgressChanged = ProgressChanged;                m_worker.WorkerReportsProgress = true;            }            m_worker.RunWorkerAsync(userState);        }        public void ReportProgress(int percentProgress, Object userState)        {            m_worker.ReportProgress(percentProgress, userState);        }    }

    使用方法:

StarBackgroundWorker myworker = new StarBackgroundWorker();myworker.RunAsync(        new DoWorkEventHandler() {            public void Invoke(Object sender1, DoWorkEventArgs e1) {                BackgroundWorker worker = sender1 as BackgroundWorker;                //線程的主體            }        },        null,        new ProgressChangedEventHandler() {            public void Invoke(Object sender1, ProgressChangedEventArgs e1) {                //--在界面線程中執行,可以刷新界面            }        },        new RunWorkerCompletedEventHandler() {            public void Invoke(Object sender, RunWorkerCompletedEventArgs e)             {                //--在界面線程中處理,線程運行結束后的處理            }       });

3. ios中實現類似BackgroundWorker的功能

    ios創建線程可以使用NSThread,在界面線程中運行調用performSelectorOnMainThread函數;也可以使用GCD相關的函數,對多線程進行封裝,可以實現類似c#的BackgroundWorker功能

a. 實現BackgroundWorker功能

    與android類似,在實現BackgroundWorker之前,參照c#的定義,同樣需要實現一些相關的接口。有以下幾個:CancellationTokenSource, ProgressChangedEventArgs, DoWorkEventArgs,RunWorkerCompletedEventArgs,具體代碼可參考附件

    定義接口:

typedef void(^ProgressChangedEventHandler)(id,ProgressChangedEventArgs*);typedef void(^RunWorkerCompletedEventHandler)(id,RunWorkerCompletedEventArgs*);typedef void(^DoWorkEventHandler)(id,DoWorkEventArgs*);

    實現BackgroundWorker

    上報狀態:

-(void)ReportProgress:(uint)percentProgress userState:(id)userState{    if (ProgressChanged != nil || ProgressChangedSelector != nil ){        dispatch_async(dispatch_get_main_queue(),^{            @try{                if( ProgressChangedSelector == nil )                    ProgressChanged(self,[ProgressChangedEventArgs initProgressChangedEventArgs:percentProgress UserState:userState]);                else{                    IMP imp = [SelectorController methodForSelector:ProgressChangedSelector];                    void (*func)(id, SEL, id, ProgressChangedEventArgs* ) = (void *)imp;                    func(SelectorController, ProgressChangedSelector, self, [ProgressChangedEventArgs initProgressChangedEventArgs:percentProgress UserState:userState]);                }            }            @catch(NSException* e)            {                            }        });    }}    異步執行

-(void)RunWorkerAsync:(id)userState{    if (DoWork != nil || DoWorkSelector != nil)    {        @try {            DoWorkEventArgs* args = [DoWorkEventArgs initDoWorkEventArgs:userState];            dispatch_async(dispatch_get_global_queue(0, 0),^{                if( DoWork != nil )                    DoWork(self,args);                else if(DoWorkSelector != nil ){                    IMP imp = [SelectorController methodForSelector:DoWorkSelector];                    void (*func)(id, SEL, id, DoWorkEventArgs* ) = (void *)imp;                    func(SelectorController, DoWorkSelector, self,args);                }                dispatch_async(dispatch_get_main_queue(),^{                    if (RunWorkerCompleted != nil)                        RunWorkerCompleted(self,[RunWorkerCompletedEventArgs initRunWorkerCompletedEventArgs:args.Result Cancelled:args.Cancel]);                    else if(RunWorkerCompletedSelector != nil){                        IMP imp = [SelectorController methodForSelector:RunWorkerCompletedSelector];                        void (*func)(id, SEL, id, RunWorkerCompletedEventArgs* ) = (void *)imp;                        func(SelectorController, RunWorkerCompletedSelector, self,[RunWorkerCompletedEventArgs initRunWorkerCompletedEventArgs:args.Result Cancelled:args.Cancel]);                    }                });            });        }        @catch(NSException* e)        {            dispatch_async(dispatch_get_main_queue(),^{                if (RunWorkerCompleted != nil)                    RunWorkerCompleted(self,[RunWorkerCompletedEventArgs initRunWorkerCompletedEventArgs:e]);                else if( RunWorkerCompletedSelector != nil ){                    IMP imp = [SelectorController methodForSelector:RunWorkerCompletedSelector];                    void (*func)(id, SEL, id, RunWorkerCompletedEventArgs* ) = (void *)imp;                    func(SelectorController, RunWorkerCompletedSelector, self,[RunWorkerCompletedEventArgs initRunWorkerCompletedEventArgs:e]);                }            });        }    }}

 

b. 為了方面使用,將BackgroundWorker進行封裝如下

-(void)RunAsync:(DoWorkEventHandler)DoWork userState:(id)userState ProgressChanged:(ProgressChangedEventHandler)ProgressChanged RunWorkerCompleted:(RunWorkerCompletedEventHandler)RunWorkerCompleted{    m_worker.DoWork = DoWork;    m_worker.RunWorkerCompleted = RunWorkerCompleted;    if (ProgressChanged != nil)    {        m_worker.ProgressChanged = ProgressChanged;    }    [m_worker RunWorkerAsync:userState];}-(void)ReportProgress:(uint)percentProgress userState:(id)userState{    [m_worker ReportProgress:percentProgress userState:userState];}使用方法:

StarBackgroundWorker* myworker = [StarBackgroundWorker initStarBackgroundWorker];            [myworker RunAsync:^(id sender1, DoWorkEventArgs *e) {                BackgroundWorker* worker = (BackgroundWorker*)sender1;                            } userState:nil ProgressChanged:^(id sender1, ProgressChangedEventArgs *e) {            } RunWorkerCompleted:^(id sender1, RunWorkerCompletedEventArgs *e) {            }            }];

4. 結束語

    如果不考慮可移植性,可以直接使用android,ios,windows中定義的多線程方法開發應用,但由于不同平臺采用的是不同語言,多線程實現接口和方式不同,會影響應用的邏輯結構,增加不同平臺移植的工作量。基于線程執行過程,參考C#中的BackgroundWorker機制,在android和ios實現了類似的多線程機制,采用相同的框架結構,提供類似的接口,可以使多線程在不同平臺具有相同的邏輯結構

    上面的代碼不完整,具體請參考附件

下載附件


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 永川市| 洛隆县| 于都县| 英山县| 遵义县| 安义县| 肥西县| 冷水江市| 浦东新区| 南漳县| 荔波县| 兰州市| 苗栗县| 车险| 岗巴县| 盐源县| 海丰县| 五河县| 商洛市| 广昌县| 邢台县| 长岛县| 互助| 开封县| 越西县| 兴安盟| 达州市| 崇文区| 德兴市| 聊城市| 广安市| 威信县| 宜兰市| 舟曲县| 新竹县| 铜山县| 句容市| 梁河县| 株洲县| 阿勒泰市| 龙海市|