Kotlin入門(29)任務Runnable

来源:https://www.cnblogs.com/aqi00/archive/2018/10/27/9860756.html
-Advertisement-
Play Games

任務Runnable定義了一個可以獨立運行的代碼片段,通常用於界面控制項的延遲處理,比如有時為了避免同時占用某種資源造成衝突,有時則是為了反覆間隔刷新界面從而產生動畫效果。運行一個任務也有多種形式,既可在UI線程中調用處理器對象的post或者postDelayed方法,也能另外開啟分線程來執行Runn ...


任務Runnable定義了一個可以獨立運行的代碼片段,通常用於界面控制項的延遲處理,比如有時為了避免同時占用某種資源造成衝突,有時則是為了反覆間隔刷新界面從而產生動畫效果。運行一個任務也有多種形式,既可在UI線程中調用處理器對象的post或者postDelayed方法,也能另外開啟分線程來執行Runnable對象。那麼在運行任務之前,必須事先聲明該任務的對象,然後才能由調用者執行該任務。Kotlin代碼聲明Runnable對象有四種方式,分別對應不同的業務場景,接下來就依次闡述Runnable對象的四種聲明方式:

第一種:內部類
內部類方式是最循規蹈矩的,在代碼里先書寫一個繼承自Runnable的內部類,再重寫它的run方法,填入具體的業務邏輯處理。以最常見的計數器為例子,每隔一秒便在界面上顯示加一後的計數結果,使用內部類方式進行變化的話,就是以下的Kotlin代碼:

    private val handler = Handler()
    private var count = 0
    inner private class Counter : Runnable {
        override fun run() {
            count++
            tv_result.text = "當前計數值為:$count"
            handler.postDelayed(this, 1000)
        }
    }

 

然後在Activity頁面的onCreate方法中加上下麵一行代碼,命令執行這個計數任務:

    handler.post(Counter())

第二種:匿名內部類

內部類的方式最正規,無疑也是最啰嗦的。由於這個計數任務只在頁面打開時啟動,因此並不需要對其顯式構造,只要在定義內部類時順便聲明任務實例即可。此時的聲明代碼便從內部類方式變成了匿名內部類方式,採取Kotlin編碼的話註意使用關鍵字object占位,表示這是一個匿名內部類,完整的Kotlin代碼如下所示:

    private val counter = object : Runnable {
        override fun run() {
            count++
            tv_result.text = "當前計數值為:$count"
            handler.postDelayed(this, 1000)
        }
    }

 

因為定義內部類的同時就聲明瞭任務實例,所以處理器直接運行該實例即可啟動任務:

    handler.post(counter)

 

內部類與匿名內部類這兩種方式,其實內部都擁有類的完整形態,故而它們的run方法允許使用關鍵字this指代這個人物類,示例代碼中的“handler.postDelayed(this, 1000)”意思是間隔一秒之後重覆執行自身任務。正因為能夠重覆執行任務,所以這兩種方式可用於持續刷新界面的動畫效果。

第三種:匿名函數
前面的兩種內部類實現方式,擁有類的完整形態意味著必須顯式重寫run方法,可是這個任務類肯定且只能重寫run方法,即使開發者不寫出來,run方法也是逃不掉的。早在第一章,當時為了演示Kotlin代碼的間接性,舉了一個例子“按鈕對象.setOnClickListener { 點擊事件的處理代碼 }”,這種寫法正是採取了Lamba表達式,直接把點擊事件介面的唯一方法onClick給省略掉。因此,本節的任務對象也可使用類似的寫法,只要說明該對象是Runnable類型,則多餘的run方法就能如願去除。下麵是個將任務對象改寫後的Kotlin代碼:

    private val counter = Runnable {
        count++
        tv_result.text = "當前計數值為:$count"
    }

 

顯而易見,上述的counter仍是Runnable類型,於是處理器依舊運行該實例即可啟動任務:

    handler.post(counter)

 

不過這種寫法去掉run方法是有代價的,雖然錶面上代碼變得簡潔,但是並不擁有類的完整結構,其內部的this關鍵字不再表示任務類自身,而是表示宿主類即Activity活動類了。鑒於這點變化,該方式內部不可再調用處理器的post或者postDelayed方法,意味著此時任務實例無法重覆調用自身。因此,採取了匿名函數方式的任務對象,適用於不需要重覆刷新的場合。

