AutoNet (Android 网络框架)

AutoNet (网络框架)

AutoNet 代理了OkHttp, 处理了复杂繁琐的网络请求代码! 使Android开发网络应用更加简单,只需关注业务即可。

Git地址

1.Android版本:

Android版AutoNet

2.ios版本:

ios版AutoNet

AutoNet 技术交流群:

QQ: 141027175

Demo说明

  • app: AutoNet各个方式使用介绍
  • recommendeddemo: AutoNet推荐用法(注:Api使用了wanandroid的Api)

特色

  • 使用简单、调用方便
  • 支持了同步、异步操作
  • 支持注解、 链式
  • 支持实体类、map传值
  • 可防止内存泄漏(需继承RxFragmentActivity、或者RxFragment。并向AutoNet传入相应的生命周期)
  • 可动态添加和修改头部
  • 可对请求参数数据进行加密
  • 可自主处理返回的头部数据
  • 可自主处理返回的body数据
  • 可自定义返回数据的类型
  • 可定义固定、灵活及临时的域名、头部信息(优先级: 临时>灵活>固定。 有效性: 固定 >= 灵活 > 临时)
  • 支持网络策略(网络、本地、先本地后网络、先网络后本地)
  • 支持上传文件和下载文件
  • 可直接获得上游的Flowable, 用户自己进行操作结果。(eg: 使用zip去合并多个请求等)

gradle依赖

compile 'cn.xiaoxige:autonet-api:2.0.3'
annotationProcessor 'cn.xiaoxige:autonet-processor:2.0.3'

简易使用demo

AutoNet_Android.png

使用

1. 初始化

1.1 AutoNetConfig(配置AutoNet的基本配置)注意:改配置基本是固定,如域名、头部数据

  • 设置是否开启Stetho调试配置
  • 设置默认域名(key: default)
  • 设置多个域名
  • 设置头部参数
  • 设置Okhttp的拦截器

1.2 AutoNet的初始化操作

AutoNet.getInstance().initAutoNet(Context, AutoNetConfig);
可以链式去设置加密的回调,头部数据的回调,Body数据的回调, eg:
AutoNet.getInstance().initAutoNet(Context, AutoNetConfig)
.setEncryptionCallback(new IAutoNetEncryptionCallback() {
        @Override
        public String encryption(Long key, String encryptionContent) {
            // 可通过key去加密参数
            return encryptionContent;
        }
    }).setHeadsCallback(new IAutoNetHeadCallBack() {
        @Override
        public void head(Object flag, Headers headers) {
            // 请求返回的头部数据回调
        }
    }).setBodyCallback(new IAutoNetBodyCallBack() {
        @Override
        public boolean body(Object flag, String body) throw Exception {
            // 自己处理需要返回true
            return false;
        }
});
还可以再次设置域名和头部数据(这里的配置为灵活的, 可在任意地方修改)
AutoNet.getInstance().updateOrInsertHead(key, value);
AutoNet.getInstance().updateOrInsertDomainNames(key, value);

2. 支持清单

2.1. 支持请求类型方式及策略

. 请求类型 请求方式 策略
注解方式 GET/POST/DELETE/PUT JSON/FORM/STREAM NET/LOCAL_NET/LOCAL/NET_LOCAL
链式同步 GET/POST/DELETE/PUT JSON/FORM/STREAM NET/LOCAL
获取上游发射器 GET/POST/DELETE/PUT JSON/FORM/STREAM NET/LOCAL
链式异步(推荐) GET/POST/DELETE/PUT JSON/FORM/STREAM NET/LOCAL_NET/LOCAL/NET_LOCAL

2.2. 支持的回调

. 注解方式 链式同步 获取上游发射器 链式异步(推荐)
IAutoNetBodyCallBack
IAutoNetHeadCallBack
IAutoNetEncryptionCallback
AbsAutoNetCallback
IAutoNetCallBack
IAutoNetComplete
IAutoNetDataBeforeCallBack
IAutoNetDataSuccessCallBack
IAutoNetDataCallBack
IAutoNetFileCallBack
IAutoNetLocalOptCallBack

