代理設(shè)計模式 - 實現(xiàn) Retrofit 的 create

相信大家都很熟悉 Retrofit 了锦援,這篇文章不會講使用,如果不是特別熟悉 Retrofit 的使用剥悟,可以去看看其他的一些文章灵寺。如果實在不想看那也沒關(guān)系,因為今天的主要內(nèi)容并不是 Retrofit 懦胞,而是代理設(shè)計模式替久。只是在講解的過程中順便講一下代理設(shè)計模式的運用。先來看看開發(fā)中哪些地方可以用到:

  • Android 插件化架構(gòu)之繞過 AndroidManifest 檢測(動態(tài)代理)
  • Android 數(shù)據(jù)庫實現(xiàn)數(shù)據(jù)的懶加載(靜態(tài)代理)
  • Android MVP 架構(gòu)設(shè)計(靜態(tài)代理和動態(tài)代理)
  • Android Xutils 實現(xiàn) View 事件注入(動態(tài)代理)
  • Android Retrofit 的 create 創(chuàng)建接口對象 (動態(tài)代理)
  • Android Framework 層的 AMS
  • Android Framework 層的 Binder 驅(qū)動

1.代理設(shè)計模式介紹


1.1 模式定義

為其他對象提供一種代理躏尉,以控制對這個對象的訪問,分為靜態(tài)代理和動態(tài)代理后众。說到代理我們其實都明白胀糜,日常的生活中也并不少見,比如每天吃飯趕進度蒂誉,我們需要叫人給我們帶飯教藻;我們?nèi)ャy行辦張卡,有銀行的業(yè)務(wù)員幫我們辦卡等等右锨,編程的思想其實有的時候和生活差不多括堤。

1.2 代理模式的簡單事例

設(shè)計模式是一種思想,經(jīng)常在講定義的時候的確又很枯燥绍移,但是無論哪一門語言我們又必須都得學悄窃,如 iOS,Android蹂窖,Unity3D 都離不開這些轧抗。既然是個簡單的事例,我們就以這個銀行辦卡來說吧:

/**
 * description: 靜態(tài)代理設(shè)計模式 - 目標接口
 * author: Darren on 2017/10/11 12:50
 * email: 240336124@qq.com
 * version: 1.0
 */
public interface IBank {
    void applyBank();
}
/**
 * description: 靜態(tài)代理設(shè)計模式 - 被代理對象
 * author: Darren on 2017/10/11 12:51
 * email: 240336124@qq.com
 * version: 1.0
 */
public class Man implements IBank{
    @Override
    public void applyBank() {
        System.out.println("辦卡");
    }
}
/**
 * description: 靜態(tài)代理設(shè)計模式 - 代理對象
 * author: Darren on 2017/10/11 12:52
 * email: 240336124@qq.com
 * version: 1.0
 */
public class BankSalesman implements IBank{
    private IBank bank;

    public BankSalesman(IBank bank){
        this.bank = bank;
    }

    @Override
    public void applyBank() {
        System.out.println("數(shù)據(jù)統(tǒng)計");
        bank.applyBank();
        System.out.println("完畢");
    }
}
/**
 * description:代理設(shè)計模式 - 測試
 * author: Darren on 2017/10/11 12:54
 * email: 240336124@qq.com
 * version: 1.0
 */
public class Client {
    public static void main(String[] args){
        Man man = new Man();
        BankSalesman salesman = new BankSalesman(man);
        salesman.applyBank();
    }
}

這就是我們的靜態(tài)代理設(shè)計模式瞬测,運行結(jié)果很簡單這里就不給出了横媚,其實代理設(shè)計模式也很簡單,其主要還是一種委托機制月趟,真實對象將方法委托給代理對象灯蝴,所以這里設(shè)計模式又有另一種說法,又叫委托模式孝宗,相信我們都不難理解穷躁。但是這里我們又要拋出一個問題,比如我現(xiàn)在要新增一個掛失我又得怎么寫呢碳褒?這里我就不寫了折砸,接下來我們看下動態(tài)代理模式看疗。

1.3 動態(tài)代理

與靜態(tài)代理不同的是,動態(tài)代理通過反射在運行時生成代理對象睦授,Java也已經(jīng)給我們提供了一個便捷的動態(tài)代理接口 InvocationHandler两芳,源碼最終調(diào)用的是 Native 方法去生成我們的代理對象,其實在內(nèi)涵段子項目中去枷,已經(jīng)帶大家看過動態(tài)代理的源碼了怖辆。這里就不做太多介紹,看下上面的事例采用動態(tài)代理删顶,又有怎樣的改變:

/**
 * description: 動態(tài)代理設(shè)計模式 - InvocationHandler
 * author: Darren on 2017/10/11 13:59
 * email: 240336124@qq.com
 * version: 1.0
 */
public class DynamicBankProxy implements InvocationHandler{
    private Object object;

    public DynamicBankProxy(Object object){
        this.object = object;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("數(shù)據(jù)統(tǒng)計");
        Object result = method.invoke(object,args);
        System.out.println("完畢");
        return result;
    }
}
/**
 * description:代理設(shè)計模式 - 測試
 * author: Darren on 2017/10/11 12:54
 * email: 240336124@qq.com
 * version: 1.0
 */
public class Client {
    public static void main(String[] args) {
        Man man = new Man();
        IBank bank = (IBank) Proxy.newProxyInstance(IBank.class.getClassLoader(),
                new Class<?>[]{IBank.class}, new DynamicBankProxy(man));
        bank.applyBank();
    }
}

2.實現(xiàn) Retrofit 的 create

對于 Retrofit 這里不會講得太詳細竖螃,只會單獨講 create,后面會有 3-4 次的視頻直播逗余,具體的大綱可以看下 Android進階之旅 - 系統(tǒng)架構(gòu)篇特咆。這里不也不結(jié)合 RXjava ,我們來看下 Retrofit 最普通的寫法:

public class RetrofitSimple {
    private static DataServiceInterface serviceInterface;

    static {
        Retrofit.Builder retrofitBuilder = new Retrofit.Builder().baseUrl("https://api.xxxxx.com/")
                .addConverterFactory(GsonConverterFactory.create());
        serviceInterface = retrofitBuilder.build().create(DataServiceInterface.class);
    }

    public static DataServiceInterface getService(){
        return serviceInterface;
    }
}
Call<Result> call = RetrofitSimple.getService().testMethod();

call.enqueue(new Callback<Result>() {
    @Override
    public void onResponse(Call<Result> call, Response<Result> response) {
        Result result = response.body();
        Log.e("TAG","result = "+result.code);
    }

    @Override
    public void onFailure(Call<Result> call, Throwable t) {
         
    }
});

這是沒有做任何封裝的录粱,相信用過的都能看懂腻格,如果都沒用過 Retrofit ,希望我們還是能多花寫時間去了解一下啥繁,因為到后面我們要自己去實現(xiàn) Retrofit 的功能菜职,也包括去修改它的源碼等等。上面代碼最主要的核心在于 Retrofit.create() 我們傳遞過去的是一個接口的 class 給我們返回的是一個對象旗闽,而這個對象其實就我們的代理對象酬核,接下來我們簡單的實現(xiàn)一下,我們把部分代碼先寫一下思路适室,后面我會帶著大家一個一個去補上的嫡意。

public class DarrenRetrofit {
    public <T> T create(Class<T> service) {
        return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[]{service}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 1. 先做一下打印,獲取方法名和參數(shù)
                /*Log.e("Method", method.getName());
                for (Object arg : args) {
                    Log.e("ARGS", arg+"");
                }*/

                // 2.解析方法注解參數(shù)到底是什么提交(Post) - 注解的不太懂請看前面的文章
                Annotation[] methodAnnotations = method.getAnnotations();
                for (Annotation methodAnnotation : methodAnnotations) {
                    // Post Get Multipart FormUrlEncoded 等等
                }

                // 3.解析 args 參數(shù)的注解

                // 4.封裝成 Call 或者其他對象返回

                return null;
            }
        });
    }
}
DarrenRetrofit retrofit = new DarrenRetrofit();
DataServiceInterface service = retrofit.create(DataServiceInterface.class);
Call<Result> call = service.testMethod();
call.enqueue(new Callback<Result>() {
    @Override
    public void onResponse(Call<Result> call, Response<Result> response) {
        Result result = response.body();
        Log.e("TAG","result = "+result.code);
    }

    @Override
    public void onFailure(Call<Result> call, Throwable t) {
        t.printStackTrace();
    }
});

所有分享大綱:Android進階之旅 - 系統(tǒng)架構(gòu)篇

視頻講解地址:http://pan.baidu.com/s/1gfep8oN

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末亭病,一起剝皮案震驚了整個濱河市鹅很,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌罪帖,老刑警劉巖促煮,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異整袁,居然都是意外死亡菠齿,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進店門坐昙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绳匀,“玉大人,你說我怎么就攤上這事〖部茫” “怎么了戈钢?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長是尔。 經(jīng)常有香客問我殉了,道長,這世上最難降的妖魔是什么拟枚? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任薪铜,我火速辦了婚禮,結(jié)果婚禮上恩溅,老公的妹妹穿的比我還像新娘隔箍。我一直安慰自己,他們只是感情好脚乡,可當我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布蜒滩。 她就那樣靜靜地躺著,像睡著了一般每窖。 火紅的嫁衣襯著肌膚如雪帮掉。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天窒典,我揣著相機與錄音,去河邊找鬼稽莉。 笑死瀑志,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的污秆。 我是一名探鬼主播劈猪,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼良拼!你這毒婦竟也來了战得?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤庸推,失蹤者是張志新(化名)和其女友劉穎常侦,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贬媒,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡聋亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了际乘。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片坡倔。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出罪塔,到底是詐尸還是另有隱情投蝉,我是刑警寧澤,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布征堪,位于F島的核電站瘩缆,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏请契。R本人自食惡果不足惜咳榜,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望爽锥。 院中可真熱鬧涌韩,春花似錦、人聲如沸氯夷。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腮考。三九已至雇毫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間踩蔚,已是汗流浹背棚放。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留馅闽,地道東北人飘蚯。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓,卻偏偏與公主長得像福也,于是被迫代替她去往敵國和親局骤。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,876評論 2 361

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,331評論 25 707
  • Retrofit是squareup公司的開源力作,和同屬squareup公司開源的OkHttp现喳,一個負責網(wǎng)絡(luò)調(diào)度凯傲,...
    藍灰_q閱讀 41,634評論 23 281
  • 念戀不舍 念起最初的相遇 不過長廊一角,幽夢一場 戀上少年的青澀 也不過目光相接拿穴,猛然心動 遇見的剛剛好 卻是命運...
    淚都掉了閱讀 335評論 0 0
  • 這幾天傍晚到附近的學校跑步時泣洞,發(fā)現(xiàn)學生越來越多起來,開學了默色。 ——“開學了球凰,你給孩子喝對奶了嗎狮腿?” ——“不,開學...
    Bevon英語翻譯閱讀 667評論 9 7
  • 春呕诉,漸入佳境缘厢,吾自京輾轉(zhuǎn)而返鄉(xiāng)。時值清明時節(jié)甩挫,外春雨寒贴硫,歲寒而煥萬物而復蘇,參天巨木雖朽而護百兒孫伊者,感明祖母之恩英遭,...
    丁丁小午閱讀 294評論 2 1