相信大家都很熟悉 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();
}
});