3. 回调介绍

回调需要继承实现AutoNet提供好的接口或者抽象类。AutoNet已经分类, 用户需要什么功能就去集成相应的接口或者抽象类即可

3.1 IAutoNetDataBeforeCallBack(数据返回前的处理, 可定制要继续返回给客户前端的数据)

public interface IAutoNetDataBeforeCallBack<T, Z> extends IAutoNetCallBack {
    // T为用户指定的body要返回的实体类(AutoNet会自动转换), emitter为Rxjava的上游, 可改变其返回结果。 如果自己处理需要返回true。eg: T为一个实体类, 里面有一个List集合, 我们在View层只需要关注List集合,则可以在这里直接重新定义并返回List集合, 并返回true。 (注意:其实这里还有一个功能就是, 根据自己的需求去判断是否集合为空更妙。emitter.onError(new EmptyError())。)
    boolean handlerBefore(T t, FlowableEmitter<Z> emitter);
}

3.2 IAutoNetDataSuccessCallBack(只关心成功的数据, 不关心失败和数据为空的结果)

public interface IAutoNetDataSuccessCallBack<T> extends IAutoNetCallBack {
    // T为用户需要返回的实体类
    void onSuccess(T entity);
}

3.3 IAutoNetDataCallBack(数据返回比较全的回调, 包含了数据成功、数据失败、数据为空)

public interface IAutoNetDataCallBack<T> extends IAutoNetDataSuccessCallBack<T> {
    // 失败
    void onFailed(Throwable throwable);
    // 数据为空(注意:如果不在IAutoNetDataBeforeCallBack去根据自己的业务去手动抛出emitter.onError(new EmptyError())的话, AutoNet是不知道你的业务是什么的, 所以在这个情况下AutoNet在body都为空的时候才调用onEmpty())
    void onEmpty();
}

3.4 IAutoNetLocalOptCallBack(需要用到本地操作, eg:网络策略, 本地、 先本地后网络, 先网络后本地。 其实AutoNet并不能自动根据你的业务和字段给你建立数据库, 需要自己去实现)

public interface IAutoNetLocalOptCallBack<T> extends IAutoNetCallBack {
    T optLocalData(Map request) throws Exception;
}

3.5 IAutoNetFileCallBack(文件操作时的回调, 需要关心上传错误等需要继承上面的IAutoNetDataCallBack)

public interface IAutoNetFileCallBack extends IAutoNetCallBack {
    // 上传文件或者下载文件的进度(0~100)
    void onPregress(float progress);
    // 上传成功或者下载成功后的File文件回调
    void onComplete(File file);
}

3.6 IAutoNetComplete (请求结束后, 该回调会被调用,不管错误成功后都会调用)

public interface IAutoNetComplete extends IAutoNetCallBack {
    void onComplete();
}

3.7 AbsAutoNetCallback(数据回调的集合, 其实数据写这个就行了, 需要什么方法重写什么方法即可)

// 其中 T为返回的body的实体类,Z为自己处理后需要返回给View层后的实体类
public abstract class AbsAutoNetCallback<T, Z> implements IAutoNetDataBeforeCallBack<T, Z>, IAutoNetDataCallBack<Z>, IAutoNetComplete {

    @Override
    public boolean handlerBefore(T t, FlowableEmitter<Z> emitter) {
        return false;
    }

    @Override
    public void onSuccess(Z entity) {
    }

    @Override
    public void onFailed(Throwable throwable) {
    }

    @Override
    public void onEmpty() {
    }

    @Override
    public void onComplete() {
    }
}
}

4. 链式调用