第四種:匿名實例
註意到前面的counter是個經過等號賦值的任務對象,既然這樣,不如直接把等號右邊的表達式塞進post方法,就像下麵的Kotlin代碼那樣:

    //第1點:在post方法中直接填寫Runnable對象的定義代碼
    handler.post(Runnable {
        count++
        tv_result.text = "當前計數值為:$count"
    })

 

上面的代碼還可以進一步精簡,因為post方法只能輸入Runnable類型的參數,所以括弧內部的Runnable純屬多餘;另外,post方法有且僅有一個輸入參數,於是圓括弧嵌套大括弧稍顯繁瑣。把這兩個冗餘之處分別刪除與合併,得到了匿名實例版的Kotlin代碼:

    //第2點:如果該任務只需執行一次,則可採用匿名實例的方式,直接嵌入任務的執行代碼
    handler.post {
        count++
        tv_result.text = "當前計數值為:$count"
    }

 

上述去掉圓括弧的辦法,只適合post方法這種僅有一個參數的調用,如果其它方法存在多個輸入參數如postDelayed方法,則外層的圓括弧仍需予以保留,此時大括弧及其內部代碼就作為一個函數參數傳入。恢復了圓括弧的Kotlin調用代碼如下所示:

    //第3點:如果是延遲執行任務,則可將匿名實例作為postDelayed的輸入參數
    handler.postDelayed({
        count++
        tv_result.text = "當前計數值為:$count"
    }, 1000)

 

匿名實例方式直接把任務代碼寫在調用函數之中,意味著這段任務代碼無法被其他地方調用,所以它的適用場景更加狹小。匿名函數雖然無法重覆調用,但是尚且允許在不同地方多次調用,而匿名實例只能在它待過的地方曇花一現,因此還是要根據實際的業務要求來選擇合適的任務方式。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言 前有芋艿大佬已經發過相關分析的文章,自己覺的源碼總歸要看一下,然後看了就要記錄下來(記性很差...),所以就有了這篇文章(以後還要繼續更
  • SELECT DATEADD(Day,(@i+1)-(DATEPART(Weekday,getdate())+@@DATEFIRST-1)%7,getdate()) ...
  • 來源:原創網站北京北亞數據恢復中心,轉載須註明出處。 學習資料庫時,我們只是以學習的態度,考慮如何使用資料庫命令語句,並未想過工作中,如果誤操作一下,都可能導致無可輓回的損失。當我在工作中真正遇到這些問題時,我開始尋找答案。 今天主要以oracle資料庫為例,介紹關於表中數據刪除的解決辦法。(不考慮... ...
  • 一. 環境準備 1.1 主庫環境(172.168.18.201) 環境 說明 查看腳本 操作系統版本 CentOS Linux release 7.4.1708 (Core) cat /etc/redhat-release 操作系統用戶名和密碼 root js*2015 IP地址 172.168.1 ...
  • 當我們需要對數據做篩選和查詢的時候,往往會涉及到一些限制條件的判斷,今天就分享一個判斷字元串的技巧。 like 相信大家對like的用法肯定都很熟悉了,它可以匹配欄位以某字元串開始,以某字元串結尾,包含有某字元串,用法如下:like '%string',like 'string%',like '%s ...
  • 一、問題 用Eclipse做項目時候報錯 java.sql.SQLException: Incorrect string value: '\xE4\xB8\x80\xE6\xAC\xA1...' for column 'excelName' at row 1。而且就只有這個表的插入有問題。 二、解決 ...
  • 從微信的誕生,到微信公眾號、微信支付,再到小程式,騰訊生態在一次又一次影響用戶行為習慣的同時,也為開發者提供了新的思路和技能發展方向。無可置疑,微信小程式開發浪潮已經來臨,也將在 2018年成為各行業流量紅利的集中爆發入口。 4月28日,騰訊雲聯合 InfoQ舉辦的雲 +社區技術沙龍,以小程式開發實 ...
  • 一.首先檢查我們的代碼: 二.註冊在主活動上的代碼需要補上: 從中我們可以看到我們註冊在XML界面上,<intent-filter>後面的代碼為<action android:name="com.example.lenovo.activitytest.ACTION_START"/>,action中間 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...