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