public class BaseCallback<T> implements Callback<T> {
    protected BaseEvent<T> event;                   // 事件

    public <Event extends BaseEvent<T>> BaseCallback(@NonNull Event event) {
        this.event = event;
    }

    /**
     * Invoked for a received HTTP response.
     * <p>
     * Note: An HTTP response may still indicate an application-level failure such as a 404 or 500.
     * Call {@link Response#isSuccessful()} to determine if the response indicates success.
     *
     * @param call
     * @param response
     */
    @Override
    public void onResponse(Call<T> call, Response<T> response) {
        if (response.isSuccessful())
            EventBus.getDefault().post(event.setEvent(response.code(), response.body()));
        else {
            EventBus.getDefault().post(event.setEvent(response.code(), null));
        }
    }

    /**
     * Invoked when a network exception occurred talking to the server or when an unexpected
     * exception occurred creating the request or processing the response.
     *
     * @param call
     * @param t
     */
    @Override
    public void onFailure(Call<T> call, Throwable t) {
        EventBus.getDefault().post(event.setEvent(-1, null));
    }
} public class BaseImpl<Service> {
    protected CacheUtil mCacheUtil;
    private static Retrofit mRetrofit;
    protected Service mService;

    public BaseImpl(@NonNull Context context) {
        mCacheUtil = new CacheUtil(context.getApplicationContext());
        initRetrofit();
        this.mService = mRetrofit.create(getServiceClass());
    }

    private Class<Service> getServiceClass() {
        return (Class<Service>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
    }

    private void initRetrofit() {
        if (null != mRetrofit)
            return;

        // 设置 Log 拦截器，可以用于以后处理一些异常情况
        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        // 为所有请求自动添加 token
        Interceptor mTokenInterceptor = new Interceptor() {
            @Override
            public okhttp3.Response intercept(Chain chain) throws IOException {
                Request originalRequest = chain.request();
                // 如果当前没有缓存 token 或者请求已经附带 token 了，就不再添加
                if (null == mCacheUtil.getToken() || alreadyHasAuthorizationHeader(originalRequest)) {
                    return chain.proceed(originalRequest);
                }
                String token = OAuth.TOKEN_PREFIX + mCacheUtil.getToken().getAccess_token();
                // 为请求附加 token
                Request authorised = originalRequest.newBuilder()
                        .header(OAuth.KEY_TOKEN, token)
                        .build();
                return chain.proceed(authorised);
            }
        };

        // 自动刷新 token
        Authenticator mAuthenticator = new Authenticator() {
            @Override
            public Request authenticate(Route route, Response response) {
                Logger.i("自动刷新 token 开始");
                TokenService tokenService = mRetrofit.create(TokenService.class);
                String accessToken = "";
                try {
                    if (null != mCacheUtil.getToken()) {
                        Call<Token> call = tokenService.refreshToken(OAuth.client_id,
                                OAuth.client_secret, OAuth.GRANT_TYPE_REFRESH,
                                mCacheUtil.getToken().getRefresh_token());
                        retrofit2.Response<Token> tokenResponse = call.execute();
                        Token token = tokenResponse.body();
                        if (null != token) {
                            mCacheUtil.saveToken(token);
                            accessToken = token.getAccess_token();
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                Logger.i("自动刷新 token 结束：" + accessToken);
                return response.request().newBuilder()
                        .addHeader(OAuth.KEY_TOKEN, OAuth.TOKEN_PREFIX + accessToken)
                        .build();
            }
        };

        // 配置 client
        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(interceptor)                // 设置拦截器
                .retryOnConnectionFailure(true)             // 是否重试
                .connectTimeout(5, TimeUnit.SECONDS)        // 连接超时事件
                .addNetworkInterceptor(mTokenInterceptor)   // 自动附加 token
                .authenticator(mAuthenticator)              // 认证失败自动刷新token
                .build();

        // 配置 Retrofit
        mRetrofit = new Retrofit.Builder()
                .baseUrl(Constant.BASE_URL)                         // 设置 base url
                .client(client)                                     // 设置 client
                .addConverterFactory(GsonConverterFactory.create()) // 设置 Json 转换工具
                .build();
    }

    private boolean alreadyHasAuthorizationHeader(Request originalRequest) {
        // 用于 debug 时临时移除 token
        if (OAuth.getRemoveAutoTokenState()) {
            return true;
        }
        String token = originalRequest.header(OAuth.KEY_TOKEN);
        // 如果本身是请求 token 的 URL，直接返回 true
        // 如果不是，则判断 header 中是否已经添加过 Authorization 这个字段，以及是否为空
        return !(null == token || token.isEmpty() || originalRequest.url().toString().contains(Constant.OAUTH_URL));
    }

    interface TokenService {
        /**
         * 刷新 token
         */
        @POST(Constant.OAUTH_URL)
        @FormUrlEncoded
        Call<Token> refreshToken(@Field("client_id") String client_id, @Field("client_secret") String client_secret,
                                 @Field("grant_type") String grant_type, @Field("refresh_token") String refresh_token);
    }
} public class CreateNewsEvent extends BaseEvent<New> {
    /**
     * @param uuid 唯一识别码
     */
    public CreateNewsEvent(@Nullable String uuid) {
        super(uuid);
    }

    /**
     * @param uuid 唯一识别码
     * @param code 网络返回码
     * @param aNew 实体数据
     */
    public CreateNewsEvent(@Nullable String uuid, @NonNull Integer code, @Nullable New aNew) {
        super(uuid, code, aNew);
    }
} public class CreateNewsReplyEvent extends BaseEvent<NewReply> {
    /**
     * @param uuid 唯一识别码
     */
    public CreateNewsReplyEvent(@Nullable String uuid) {
        super(uuid);
    }

    /**
     * @param uuid     唯一识别码
     * @param code     网络返回码
     * @param newReply 实体数据
     */
    public CreateNewsReplyEvent(@Nullable String uuid, @NonNull Integer code, @Nullable NewReply newReply) {
        super(uuid, code, newReply);
    }
} public class DeleteNewsReplyEvent extends BaseEvent<State> {
    /**
     * @param uuid 唯一识别码
     */
    public DeleteNewsReplyEvent(@Nullable String uuid) {
        super(uuid);
    }

    /**
     * @param uuid  唯一识别码
     * @param code  网络返回码
     * @param state 实体数据
     */
    public DeleteNewsReplyEvent(@Nullable String uuid, @NonNull Integer code, @Nullable State state) {
        super(uuid, code, state);
    }
} public class GetNewsListEvent extends BaseEvent<List<New>> {
    /**
     * @param uuid 唯一识别码
     */
    public GetNewsListEvent(@Nullable String uuid) {
        super(uuid);
    }

    /**
     * @param uuid 唯一识别码
     * @param code 网络返回码
     * @param news 实体数据
     */
    public GetNewsListEvent(@Nullable String uuid, @NonNull Integer code, @Nullable List<New> news) {
        super(uuid, code, news);
    }
} public class GetNewsNodesListEvent extends BaseEvent<List<Node>> {
    /**
     * @param uuid 唯一识别码
     */
    public GetNewsNodesListEvent(@Nullable String uuid) {
        super(uuid);
    }

    /**
     * @param uuid  唯一识别码
     * @param code  网络返回码
     * @param nodes 实体数据
     */
    public GetNewsNodesListEvent(@Nullable String uuid, @NonNull Integer code, @Nullable List<Node> nodes) {
        super(uuid, code, nodes);
    }
} public class GetNewsRepliesListEvent extends BaseEvent<List<NewReply>> {
    /**
     * @param uuid 唯一识别码
     */
    public GetNewsRepliesListEvent(@Nullable String uuid) {
        super(uuid);
    }

    /**
     * @param uuid       唯一识别码
     * @param code       网络返回码
     * @param newReplies 实体数据
     */
    public GetNewsRepliesListEvent(@Nullable String uuid, @NonNull Integer code, @Nullable List<NewReply> newReplies) {
        super(uuid, code, newReplies);
    }
} public class GetNewsReplyEvent extends BaseEvent<NewReply> {
    /**
     * @param uuid 唯一识别码
     */
    public GetNewsReplyEvent(@Nullable String uuid) {
        super(uuid);
    }

    /**
     * @param uuid     唯一识别码
     * @param code     网络返回码
     * @param newReply 实体数据
     */
    public GetNewsReplyEvent(@Nullable String uuid, @NonNull Integer code, @Nullable NewReply newReply) {
        super(uuid, code, newReply);
    }
} public class UpdateNewsReplyEvent extends BaseEvent<NewReply> {
    /**
     * @param uuid 唯一识别码
     */
    public UpdateNewsReplyEvent(@Nullable String uuid) {
        super(uuid);
    }

    /**
     * @param uuid     唯一识别码
     * @param code     网络返回码
     * @param newReply 实体数据
     */
    public UpdateNewsReplyEvent(@Nullable String uuid, @NonNull Integer code, @Nullable NewReply newReply) {
        super(uuid, code, newReply);
    }
} public class UUIDGenerator {
    private UUIDGenerator() {
    }

    public static String getUUID() {
        return UUID.randomUUID().toString();
    }

    //获得指定数量的UUID  
    public static String[] getUUID(int number) {
        if (number < 1) {
            return null;
        }
        String[] ss = new String[number];
        for (int i = 0; i < number; i++) {
            ss[i] = getUUID();
        }
        return ss;
    }
}  
import com.gcssloop.diycode_sdk.api.news.event.DeleteNewsReplyEvent;
import com.gcssloop.diycode_sdk.api.news.event.GetNewsListEvent;
import com.gcssloop.diycode_sdk.api.news.event.GetNewsNodesListEvent;
import com.gcssloop.diycode_sdk.api.news.event.GetNewsRepliesListEvent;
import com.gcssloop.diycode_sdk.api.news.event.GetNewsReplyEvent;
import com.gcssloop.diycode_sdk.api.news.event.UpdateNewsReplyEvent;
import com.gcssloop.diycode_sdk.utils.UUIDGenerator;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.gcssloop.diycode_sdk.api.base.callback.BaseCallback;
import com.gcssloop.diycode_sdk.api.base.impl.BaseImpl;
import com.gcssloop.diycode_sdk.api.news.event.CreateNewsEvent;
import com.gcssloop.diycode_sdk.api.news.event.CreateNewsReplyEvent;
/*
 * Copyright 2017 GcsSloop
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Last modified 2017-03-08 23:50:55
 *
 * GitHub:  https://github.com/GcsSloop
 * Website: http://www.gcssloop.com
 * Weibo:   http://weibo.com/GcsSloop
 */

package com.gcssloop.diycode_sdk.api.news.api;



public class NewsImpl extends BaseImpl<NewsService> implements NewsAPI {

    public NewsImpl(@NonNull Context context) {
        super(context);
    }

    /**
     * 获取 news 列表
     *
     * @param node_id 如果你需要只看某个节点的，请传此参数, 如果不传 则返回全部
     * @param offset  偏移数值，默认值 0
     * @param limit   数量极限，默认值 20，值范围 1..150
     * @see GetNewsListEvent
     */
    @Override
    public String getNewsList(@Nullable Integer node_id, @Nullable Integer offset, @Nullable Integer limit) {
        String uuid = UUIDGenerator.getUUID();
        mService.getNewsList(node_id, offset, limit).enqueue(new BaseCallback<>(new GetNewsListEvent(uuid)));
        return uuid;
    }

    /**
     * 创建一个 new (分享)
     *
     * @param title   标题
     * @param address 地址(网址链接)
     * @param node_id 节点 id
     * @see CreateNewsEvent
     */
    @Override
    public String createNews(@NonNull String title, @NonNull String address, @NonNull Integer node_id) {
        String uuid = UUIDGenerator.getUUID();
        mService.createNews(title, address, node_id).enqueue(new BaseCallback<>(new CreateNewsEvent(uuid)));
        return uuid;
    }

    /**
     * 获取 news 回帖列表
     *
     * @param id     id
     * @param offset 偏移数值 默认 0
     * @param limit  数量极限，默认值 20，值范围 1...150
     * @see GetNewsRepliesListEvent
     */
    @Override
    public String getNewsRepliesList(@NonNull int id, @Nullable Integer offset, @Nullable Integer limit) {
        String uuid = UUIDGenerator.getUUID();
        mService.getNewsRepliesList(id, offset, limit).enqueue(new BaseCallback<>(new GetNewsRepliesListEvent(uuid)));
        return uuid;
    }

    /**
     * 创建 news 回帖 (暂不可用, 没有api)
     *
     * @param id   id
     * @param body 回帖内容， markdown格式
     * @see CreateNewsReplyEvent
     */
    @Override
    public String createNewsReply(@NonNull int id, @NonNull Integer body) {
        String uuid = UUIDGenerator.getUUID();
        mService.createNewsReply(id, body).enqueue(new BaseCallback<>(new CreateNewsReplyEvent(uuid)));
        return uuid;
    }

    /**
     * 获取 news 回帖详情
     *
     * @param id id
     * @see GetNewsReplyEvent
     */
    @Override
    public String getNewsReply(@NonNull int id) {
        String uuid = UUIDGenerator.getUUID();
        mService.getNewsReply(id).enqueue(new BaseCallback<>(new GetNewsReplyEvent(uuid)));