AutoNet.getInstance().createNet()
    // 设置url后缀(除去域名)
    .setSuffixUrl(String)
    // 设置一个标志, 会在全局的Head和Body中回调
    .setFlag(flag)
    // 参数
    .setParams(Map)
    .setParam(key, value)
    .setRequestEntity(IAutoNetRequest)
    // post请求(可传参数)
    .doPost(...)
    // get请求(可传参数)
    .doGet(...)
    // put(可传参数)
    .doPut(...)
    // delete(可传参数)
    .doDelete(...)
    // 指定使用的域名的Key(默认default)
    .setDomainNameKey(String)
    // 设置网络请求方式
    .setNetPattern(NetPattern)
    // 设置网络策略
    .setNetStrategy(NetStrategy)
    // 设置请求类型(JSON/FORM/STREAM/OTHER)
    .setReqType(Type)
    // 设置返回类型(JSON/FORM/STREAM/OTHER)
    .setResType(Type)
    // 设置额外的参数(主要解决动态的拼在url中的参数。eg: www.xxx.com/news/1, 最后的那个1为动态)
    .setExtraDynamicParam(String)
    // 临时的BaseUrl
    .setBaseUrl(String)
    // 链接超时时间
    .setConnectOutTime(Long)
    // 读取时间
    .setReadOuTime(Long)
    // 写入时间
    .setWriteOutTime(Long)
    // 需要加密的参数的key, 可根据key去加密其中类型的参数, 在初始化时使用到了,还记得吗(上去看看)
    .setEncryptionKey(Long)
    // 设置MediaType
    .setMediaType(String)
    // 发送文件
    .setPullFileParams()
    // 接受文件
    .setPushFileParams()
    // 设置临时头部
    .setHeads(String[])
    // 绑定生命周期,防止内存泄漏(忘了?上面有说)
    .setTransformer(...)
    // 数据回调(2章节中讲到的一些回调)
    (1).start(CallBack);
    // 获得上游, 用户自己处理结果
    (2).getFlowable(Class);
    // 同步请求
    (3).synchronizationNet(Class)

5. 获取上游并处理(已zip合并为例, 这里只是用了两个, 其实RxJava提供了好多, 当然还有其他用法,详情可以看RxJava的用法)

