Skip to content

Instantly share code, notes, and snippets.

@kkmike999
Last active February 14, 2019 02:48
Show Gist options
  • Save kkmike999/df65b1c2f730d16a20f61f7074e4e309 to your computer and use it in GitHub Desktop.
Save kkmike999/df65b1c2f730d16a20f61f7074e4e309 to your computer and use it in GitHub Desktop.
悦跑圈Api代理用法

Http api使用方法

示例代码+解说:

ps.代码仅用于演示,与实际代码出入

json数据

{
    "ret": "0",
    "msg": "成功",
    "data": [
        {
            "shoe_id": "128",
            "shoe_name": "阿迪达斯"
        }
    ]
}

Api接口

public interface ShoeApi{
	/**
     * 某品牌 跑鞋列表
     *
     * @param brand_id 品牌id
     * @return
     */
    @POST("brand-shoe-list")
    Observable<List<Shoe>> brandShoeList(@Field("brand_id") int brand_id);
    
}

被代理的接口,接口规则参照: Retrofit2风格 + RxJavaCallAdapter 。

  • @POST(url),url表示请求路径,但不包含域名。@POST("brand-shoe-list")实际上是请求 http://xxx.com/brand-shoe-list
  • @Field(name)int valuename指参数名,value参数值。
  • Observable<T>T是json实例化后的对象

其他注解

  • @Data(name), json数据中"data"字段存放可实例化数据,但也可能是其他名称。这时,通过@Data(name)可指定字段名,name默认"data"
  • @String(name), 由于技术原因,将_json中某字段实例化成String,需要添加此注释。name作用跟@Data(name)一样,但@String(name)默认"msg"
  • @AllResponse, 解释整个json数据。
示例1
@String("msg")
Observable<String> join();

可解释下面的"msg"

{
	"ret":0,
	"msg":"成功"
}
示例2
@Data("user")
Observable<User> loadUser(@Field("did")int uid);

可解释下面"user"字段

{
	"user":{...}
}
示例3
@AllReponse
Observable<User> loadUser(...);
{
	"uid":1,
	"name":"小白"
}

Retrofit & RepositoryProxy

/**
 * 跑鞋Retrofit
 */
public class ShoeRetrofit extends BaseRetrofit {

    @Override
    public <T> T createApi(Class<T> clazz) {
        RepositoryProxy proxy = getProxyBuilder().baseurl("http://wear.api.thejoyrun.com/") // 正式服务器域名
                                                    .testurl("http://wear.api.test.thejoyrun.com/") // 测试服务器域名
                                                    .setTestServer(isTestApi())// 是否测试服务器,默认false
                                                    .gson(GsonHelper.getGson())
                                                    .build();

        return proxy.create(clazz);
    }
}

(自己YY出来的类,并不是square那个Retrofit ^_^)

Retrofit其实并没实则作用,RepositoryProxy才是重点。RepositoryProxy设置 正式/测试服务器 域名(一定要有"http://"前序)。GsonHelper.getGson()是对Gson进行了配置,json字段值是"",也可正常解析成int

注意,不要自己写构造函数,会对单元测试造成影响。


Presenter

public interface ShoePresenter extends Presenter {
    /**
     * 获取品牌跑鞋列表
     */
    void loadShoeList(int brand_id);
}
/**
 * 跑鞋Presenter
 */
public class ShoePresenterImpl implements ShoePresenter {

    ShoeApi shoeApi;// 跑鞋api类
    ShoeView shoeView;// 跑鞋View

	// 在构造函数创建的实例,也可以用dagger注入
    public ShoePresenterImpl(ShoeView shoeView) {
        this.shoeView = shoeView;

        this.shoeApi = new ShoeRetrofit().create(ShoeApi.class);// 创建api代理
    }

    @Override
    public void loadShoeList(int brand_id) {
		// 底层代码默认api运行在io线程,不需要再写subscribeOn(Schedulers.io())
		
		shoeApi.brandShoeList(brand_id)
               .observeOn(AndroidSchedulers.mainThread())
               .subscribe(new SimpleSubscriber<List<Shoe>>() {

                   @Override
                   public void onNext(List<Shoe> shoes) {
                       shoeView.onShoesLoaded(shoes);// 回调数据给View
                   }
               });
    }
}

相信你能看懂的!


依赖关系

image


单元测试

TestCase

public class ShoeApiTest extends ApiCase {

//  @Api(uid = 4, sid = "", isTestApi = true, value = ShoeRetrofit.class, useLocalTime = false)
    @MockApi
    ShoeApi shoeApi;

    @Test
    public void testBrandShoeList() throws Exception {
        mockRetrofit.addLocalPath("brand-shoe-list", "shoe/shoe_list.json");

        List<Shoe> list = shoeApi.brandShoeList(11, 1, 10)
                                 .toBlocking()
                                 .first();

        Shoe shoe = list.get(0);

        verifyShoe(shoe);
    }

	private void verifyShoe(Shoe shoe) {
        Assert.assertEquals(shoe.shoe_id, 128);
        Assert.assertEquals(shoe.shoe_name, "阿迪达斯");
    }
}

shoe_list.json

{
    "ret": "0",
    "msg": "成功",
    "data": [
        {
            "shoe_id": "128",
            "shoe_name": "阿迪达斯"
        }
    ]
}

ApiCase

TestCase继承ApiCase,才可以使用@MockApi、@Api,还有其他屌屌的功能。

@MockApi

对Api接口注释,在TestCase.setUp()之前,会自动用MockRetrofit代理api。与new MockRetrofit().create(ShoeApi.class)等效。

@Api

可让Api接口请求真实网络。一个Api接口,不能同时使用@MockApi@Api

@Api参数:

  • uid
  • sid 登陆信息sid
  • isTestApi 是否请求测试服务器,false则请求正式服务器 (默认true)
  • value 代理Api接口的Retrofit
  • userLocalTime 请求服务器时,会进行url签名,真机上是获取服务器lasttime,if true,会再请求服务器获取lasttime,if false,直接用本地时间(默认false)

MockRetrofit

模拟网络请求,返回mock数据。

  • addLocalPath(url,path), url需与api方法注释@POST(url)中url一致, path指本地mock数据路径(放在src/test/assets/目录下)
  • addSuccess(path)addFail(path),其实与addLocalPath(...)一样,只是path指向默认的success.sonfail.json

Observable

RxJava的Observable。

  • toBlocking(),将Observable转成BlockingObservable,强制同步处理;
  • first(),返回第一个处理的数据
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment