Android拼接實現(xiàn)動態(tài)對象方法詳解
1. 前言
我們往往有些配置文件,當(dāng)項目大的時候,一些配置文件或者一些判斷邏輯就會變得復(fù)雜,會出現(xiàn)很多判斷語句,我在想,能不能通過前綴拼接動態(tài)參數(shù)并且借助反射等方式去消除一些判斷,讓這些判斷的地方去實現(xiàn)動態(tài)。
當(dāng)前只是有個想法,但是這個操作又沒有風(fēng)險,對性能影響大不大,會不會在使用中出現(xiàn)什么問題,還不得而知,下面就用一些Demo來描述一下這個方案。
這個思路的規(guī)則就是:默認(rèn)前綴拼接動態(tài)參數(shù)獲取對象,動態(tài)參數(shù)可以是從后臺獲取,可以是用文件中獲取,可以是從系統(tǒng)參數(shù)獲取,等等,任何你能想到的地方,這個根據(jù)自己的場景去涉及從何獲取。
2. 動態(tài)選密鑰
舉例的場景不一定好,但是應(yīng)該能看出這個方案的使用方式。
假如我們有做跨端的對稱加密,然后希望密鑰有幾套,不固定只有一套,然后要動態(tài)去選擇密鑰,當(dāng)然這個動態(tài)的條件要簡單,不然也只能if-else去寫了。假如我有10套密鑰,我根據(jù)當(dāng)前的時間戳的最后一位,去選擇使用哪套
假設(shè)這些公鑰
public class KeyLibs { public static final String KEY0 = "0000000000000000"; public static final String KEY1 = "1111111111111111"; public static final String KEY2 = "2222222222222222"; public static final String KEY3 = "3333333333333333"; public static final String KEY4 = "4444444444444444"; public static final String KEY5 = "5555555555555555"; public static final String KEY6 = "6666666666666666"; public static final String KEY7 = "7777777777777777"; public static final String KEY8 = "8888888888888888"; public static final String KEY9 = "9999999999999999"; }
如果我要用if-else去寫
String key; int type = (int) ((System.currentTimeMillis()/1000) % 10); if (type == 0){ key = KeyLibs.KEY0; }else if (){......} ...... else if (type == 9){ key = KeyLibs.KEY9; }
這樣寫就很讓人不舒服,但是如果我們用反射
try { long time = System.currentTimeMillis()/1000; Log.v("mmp", "獲取到的時間:" + time); Class cls = Class.forName("com.kylin.demo.KeyLibs"); Field fields = cls.getDeclaredField("KEY" + (time % 10)); fields.setAccessible(true); String result = (String) fields.get(null); Log.v("mmp", "獲取到的key:" + result); } catch (Exception e) { e.printStackTrace(); }
可以看看結(jié)果
這里的"KEY" + (time % 10)就是拼接操作
這樣據(jù)這個例子好像又感覺不要太好,在這個基礎(chǔ)上我們變一變。假如我們有很多套域名,根據(jù)一個參數(shù)的值去判斷去用什么域名。
根據(jù)一個參數(shù)的值去判斷去用什么域名,這個參數(shù)可以是后臺返回一個string字符串,可以是寫在文件中(比如利用v1簽名的漏洞的參數(shù)),也可以是其它方式。總之需要只根據(jù)這個參數(shù)的值去判斷使用哪個域名 ,那我們可以這樣做
先寫下域名常量
public class KeyLibs { public static final String URL_SHUAI = "www.shuai.com"; public static final String URL_ZHENDESHUAI = "www.zhendeshuai.com"; public static final String URL_SHIFENSHUAI = "www.shifenshuai.com"; public static final String URL_QUESHISHUAI = "www.queshishuai.com"; }
然后通過反射去獲取
try { String type = ....... Class cls = Class.forName("com.kylin.demo.KeyLibs"); // toUpperCase 是轉(zhuǎn)大寫 Field fields = cls.getDeclaredField("URL_" + toUpperCase(type)); fields.setAccessible(true); String result = (String) fields.get(null); } catch (Exception e) { e.printStackTrace(); }
假如你的type拿到的是shifenshuai,那這里拿到的域名就是URL_SHIFENSHUAI。那有個朋友就說了,為什么不動態(tài)返回這個域名呢,我這不是舉例嘛,沒想到什么比較好的例子,大概能看懂這個意思就行。
這里的"URL_" + toUpperCase(type)就是拼接操作
3. 換膚上的使用
假如我要使用換膚,我可以這樣定規(guī)則:我的皮膚資源ID的名稱是原資源的名稱加上下劃線加上皮膚名
比如我的這一套皮膚的皮膚名是"plugin",我的原皮膚中有個圖片kylin_close,那我的這個圖片在這套皮膚中的名字就叫kylin_close_plugin
PS:我這里只是舉個例子,一般皮膚資源不會直接這樣和原資源放在一起,要么動態(tài)皮膚放在插件中,要么靜態(tài)皮膚放在單獨一個文件用gradle去控制資源合并
那我要做的就是當(dāng)我從任何地方接收到這個皮膚名之后,我把原皮膚換成新的皮膚。Resources的getIdentifier能根據(jù)名稱找到皮膚,但我不想通過名稱,我想通過資源,這樣也方便我查看資源,那我可以這樣寫 (代碼直接在這寫,沒經(jīng)過驗證,如果拿去用有問題,可自行調(diào)整)
public int getPluginId(int id){ String name = "plugin"; // todo 動態(tài)獲取的參數(shù) String rName = getResources().getResourceName(id); rName = rName + "_" + name; // todo 這里我寫死是drawable,顯示可以根據(jù)TypeId去判斷是什么 int result = getResources().getIdentifier(rName, "drawable", getPackageName());; if (result == -1){ result = id; //找不到資源的情況下用會原資源 } return result; }
在調(diào)用的地方
imageView.setImageResource(getPluginId(R.drawable.kylin_close));
這里的rName = rName + "_" + name就是拼接操作。
先解讀一下這段代碼,因為也算是不完整的代碼。name就是我們獲取的動態(tài)參數(shù),上面也說了,這個參數(shù)是可以從后臺反,可以從本地文件拿,可以從你自己設(shè)計的任何一個地方拿到。然后getResources().getResourceName就是根據(jù)傳進來的資源ID拿到資源名稱,然后rName = rName + "_" + name拼接操作,就是得到我們皮膚的資源名稱,再用getIdentifier方法通過資源名稱拿到資源ID,最后判斷如果拿不到資源ID的話,就返回原資源ID。 然后這里有個地方我沒寫,就是你可以通過資源ID去判斷資源的類型(我這里寫死drawable),其實這個可以根據(jù)id去判斷,我們都知道ID的組成是有規(guī)則的,分為PackageId、TypeId、EntryId這些,我們可以進行拆解判斷TypeId就知道是什么資源了,這里我就不演示了,相信大家能理解。
好,那這么做的好處是什么,這么做其實有個好處就是如果你的某個資源要新皮膚,你直接給新皮膚的資源按約定格式去命名就行,這樣就不用去改代碼。
4. 總結(jié)
我這里其實感覺例子列舉得不是很好,但是主要是想表達,通過自己去約定一套規(guī)則,通過前綴拼接動態(tài)參數(shù)的方式去消除一些非必要的判斷語句,并且在一定程度上能提高擴展性。但相對的也有缺點,比如換膚那個例子,我先通過ID拿到名稱,再通過名稱拿到目標(biāo)ID,就其實多走了兩步,但是這個對性能的影響有多少,這就需要具體去取舍了。因為我是一想到就寫出來,所以可能有些地方?jīng)]考慮周全。
以上就是Android拼接實現(xiàn)動態(tài)對象方法詳解的詳細(xì)內(nèi)容,更多關(guān)于Android拼接動態(tài)對象的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android Mouse實現(xiàn)過程詳細(xì)筆記
鼠標(biāo)的實現(xiàn)有兩個步驟,一個是所有層上面的一個圖標(biāo),還有一個就是事件控制2013-09-09Android Jetpack庫剖析之Lifecycle組件篇
本章也是帶來了Jetpack中我認(rèn)為最重要的架構(gòu)組件Lifecycle的原理探索,至于為什么覺得它是最重要是因為像ViewModel,LiveData這些組件也依賴于Lifecycle來感知宿主的生命周期,那么本章我們帶著幾個問題來探索一下這個組件2022-07-0730分鐘搞清楚Android Touch事件分發(fā)機制
30分鐘搞清楚Android Touch事件分發(fā)機制,Touch事件分發(fā)中只有兩個主角:ViewGroup和View,想要深入學(xué)習(xí)的朋友可以參考本文2016-03-03Android實戰(zhàn)教程第四十篇之Chronometer實現(xiàn)倒計時
這篇文章主要介紹了Android實戰(zhàn)教程第四十篇之Chronometer實現(xiàn)倒計時,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11Android學(xué)習(xí)小結(jié)之獲取被啟動的Activity傳回的數(shù)據(jù)
這篇文章主要介紹了獲取被啟動的Activity傳回的數(shù)據(jù),非常不錯,介紹的非常詳細(xì),需要的朋友可以參考下2016-08-08Kotlin 封裝萬能SharedPreferences存取任何類型詳解
這篇文章主要介紹了Kotlin 封裝萬能SharedPreferences存取任何類型詳解的相關(guān)資料,需要的朋友可以參考下2017-05-05Android Broadcast原理分析之registerReceiver詳解
這篇文章主要介紹了Android Broadcast原理分析之registerReceiver詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-08-08Android Studio連接MySql實現(xiàn)登錄注冊(附源代碼)
登錄注冊是常用的一個功能,正好今天用android studio 做一個類似于這樣的登錄軟件,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05