// zip
// 1. 得到wanAndroid的上游发射器
Flowable wanAndroidFlowable = getWanAndroidFlowable();
// 2. 得到百度的上游发射器
Flowable baiduFlowable = getBaiduFlowable();
// 3. 合并
//noinspection unchecked
Flowable.zip(wanAndroidFlowable, baiduFlowable, new BiFunction<WanAndroidResponse, String, ZipEntity>() {
    @Override
    public ZipEntity apply(WanAndroidResponse wanAndroidResponse, String s) throws Exception {
        ZipEntity zipEntity = new ZipEntity();
        List<WanAndroidEntity> data = wanAndroidResponse.getData();
        zipEntity.setData(data);
        zipEntity.setBaidu(s);
        return zipEntity;
    }
}).subscribe(new Subscriber<ZipEntity>() {
    @Override
    public void onSubscribe(Subscription subscription) {
        subscription.request(Integer.MAX_VALUE);
    }

    @Override
    public void onNext(ZipEntity o) {
        List<WanAndroidEntity> data = o.getData();
        // 这里进行模拟, 如果 wanAndroid 数据是必须的数据, 为空就是错误
        if (data == null || data.isEmpty()) {
            Toast.makeText(MainActivity.this, "数据为空了", Toast.LENGTH_SHORT).show();
            return;
        }

        Toast.makeText(MainActivity.this, "成功:\n" + o.toString(), Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onError(Throwable throwable) {
        if (throwable instanceof EmptyError) {
            Toast.makeText(MainActivity.this, "数据为空了", Toast.LENGTH_SHORT).show();
            return;
        }
        Toast.makeText(MainActivity.this, "数据错误:\n" + throwable.getMessage(), Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onComplete() {
        Toast.makeText(MainActivity.this, "结束", Toast.LENGTH_SHORT).show();
    }
});


private Flowable getWanAndroidFlowable() {
    return AutoNet.getInstance().createNet()
            .setDomainNameKey("wanandroid")
            .setSuffixUrl("/wxarticle/chapters/json")
            .doGet()
            // 设置追踪, 为了在body拦截中, 不让其他逻辑进行了拦截
            .setFlag(666)
            .getFlowable(WanAndroidResponse.class)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io());
}

private Flowable getBaiduFlowable() {
    return AutoNet.getInstance().createNet()
            // 设置追踪, 为了在body拦截中, 不让其他逻辑进行了拦截
            .setFlag(666)
            .getFlowable(String.class)
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeOn(Schedulers.io());
}

6. 注解方式

6.1 注解介绍

  • AutoNetAnontation 网络参数设置(value(除去域名)、flag、 writeTime、readTime、connectOutTime)
  • AutoNetBaseUrlKeyAnontation BaseUrl的选择标识key(value)
  • AutoNetDisposableBaseUrlAnontation 本次请求临时使用的BaseUrl(value)
  • AutoNetDisposableHeadAnnontation 本次请求临时使用的头部信息(value[])
  • AutoNetEncryptionAnontation 加密参数设置(key, value)
  • AutoNetMediaTypeAnontation 请求的MediaType(value)
  • AutoNetPatternAnontation 请求方式(value(get/post/put/delete))
  • AutoNetStrategyAnontation 网络请求策略(value(net/local/local_net/net_local))
  • AutoNetTypeAnontation 请求和返回的请求类型(reqType(json/form/stream), resType(json/form/stream))

6.2 代理类名规则

如果是回调是内部 则代理类名为 外层类名 + 回调类名 + AutoProxy
如果回调就是一个类 则代理类名为 回调类名 + AutoProxy

6.3 注意

如果使用的是注解方式请求网络, 在写完类后,请build -> rebuild project。

6.4 例子

一、普通请求

@AutoNetPatternAnontation(AutoNetPatternAnontation.NetPattern.GET)
@AutoNetAnontation("/init.php")
@AutoNetBaseUrlKeyAnontation("jsonTestBaseUrl")
public class doGet implements IAutoNetDataBeforeCallBack<TestResponseEntity>, IAutoNetDataCallBack<List<Entity>> {
    @Override
    public boolean handlerBefore(TestResponseEntity o, FlowableEmitter emitter) {
        List<Entity> entitys = o.getList();
        if(entitys == null || entitys.isEmpty()){
            emitter.onError(new EmptyError());
            return true;
        }
        emitter.onNext(entitys);
        return true;
    }

    @Override
    public void onSuccess(List<Entity> entitys) {

    }

    @Override
    public void onFailed(Throwable throwable) {

    }

    @Override
    public void onEmpty() {
    }
}

先build下, 然后再需要发送该网络连接时:
MainActivitydoGetAutoProxy.startNet(MainActivity.this, bindUntilEvent(ActivityEvent.DESTROY));
注意:MainActivitydoGetAutoProxy这个类生成的规则前面已给出

二、 上传文件

@AutoNetBaseUrlKeyAnontation("upFile")
@AutoNetTypeAnontation(reqType = AutoNetTypeAnontation.Type.STREAM)
@AutoNetPatternAnontation(AutoNetPatternAnontation.NetPattern.POST)
public class PushFile implements IAutoNetDataCallBack, IAutoNetFileCallBack {

    @Override
    public void onFailed(Throwable throwable) {
    }

    @Override
    public void onEmpty() {
    }

    @Override
    public void onSuccess(Object entity) {
    }

    @Override
    public void onPregress(float progress) {
    }

    @Override
    public void onComplete(File file) {
    }
}

请求方式:
MainActivityPushFileAutoProxy.pushFile(MainActivity.this, "upload", path + File.separator + "a.png");

三、 下载文件

@AutoNetBaseUrlKeyAnontation("downFile")
@AutoNetTypeAnontation(resType = AutoNetTypeAnontation.Type.STREAM)
@AutoNetAnontation("/apk/downLoad/android_4.2.4.apk")
public class PullFile implements IAutoNetDataCallBack<File>, IAutoNetFileCallBack {
    @Override
    public void onFailed(Throwable throwable) {
    }

    @Override
    public void onEmpty() {
    }

    @Override
    public void onSuccess(File entity) {
    }

    @Override
    public void onPregress(float progress) {
    }

    @Override
    public void onComplete(File file) {
    }
}

请求方式:
MainActivityPullFileAutoProxy.pullFile(MainActivity.this, path, "pppig.apk");

7. 简单的例子

初始化

AutoNetConfig config = new AutoNetConfig.Builder()
            .isOpenStetho(BuildConfig.DEBUG)
            .setDefaultDomainName(ApiConstant.BASE_POST_URL)
            .build();

AutoNet.getInstance().initAutoNet(this, config).setBodyCallback(new IAutoNetBodyCallBack() {
        @Override
        public boolean body(Object flag, String body) {
            // 全局的, 所有的请求都会到这里
            // 在这里可以根据自己的统一的字段去判断code什么的是否成功了
            // 如果不成功可以以异常出去, 最后会在onFailed回调
            if (!TextUtils.isEmpty(body)) {
                try {
                    BaseResponse baseResponse = new Gson().fromJson(body, BaseResponse.class);
                    if (!baseResponse.isSuccess()) {
                        throw new CustomError(baseResponse.getMessage());
                        return true;
                    }
                } catch (Exception e) {
                    emitter.onError(e);
                    return true;
                }
            }
            return false;
        }
    });

简单使用

AutoNet.getInstance().createNet()
    .setSuffixUrl("/test")
    .setParam("a", "a")
    .setParam("b", 1)
    .doPost()
    .start(new TestListCallback());
private class TestListCallback extends AbsAutoNetCallback<TestListResponse, List<TestEntity>> {

    @Override
    public boolean handlerBefore(TestListResponse response, FlowableEmitter emitter) {
        // 这里可以在数据返回以前, 再次指定要返回的数据, 并根据自己的业务去判断是否为空(注意这里是在分线程中)
        List<TestEntity> entitys = response.getData();
        if (entitys == null || entitys.isEmpty()) {
            emitter.onError(new EmptyError());
            return true;
        }
        //noinspection unchecked
        emitter.onNext(entitys);
        return true;
    }

    @Override
    public void onSuccess(List<TestEntity> entitys) {
        bindUserInfo(entitys);
        mEmptyLayout.showContent();
        refreshLayout.refreshComplete();
    }

    @Override
    public void onFailed(Throwable throwable) {
        HandlerError.handlerError(throwable);
        mEmptyLayout.showContent();
        refreshLayout.refreshComplete();
    }

    @Override
    public void onEmpty() {
        HandlerError.handlerEmpty();
        mEmptyLayout.showContent();
        refreshLayout.refreshComplete();
    }
}

2.0.+ 修改点(该版本修改较大, 架构等都有修改, 所以和之前的版本可能有个别用法不同,如果切换最新版本需要主要一下几点)

一、 支持了同步请求,异步请求

  • 增添了synchronizationNet(Class)方法。 Class 即后台返回的数据结构类型。
  • 修改了getFlowable(Class), 增加参数Class。Class 即后台返回的数据结构类型。

二、 body回调

  • 去除 FlowableEmitter 参数, 在之前需要进行特出处理的比如 emitter.onError(new Custom("...")) 改为 throw new Custom("...")

三、 增加了IAutoNetComplete 接口, 如果你想监听请求结束, 就集成IAutoNetComplete。 它不管是否成功失败最后都会回调

四、 如果是下载文件操作, 那么请求返回的ResponseClass 需要制定为 File.class类型

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,312评论 5 473
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,578评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,337评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,134评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,161评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,303评论 1 280
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,761评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,421评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,609评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,450评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,504评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,194评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,760评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,836评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,066评论 1 257
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,612评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,178评论 2 341

推荐阅读更多精彩内容

  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,714评论 6 342
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,315评论 25 707
  • 籍雨亭6月11日感恩日记 1、感恩北京这几天的天气,很凉快,谢谢、谢谢、谢谢 2、感恩淘宝这个好平台,买了好多出行...
    籍雨亭阅读 200评论 0 0
  • 有可能你会问:“你在新年买年货了没?包饺子了没?大扫除了没?贴对联了没?” “没有! 我把那些...
    和薇阅读 244评论 0 1
  • 最近看了篇文章《中国诗词大会没做到的,王者荣耀做到了》。 大概意思是说,玩儿了王者荣耀之后的诸多玩家,开始更多的了...
    离子凝胶阅读 2,734评论 0 1