首先,我不喜歡的在Android項(xiàng)目中用的Handler是長(zhǎng)這樣的
private static final int DO_SOMEGTING = 1; private static final int DO_OTHER_THING = 2; private Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case DO_SOMEGTING: xxxxxxxxxxx 具體代碼 xxxxxxxx break; case DO_OTHER_THING: xxxxxxxxxxx 具體代碼 xxxxxxxx break; } }
這種寫(xiě)法的主要原因,我想,絕大多數(shù)是因?yàn)樵诜荱I線(xiàn)程中做了一些操作,比如網(wǎng)絡(luò)請(qǐng)求,之后需要對(duì)界面進(jìn)行操作,這時(shí)候操作就需要在UI線(xiàn)程中進(jìn)行了。例如下面這樣發(fā)送一個(gè)消息給Handler
Message msg = new Message(); msg.what = DO_SOMEGTING; msg.obj = result; mHandler.sendMessage(msg);
上面這樣的寫(xiě)法在各種第三方庫(kù)或者博客上面隨處可見(jiàn),但是,為什么我不喜歡在實(shí)際項(xiàng)目中使用這樣的寫(xiě)法呢?
1. 這樣會(huì)造成代碼混亂,降低代碼的可讀性
寫(xiě)代碼其實(shí)就跟你高考的時(shí)候?qū)懽魑囊粯?,不僅要表達(dá)出你的意思,還要讓閱卷老師一眼就看得懂你在寫(xiě)什么,結(jié)構(gòu)要清晰,因?yàn)榇a不僅僅是寫(xiě)給你自己看的,還要給團(tuán)隊(duì)其他人看的,或者某一天你晚上12點(diǎn)在公司加班,吃著泡面,吃著吃著突然就掛了(-_-#),或者你突然雙色球中了一等獎(jiǎng)把獎(jiǎng)池掏空了,瀟瀟灑灑跟Boss say goodbye,這時(shí)候,后面接手你代碼的哥們(或者妹子)看到你一個(gè)Handler里面好幾百行,switch里面n個(gè)case,心中該是有多奔騰。就算你福如東海壽比南山運(yùn)氣背到爆5塊錢(qián)都沒(méi)中過(guò),但當(dāng)你像上面那樣sendMessage(msg)之后,我想,就算是你自己寫(xiě)的代碼,還是要去全局搜索sendMessage之后會(huì)去執(zhí)行哪里的代碼,話(huà)說(shuō)這跟你用goto是不是有異曲同工之妙?。。。?/p>
2.有更優(yōu)雅的實(shí)現(xiàn)方法
現(xiàn)在RxAndroid都已經(jīng)發(fā)布到1.1版本了,已經(jīng)是穩(wěn)定版了,所以很多開(kāi)發(fā)者也在項(xiàng)目中使用RxAndroid,不得不說(shuō),流式的編程方式用起來(lái)很爽,就像下面這樣
Observable.create((Observable.OnSubscribe<String>) subscriber -> { //這是在io線(xiàn)程執(zhí)行的 }) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe( result->{//這是在UI線(xiàn)程執(zhí)行的} );
這里順便說(shuō)下,很多人弄不清楚subscribeOn和observeOn對(duì)應(yīng)的是執(zhí)行哪一部分的代碼,subscribeOn 執(zhí)行的是subscriber的代碼,observeOn執(zhí)行的是subscribe的代碼,這個(gè)要是搞不清楚,自己寫(xiě)個(gè)小例子測(cè)試下很容易就知道了。
什么時(shí)候可以使用Handler
1.寫(xiě)提供給別人用的第三方庫(kù)的時(shí)候
當(dāng)你在寫(xiě)一個(gè)庫(kù)的時(shí)候,就應(yīng)該盡量避免引入其他第三方庫(kù),因?yàn)闆](méi)準(zhǔn)你的庫(kù)就那么幾十一百K,然后你引用的庫(kù)好幾M,這時(shí)候就要重新思考整個(gè)庫(kù)的設(shè)計(jì)了,例如提供另外可選的庫(kù)來(lái)給用戶(hù)選擇,例如retrofit的json轉(zhuǎn)換就提供了幾個(gè)版本的可選庫(kù)。
2.寫(xiě)博客的時(shí)候
很多時(shí)候?qū)懖┛途蛯?zhuān)門(mén)是為了針對(duì)某個(gè)知識(shí)點(diǎn)進(jìn)行講解,這個(gè)時(shí)候引入一大堆的第三方庫(kù)是很麻煩的,還要額外多講解引入的庫(kù),所以很多博客在寫(xiě)的時(shí)候用Handler是因?yàn)檫@個(gè)不用去特意講解和引入其他庫(kù),讓讀者關(guān)注點(diǎn)集中在講解的知識(shí)點(diǎn)上。
#不想引用第三方庫(kù)應(yīng)該怎么做
很多人又不想引用第三方庫(kù)又想讓代碼看起來(lái)簡(jiǎn)潔易懂,這時(shí)候就要想辦法了,比如將需要在UI線(xiàn)程執(zhí)行的代碼塊封裝成方法,這樣不僅在看代碼的時(shí)候直接點(diǎn)擊進(jìn)入方法還可以提高代碼的復(fù)用性。然后在需要執(zhí)行方法的地方調(diào)用
handler.post(new Runnable(xxx()));//這里xxx()就是封裝好的方法
{(-_-)}那些說(shuō)handler.post(Runnable)這樣是post一個(gè)線(xiàn)程的,我就原諒下你的無(wú)知,感覺(jué)點(diǎn)進(jìn)去看下具體實(shí)現(xiàn)吧?。。。?!