基于对Retrofit的源码的理解,实现Retrofit调用的模式的activity之间的跳转

Retrofit实现的巧妙,以及对动态代理、适配模式和泛型的运用真是让人佩服至极,通过动态代理以及适配让一个带有注解的普通的接口转换成一个HttpRequest请求并使用OkHttpCall发送,真是太赞了,今天实现了一个简单retrofit方式的activity之间的跳转。一个小demo,分享一下。


首先,我们要定义一下注解:

//此注解是用来标注,跳转到的类是哪个模块的

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Path {
    String value();
}
//此注解是描述具体跳转到哪个类的
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Activity {
    Class value();
}

//此注解描述,要传递的参数的key值
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Parameter {
    String value();
}
接下来就是一个Service的接口,跟Retrofit的HttpService完全一样
public interface RouterService {
    //要跳转到OtherActivity这个页面,且该页面是在主模块中实现,并且带para1和para2两个String型参数过去
    @Path("main")
    @Activity(OtherActivity.class)
    public Intent gotoOtherActivity(Context context,@Parameter("para1") String para1, @Parameter("para2") String para2);
}
接口定义就完成了,接下来就是最核心东西,将这个接口翻译成Intent对象并返回
public final class RouterUtil {


    private static final Charset UTF_8 = Charset.forName("UTF-8");

    public <T> T create(final Class<T> service){
	//使用动态代理的方式返回泛型T对象,且在InvocationHandler类中将方法转换成intent并返回
        return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[]{service}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Intent intent = new Intent();
                Class toClz = null;
		//这里并没有出Path这个注解,因为是demo,还没有用到,这里只处理了Activity注解
                Activity actAnnotation = method.getAnnotation(Activity.class);
                if(actAnnotation != null){
		    //获取到要跳转到页面的class文件
                    toClz = actAnnotation.value();
                }
		//获取到该方法的所有的参数类型
                Class[] paraTypes = method.getParameterTypes();
                for (int i = 0; i < paraTypes.length; i++) {
                    Class para = paraTypes[i];
                    if(para == Context.class){
                        intent.setClass((Context) args[i],toClz);
                    }
                    if(para == String.class){
			//获取每个参数的注解,并捕捉到Parameter注解,因为是demo,所以直接以
			//anno[0]的方式获取了
                        Annotation[] anno = method.getParameterAnnotations()[i];                        if(anno[0] instanceof Parameter){
			    //获取到了((Parameter)anno[0]).value()为key,(String)args[i]为参数值
                            intent.putExtra(((Parameter)anno[0]).value(),(String)args[i]);
                        }

                    }
                }
                return intent;
            }
        });
    }

    public static final class Builder{
        public Builder(){

        }
        public RouterUtil build(){
            return new RouterUtil();
        }
    }
}
动态代理中invoke方法里完成了普通接口-Intent对象的转换,接下来是调用,
//返回其实不是RouterService接口的对象,而是一个代理接口的对象
RouterService routerService = new RouterUtil.Builder().build().create(RouterService.class);
Intent intent = routerService.gotoOtherActivity(MainActivity.this,"param1","param2")
startActivity(intent);
有没有疑问说,routerService.gotoOtherActivity简单的调用一下怎么就转换成了intent对象了呢,这仅仅是一个未被实现的接口里的方法而已啊。这就是动态代理的作用,当我们使用
RouterService routerService = new RouterUtil.Builder().build().create(RouterService.class);
这行代码创建的routerService这个对象,它已经不是原来的RouterService的对象,而是一个代理的对象,当执行其方法的时候,都要
执行invoke方法里面的代码,才会真正会转换成Inetnt对象。
这样跳转可以隐藏真正的目标Activity。



 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Retrofit2是一个用于在Android和Java中进行网络请求的库。要调用接口,首先需要进行以下步骤: 1. 添加依赖:在项目的build.gradle文件中添加以下依赖项: ```groovy implementation 'com.squareup.retrofit2:retrofit:2.x.x' ``` 2. 创建接口定义:创建一个Java接口,定义你想要调用的API方法。例如: ```java public interface ApiService { @GET("endpoint") Call<ResponseBody> getData(); } ``` 3. 创建Retrofit实例:使用Retrofit.Builder创建一个Retrofit实例,并设置相关配置。例如: ```java Retrofit retrofit = new Retrofit.Builder() .baseUrl("https://api.example.com/") .addConverterFactory(GsonConverterFactory.create()) .build(); ``` 在上述代码中,baseUrl()指定API的基本URL,addConverterFactory()用于指定数据转换器。 4. 创建API实例:使用Retrofit.create()方法创建一个API实例。例如: ```java ApiService apiService = retrofit.create(ApiService.class); ``` 5. 调用接口方法:使用创建的API实例调用接口方法,并处理响应。例如: ```java Call<ResponseBody> call = apiService.getData(); call.enqueue(new Callback<ResponseBody>() { @Override public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) { if (response.isSuccessful()) { // 处理成功响应 } else { // 处理错误响应 } } @Override public void onFailure(Call<ResponseBody> call, Throwable t) { // 处理网络请求失败 } }); ``` 以上是基本的Retrofit2调用接口的步骤。你可以根据接口定义自定义请求参数、请求体、请求头等。同时,你还可以使用注解来对请求进行更详细的配置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值