淺談android ioc控制反轉(zhuǎn)一(控件篇)

1、ioc介紹

控制反轉(zhuǎn)(Inversion of Control漾稀,英文縮寫為IoC)把創(chuàng)建對象的權(quán)利交給框架,是框架的重要特征瓮顽,并非面向?qū)ο缶幊?/a>的專用術(shù)語。它包括依賴注入(Dependency Injection缕贡,簡稱DI)和依賴查找(Dependency Lookup)晾咪。

到底啥意思呢???

原本我們在一個類里面用到很多成員變量,都是靠new出來塞赂,然后去訪問昼蛀。

如果咋們運用ioc那就不需要new了,你配置個xml文件仇哆,里面寫明類名夫植,有哪些成員變量,等加載這個類的時候延欠,ioc幫你new沈跨。

?說了這么多好像還沒說明白^_^,那就直接上代碼~~~~~~

2隅俘、框架

開發(fā)android的小伙伴應(yīng)該對 butterknife框架應(yīng)該不陌生吧笤喳。筆者對此框架的評價就是:好用,好用蒙畴,很好用!

目標:

@SetContentView(R.layout.activity_main)
public class MainActivityextends AppCompatActivity {
???????? @ViewBind(R.id.tv)
???????? private TextViewtv;??
???????? @Override
???????? protected void onCreate(Bundle savedInstanceState) {
???????????? super.onCreate(savedInstanceState);? ? ??
???????????? ViewInjectUtils.inject(this);? ? ?
???????????? tv.setOnClickListener(new View.OnClickListener()
??? ? ? ? ? {
???????????????? @Override? ? ? ? ??
????????????????? public void onClick(View v) {??
?????????????????????? Toast.makeText(MainActivity.this,"我被點擊了",Toast.LENGTH_LONG).show();? ? ? ??
??????????? }? ?
? ?? });
?? }
}

這里省去了tv控件創(chuàng)建的代碼 和 xml文件的加載呜象。其中控件創(chuàng)建時咋們最討厭的事情,一直重復(fù)findViewById蹬音。

SetContentView用于在類上使用休玩,主要標明該Activity需要使用的布局文件劫狠。
ViewBind在字段上使用独泞,主要標明該字段綁定的控件id苔埋。

3.框架實現(xiàn)

首先先來寫SetContentView和ViewBind這兩個注解類
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;
/**
*描述:
* * @author guoweiquan * @version 1.0
* @data 2018/5/14 下午2:15
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface SetContentView
{
int value();
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*描述:
* * @author guoweiquan
* @version 1.0
* @data 2018/5/14 下午2:25 */
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ViewBind{
?????? int value();
}

解釋下注解:@interface代表是注解類 ;
@Target表示該注解可以用于什么地方(ElementType系統(tǒng)枚舉類)组橄,
總共類型如下:
??????? @Target(ElementType.TYPE)//接口、類衫画、枚舉瓮栗、注解
??????? @Target(ElementType.FIELD)//字段费奸、枚舉的常量
??????? @Target(ElementType.METHOD)//方法
??????? @Target(ElementType.PARAMETER)//方法參數(shù)
??????? @Target(ElementType.CONSTRUCTOR)//構(gòu)造函數(shù)
??????? @Target(ElementType.LOCAL_VARIABLE)//局部變量
??????? @Target(ElementType.ANNOTATION_TYPE)//注解
???????? @Target(ElementType.PACKAGE) //包
???????? @Retention表示:表示需要在什么級別保存該注解信息进陡;我們這里設(shè)置為運行時.總共類型如下:
? ? ? ? ? enumRetentionPolicy {
?????????????? SOURCE,
?????????????? CLASS,
?????????????? RUNTIME
???????????? }

下面來看下viewInjectUtils的實現(xiàn):

import android.app.Activity;

import java.lang.reflect.Field;import java.lang.reflect.Method;

/**
*描述:
* * @author guoweiquan
* @version 1.0
* @data 2018/5/14 下午2:19
*/

