美文网首页
彻底明白Android设计模式—(动态)代理模式

彻底明白Android设计模式—(动态)代理模式

作者: 积木zz | 来源:发表于2020-04-22 09:46 被阅读0次

    代理模式其实就是提供了对目标对象的另外的访问方式,通过代理对象访问目标对象
    为啥要这么麻烦呢!!!其实是为了不去修改原有的代码,通过代理也可以访问这个对象而且可以进行扩展

    这种模式有什么应用场景呢?先说下生活中对应的场景,明星接通告
    一般商家要找明星做活动,是要先找到他的经纪人,然后经纪人去负责一些琐碎的或者运营方面的事情,而明星只需要做具体的活动相关事情就可以了。这里经纪人的作用就是作为了一个代理。

    静态代理

    首先是静态代理,上代码

     /**
         * 首先声明一个接口,用于工作的接口
         */
        public interface IStarDao {
            void dowork();
        }
    
        /**
         * 明星工作类
         * 主要为演戏
         */
        public class SuperStarDao implements IStarDao {
    
            @Override
            public void dowork() {
                //演戏工作
            }
        }
    
        /**
         * 经纪人代理类
         * 主要是负责接活,并且安排明星工作,以及后续宣传工作
         */
        public class StarbrokerDaoProxy implements IStarDao {
    
            private IStarDao starDao;
    
            public StarbrokerDaoProxy(IStarDao starDao) {
                this.starDao = starDao;
            }
    
            @Override
            public void dowork() {
                /*--接活--*/
                starDao.dowork();//明星工作
                /*--宣传工作--*/
            }
        }
    

    ok,至此明星和经纪人已经创建完毕,接下来就是怎么去操作,首先找到具体的明星,然后找到对应的经纪人,也就是代理类,从而完成所有工作

        public void main() {
            SuperStarDao starDao = new SuperStarDao();
            StarbrokerDaoProxy proxy = new StarbrokerDaoProxy(starDao);
            proxy.dowork();
        }
    

    动态代理

    动态代理的特点是不需要提前创建代理对象,而是利用反射机制在运行时创建代理类,从而动态实现代理功能
    也就是说,这里的明星不需要具体的经纪人了。有活动的时候,可以创建一个经纪人,可以是自己,可以是家人,然后完成原本代理的一些工作,见代码

        public void main() {
            final IStarDao starDao = new SuperStarDao();
    
            IStarDao proxy = (IStarDao) Proxy.newProxyInstance(
                    starDao.getClass().getClassLoader(),
                    starDao.getClass().getInterfaces(),
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            /*--接活--*/
                            Object returnValue = method.invoke(starDao, args);//明星工作
                            /*--宣传工作--*/
                            return returnValue;
                        }
                    });
    
            proxy.dowork();
        }
    

    在Android中的应用

    Retrofit,想必大家都很熟悉,retrofit其实核心内容就是用了动态代理。

    想想retrofit是怎么工作的?在interface里面写上需要配置的请求方法,并添加一些注解
    然后创建出interface的实例,就可以直接调用方法进行网络请求了。
    看看代码:

    public interface ApiService {
        @POST(RetrofitHelper.APP_V1 + "/banner")
        Observable<BaseEntity<List<Banner>>> getBanners();
    }
     
    ApiService mService = new Retrofit.Builder().baseUrl("").build().create(ApiService.class);
    
    service.getBanners().enqueue(callback);
    
    

    我们只是写了ApiService接口和接口下面的getBanners方法,然后就可以进行网络请求。
    所以retrofit是代替我们写了网络请求的具体逻辑,也就是完成了代理的这样一个作用。

    具体怎么代理的呢?
    奥秘主要就在这个.create(ApiService.class)方法里面,看看源码:

      public <T> T create(final Class<T> service) {
        return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
            new InvocationHandler() {
              private final Platform platform = Platform.get();
              @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
                  throws Throwable {
                ServiceMethod<Object, Object> serviceMethod =
                    (ServiceMethod<Object, Object>) loadServiceMethod(method);
                OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
                return serviceMethod.callAdapter.adapt(okHttpCall);
              }
            });
      }
    

    看到这个newProxyInstance方法了吧,这就是创建动态代理类的方法。
    invoke方法里面就是具体去拆解 接口里面方法的一些参数,然后完成网络请求的整个过程了,也就是代理帮你做的一些事情。

    这里顺便就简单说下这些源码干了什么事,也方便大家自己研究源码

    • loadServiceMethod 主要是读取接口里面每个方法的注解啊,参数啊等等
    • new OkHttpCall 主要是调用okhttp的一些方法,发起一些网络请求
    • adapt(okHttpCall) 主要是转换OkHttpCall对象,并且切换到主线程

    你的一个👍,就是我分享的动力❤️。

    相关文章

      网友评论

          本文标题:彻底明白Android设计模式—(动态)代理模式

          本文链接:https://www.haomeiwen.com/subject/rrzyihtx.html