public class ViewInjectUtils {

private static final StringSETCONTENTVIEW ="setContentView";?
private static final StringFINDVIEWBYID ="findViewById";?
public static void inject(Activity activity)??
{

?????? bindContentView(activity);? ?
? ? ?? bindViews(activity);??
}

/**? ?
? * 綁定主布局文件? ? ??
? * @param activity? ?
? */?
private static void bindContentView(Activity activity)
{? ? ?
??????? Class clazz = activity.getClass();??
??????? SetContentView contentView = clazz.getAnnotation(SetContentView.class);
?????? // 查詢類上SetContentView注解? ? ?
?????? if (contentView !=null)? ? ?
?????? {
????????? int contentViewLayoutId = contentView.value();
????????? try{? ? ? ? ? ? ?
????????????????????? Method method = clazz.getMethod(SETCONTENTVIEW, int.class);???

????????????????????? method.setAccessible(true);
???????????????????? //設(shè)置可以訪問private域? ? ? ? ? ? ??
????????????????????? method.invoke(activity, contentViewLayoutId);
???????????????? }catch (Exception e)? ? ? ? ?
???????????? {? ? ? ? ? ? ??
???????????????? e.printStackTrace();? ? ? ? ?
????????????? }? ? ?
?????????? }??
}

/**??
? * 綁定所有的控件? ? ?
? * @param activity? ?
? */?
private static void bindViews(Activity activity)??
{? ? ??
??????? Class clazz = activity.getClass();? ? ??
???????? Field[] fields = clazz.getDeclaredFields();//獲取自己聲明的各種字段缨历,包public糙麦,protected,private? ? ? ???? for (Field field : fields)? ? ?
???????? {
????????????? ViewBind viewInjectAnnotation = field.getAnnotation(ViewBind.class);? ? ? ? ?
???????????? if (viewInjectAnnotation !=null)
???????????? {
??????????????????? int viewId = viewInjectAnnotation.value();? ? ? ? ? ? ??
??????????????????? if (viewId != -1)? ? ? ? ? ? ?
??????????????????? {
???????????????????????? try{
????????????????????????????????? Method method = clazz.getMethod(FINDVIEWBYID,? int.class);
????????????????????????????????? Object view = method.invoke(activity, viewId);//找到相應(yīng)控件對象????

?????????????????????????????????? field.setAccessible(true);
?????????????????????????????????? field.set(activity, view);//給本字段賦值? ? ? ? ? ? ? ? ?
??????????????????????????????? }catch (Exception e)? ? ? ? ? ? ? ? ?
??????????????????????????????? {? ? ? ? ? ? ? ? ? ? ??
? ? ? ? ? ??????????????????????????? e.printStackTrace();? ? ? ? ? ? ? ??
?????????????????????????????????? }? ? ? ?
???????????????????????? }? ? ? ??
???????????????? }? ? ?
? ? ? ? ?? }??
??????? }
?}

在MainActivity創(chuàng)建時候inject方法被調(diào)用魄缚,其中bindContentView和bindViews這兩個方法 就是幫咋們把加載xml和創(chuàng)建控件的活給干了冶匹。

結(jié)果如下:

項目github地址:https://github.com/seaeel/AndroidIoc.git

博主技術(shù)交流群:239025382

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嚼隘,一起剝皮案震驚了整個濱河市飞蛹,隨后出現(xiàn)的幾起案子谤狡,更是在濱河造成了極大的恐慌豌汇,老刑警劉巖泄隔,帶你破解...
    沈念sama閱讀 221,695評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件佛嬉,死亡現(xiàn)場離奇詭異,居然都是意外死亡暖呕,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評論 3 399
  • 文/潘曉璐 我一進店門瓤逼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來霸旗,“玉大人戚揭,你說我怎么就攤上這事∶裆梗” “怎么了?”我有些...
    開封第一講書人閱讀 168,130評論 0 360
  • 文/不壞的土叔 我叫張陵靴姿,是天一觀的道長空猜。 經(jīng)常有香客問我恨旱,道長,這世上最難降的妖魔是什么搜贤? 我笑而不...
    開封第一講書人閱讀 59,648評論 1 297
  • 正文 為了忘掉前任仪芒,我火速辦了婚禮耕陷,結(jié)果婚禮上据沈,老公的妹妹穿的比我還像新娘。我一直安慰自己嗜诀,他們只是感情好孔祸,可當我...
    茶點故事閱讀 68,655評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拂蝎,像睡著了一般惶室。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上皇钞,一...
    開封第一講書人閱讀 52,268評論 1 309
  • 那天鹅士,我揣著相機與錄音掉盅,去河邊找鬼。 笑死趾痘,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的永票。 我是一名探鬼主播滥沫,決...
    沈念sama閱讀 40,835評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼兰绣!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起缀辩,我...
    開封第一講書人閱讀 39,740評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎瓢阴,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體荣恐,經(jīng)...
    沈念sama閱讀 46,286評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,375評論 3 340
  • 正文 我和宋清朗相戀三年旗唁,在試婚紗的時候發(fā)現(xiàn)自己被綠了检疫。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,505評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡屎媳,死狀恐怖烛谊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情嘉汰,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評論 5 350
  • 正文 年R本政府宣布双泪,位于F島的核電站焙矛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏村斟。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,873評論 3 333
  • 文/蒙蒙 一蟆盹、第九天 我趴在偏房一處隱蔽的房頂上張望邑滨。 院中可真熱鬧,春花似錦匣距、人聲如沸面哥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,357評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至外里,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間鳖链,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,466評論 1 272
  • 我被黑心中介騙來泰國打工芙委, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留狂秦,地道東北人。 一個月前我還...
    沈念sama閱讀 48,921評論 3 376
  • 正文 我出身青樓侧啼,卻偏偏與公主長得像堪簿,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子戴甩,可洞房花燭夜當晚...
    茶點故事閱讀 45,515評論 2 359

推薦閱讀更多精彩內(nèi)容