zoukankan      html  css  js  c++  java
  • okHttp,greenDao,EventBus组合框架项目中实战

    okHttp,greenDao,EventBus组合封装
    zzyandroid
    介绍

    开门见山,大体思路是在Activity中启动服务,通过服务创建Http请求,请求处理结果通过EventBus通知前台更新。

    okHttp封装  首先实现下面接口package cn.org.cfpamf.data.i;

    import android.support.annotation.NonNull;

    import com.squareup.okhttp.Callback;
    import com.squareup.okhttp.OkHttpClient;
    import com.squareup.okhttp.Request;
    import com.squareup.okhttp.RequestBody;

    /**
    * 项目名称:groupBackstage
    * 类描述:
    * 创建人:zzy
    * 创建时间:2015/10/16 10:14
    * 修改人:Administrator
    * 修改时间:2015/10/16 10:14
    * 修改备注:
    */
    public interface IOkHttpRequest {
        /**
         * 获取HttpClient
         * @return
         */
        OkHttpClient getOkHttpClient();

        /**
         * 配置地址
         * @return
         */
        String getUrl();

        /**
         * 配置请求
         * @return
         */
        Request getRequest();

        /**
         * 配置请求
         * @return
         */
        Request.Builder getRequestBuilder();

        /**
         * 处理返回消息
         * @return
         */
        Callback getResponseCallBack();

        /**
         * 获取请求主体
         * @return
         */
        RequestBody getRequestBody();

        /**
         * 启动网络请求
         * @param okHttpClient
         * @param request
         * @param callback
         */
        void execute(@NonNull OkHttpClient okHttpClient, @NonNull Request request, @NonNull Callback callback);
    }



    然后具体实现:
    package cn.org.cfpamf.data.okHttp;

    import android.content.Context;
    import android.os.Bundle;
    import android.support.annotation.NonNull;

    import com.orhanobut.logger.Logger;
    import com.squareup.okhttp.Callback;
    import com.squareup.okhttp.OkHttpClient;
    import com.squareup.okhttp.Request;
    import com.squareup.okhttp.Response;

    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.concurrent.TimeUnit;

    import cn.org.cfpamf.data.exception.e.HandleOkHttpException;
    import cn.org.cfpamf.data.exception.e.PrintLog;
    import cn.org.cfpamf.data.i.IOkHttpEvent;
    import cn.org.cfpamf.data.i.IOkHttpRequest;
    import cn.org.cfpamf.data.i.IOkHttpResponse;
    import cn.org.cfpamf.data.util.TimeUtils;
    import de.greenrobot.event.EventBus;

    /**
    * 项目名称:groupBackstage
    * 类描述:
    * 创建人:zzy
    * 创建时间:2015/10/20 14:03
    * 修改人:Administrator
    * 修改时间:2015/10/20 14:03
    * 修改备注:
    */
    public abstract class AbstractBaseOkHttp implements IOkHttpRequest, IOkHttpResponse, IOkHttpEvent {

        private static final String CONTENT_TYPE_KEY = "Content-Type";
        protected static final String CONTENT_TYPE = "application/json; charset=utf-8";
        private static final String ACCEPT_KEY = "Accept";
        private static final String ACCEPT = "application/json";
        private static final String UTF8 = "utf8";

        private static OkHttpClient okHttpClient;
        /**
         * get请求参数 Bundle key
         */
        public static final String BUNDLE_GET_KEY = "BUNDLE_GET_KEY";
        /**
         * post/put 请求参数 Bundle key
         */
        public static final String BUNDLE_POST_OR_PUT_KEY = "BUNDLE_POST_OR_PUT_KEY";

        protected Context context;
        protected Bundle bundle;
        protected Request request;

        /**
         * 日志
         */
        protected PrintLog printLog;
        ;
        /**
         * 网络请求 异常信息
         */
        protected String errorMessage;

        /**
         * @param context
         * @param bundle
         */
        public AbstractBaseOkHttp(@NonNull Context context, @NonNull Bundle bundle) {
            this.context = context;
            this.bundle = bundle;
            printLog = new PrintLog();
            printLog.setRequestTime(TimeUtils.getCurrentTimeInString(new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒")));
            request = getRequest();
            printLog.setUrl(request.urlString());
            printLog.setHeaders(newStringBuilder().append(CONTENT_TYPE_KEY).append("=").append(request.header(CONTENT_TYPE_KEY)).toString());
            execute(getOkHttpClient(), getRequest(), getResponseCallBack());
        }

        /**
         * 获取HttpClient
         *
         * @return
         */
        @Override
        public OkHttpClient getOkHttpClient() {
            if (okHttpClient == null) {
                okHttpClient = new OkHttpClient();
            } else {
                okHttpClient = okHttpClient.clone();
            }
            okHttpClient.setConnectTimeout(30, TimeUnit.SECONDS);
            return okHttpClient;
        }

        /**
         * 请求配置
         *
         * @return
         */
        @Override
        public Request.Builder getRequestBuilder() {
            return new Request.Builder()
                    .addHeader(CONTENT_TYPE_KEY, CONTENT_TYPE)
                    .addHeader(ACCEPT_KEY, ACCEPT);
        }

        /**
         * 处理接口返回
         * @return
         */
        @Override
        public Callback getResponseCallBack() {
            return new Callback() {
                @Override
                public void onFailure(Request request, IOException e) {
                    onFailed(e);
                }

                @Override
                public void onResponse(Response response) throws IOException {
                    if (response.isSuccessful())
                        onSuccess(response);
                    else
                        throw new IOException();
                }
            };
        }

        /**
         * 如果子类需要处理失败信息 重写该方法
         *
         * @param exception
         */
        @Override
        public void onFailed(@NonNull Exception exception) {
            errorMessage = HandleOkHttpException.handleMessage(exception);
            printLogger(errorMessage);
            //通知前台更新 失败后返回子类对象 在Activity里注册子类的监听
            EventBus.getDefault().post(getPostEvent());
            Logger.e(errorMessage);
        }

        /**
         * 启动网络请求
         *
         * @param okHttpClient
         * @param request
         * @param callback
         */
        @Override
        public void execute(OkHttpClient okHttpClient, Request request, Callback callback) {
            okHttpClient.newCall(request).enqueue(callback);
        }


        /**
         * 打印日志,写入sd卡并提交腾讯统计服务
         *
         * @param body
         */
        protected void printLogger(String body) {
            printLog.setResponseTime(TimeUtils.getCurrentTimeInString(new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒")));
            printLog.setResponseBody(body);
            printLog.printLogToSdCard(context);
        }

        public String getErrorMessage() {
            return errorMessage;
        }

        public void setErrorMessage(String errorMessage) {
            this.errorMessage = errorMessage;
        }
    }




    简单实现后,子类继承即可方便调用,而且少去很多重复代码。下面贴出抽象类后的代码,以请求百度地址为例:


    package cn.org.cfpamf.data.okHttp;

    import android.content.Context;
    import android.os.Bundle;
    import android.support.annotation.NonNull;

    import com.orhanobut.logger.Logger;
    import com.squareup.okhttp.Request;
    import com.squareup.okhttp.RequestBody;
    import com.squareup.okhttp.Response;

    import java.io.IOException;
    import java.util.UUID;

    import cn.org.cfpamf.data.database.DatabaseManager;
    import cn.org.cfpamf.data.sql.db.Baidu;
    import de.greenrobot.event.EventBus;

    /**
    * 项目名称:Zhnx
    * 类描述:
    * 创建人:zzy
    * 创建时间:2015/11/10 11:00
    * 修改人:Administrator
    * 修改时间:2015/11/10 11:00
    * 修改备注:
    */
    public class BaiduTestOkHttp extends AbstractBaseOkHttp {

        public static final String TYPE_BAIDU = "BaiduTestOkHttp";

        /**
         * @param context
         * @param bundle
         */
        public BaiduTestOkHttp(@NonNull Context context, @NonNull Bundle bundle) {
            super(context, bundle);
        }

        @Override
        public AbstractBaseOkHttp getPostEvent() {
            return this;
        }

        @Override
        public String getUrl() {
            return "Http://www.baidu.com";
        }

        @Override
        public Request getRequest() {
            return getRequestBuilder().url(getUrl()).build();
        }

        /**
         * 没有body
         *
         * @return
         */
        @Override
        public RequestBody getRequestBody() {
            return null;
        }

        @Override
        public void onSuccess(@NonNull Response response) {
            try {
                String strResponse = response.body().string();
                Baidu baiu = new Baidu();
                baiu.setId(UUID.randomUUID().toString());
                baiu.setResponse(strResponse);
                //插入数据库
                new DatabaseManager<Baidu>(context).insert(baiu);
                //通知前台更新
                EventBus.getDefault().post(baiu);
                Logger.d(strResponse);
            } catch (IOException e) {
                onFailed(e);
            }
        }
    }

    大家可以看到子类实现可以很简单而且很清晰明了,项目中的日志打印也封装在抽象类中,更是省去了处处调用日志打印的繁琐,
    大家注意到里面有个getPostEvent()方法return this,这是为了每个接口失败的返回都通过网络对象通知前台,因为懒得定义新的对象再post通知,
    这个例子中成功请求后就往前台通知接口中返回的数据,这样在实际项目中的确是有用的,像前台要知道更新了什么数据,更新了多少条,很容易就实现了。
    数据库是在greenDao的基础上抽象出了一个DataBaseManager通过泛型可以简单实现数据中每张表的增删改查。看了下面接口,大家应该就明白了:
    package cn.org.cfpamf.data.database;

    import java.util.List;

    /**
    * 项目名称:groupBackstage
    * 类描述:
    * 创建人:zzy
    * 创建时间:2015/8/28 17:05
    * 修改人:Administrator
    * 修改时间:2015/8/28 17:05
    * 修改备注:
    */
    public interface IDatabase<M> {

        void insert(M m);

        void delete(M m);

        void insertOrReplace(M m);

        void update(M m);

        M selectByPrimaryKey(Class<M> entityClass, String Id);

        List<M> loadAll(Class<M> entityClass);

        void refresh(M m);

        /**
         * Closing available connections
         */
        void closeDbConnections();

        /**
         * Delete all tables and content from our database
         */
        void dropDatabase();

        /**
         * 事务
         */
        void runInTx(Runnable runnable);


    }


    基本的增删改查是没有问题了。具体启动是通过服务启动的:



    package cn.org.cfpamf.data;

    import android.app.IntentService;
    import android.content.Intent;

    import cn.org.cfpamf.data.bus.NetStatusEvent;
    import cn.org.cfpamf.data.factory.OkHttpFactory;
    import cn.org.cfpamf.data.util.NetWorkUtils;
    import de.greenrobot.event.EventBus;

    /**
    * 项目名称:Zhnx
    * 类描述:
    * 创建人:zzy
    * 创建时间:2015/11/10 10:42
    * 修改人:Administrator
    * 修改时间:2015/11/10 10:42
    * 修改备注:
    */
    public class ApiService extends IntentService {

        /**
         * Creates an IntentService.  Invoked by your subclass's constructor.
         */
        public ApiService() {
            super("ApiService");
        }

        @Override
        public void onCreate() {
            super.onCreate();
        }

        @Override
        protected void onHandleIntent(Intent intent) {
            if (!NetWorkUtils.isNetworkConnected(getApplicationContext())) {
                //在baseActivity里注册即可
                EventBus.getDefault().post(newNetStatusEvent(NetStatusEvent.Please_Connect_To_The_Network_And_Try_Again));
            } else {
                OkHttpFactory.createHttp(this, intent.getType(), intent.getExtras());
            }
        }

        @Override
        public void onDestroy() {
            super.onDestroy();
        }
    }


    前台所有请求通过调用服务启动,并由IntentService自己管理生命周期,网络处理完毕后即可自己释放掉,而且统一对网络进行判断,通过Bundle携带数据过来,并传递给Http请求。具体Get,post请求源码中有例子,这里就不一一描述,前台接受如下:
    package cn.org.cfpamf.zhnx;

    import android.widget.TextView;

    import butterknife.Bind;
    import cn.org.cfpamf.data.base.BaseActivity;
    import cn.org.cfpamf.data.manager.StartServiceManager;
    import cn.org.cfpamf.data.okHttp.BaiduTestOkHttp;
    import cn.org.cfpamf.data.sql.db.Baidu;

    public class MainActivity extends BaseActivity {

        @Bind(R.id.text_response)
        TextView text_response;

        @Override
        protected void setToolbar() {
        }

        @Override
        protected void setLayoutContentView() {
            setContentView(R.layout.activity_main);
        }

        @Override
        protected void afterView() {
            StartServiceManager.startBaiduOkHttp(this);
        }

        /**
         * 处理失败信息
         *
         * @param baiduTestOkHttp
         */
        public void onEventMainThread(BaiduTestOkHttp baiduTestOkHttp) {
            createHintDialog("失败", baiduTestOkHttp.getErrorMessage());
        }

        /**
         * 处理成功信息
         * @param baidu
         */
        public void onEventMainThread(Baidu baidu) {
            //更新UI
            text_response.setText(baidu.getResponse());
        }
    }

    总结这是本人一点点小分享,有兴趣的大家可以下载源码查看,地址是:https://github.com/zzyandroid0425/EXP 
    源码中还有好多项目中经常用到的东西,比如常见的工具类,常用的BaseRecyclerViewAdapter,AotuGridLayoutManager,也都是自己查询资料,并总结到里面,慢慢的做为一个项目的基础框架使用,后期还会加入android data binding,自己也是准备在现在的项目中去试用这个官方的框架。一起学习。谢谢观看!



  • 相关阅读:
    SharePoint文件磁盘存储组件使用指南
    自定义SharePoint新网站创建过程(1)
    SharePoint : 超级Web Application Framework
    Video:使用VSeWSS创建定制SharePoint页面
    SharePoint Designer 2007 is now FREE !
    关于SharePoint解决方案开发模型的凌乱文章…
    初试Silverlight Streaming服务
    Feature Schema中Module和File节点属性含义的解释
    如何定制列表项编辑页面
    使用SharePoint Server 2007搜索Domino Notes
  • 原文地址:https://www.cnblogs.com/android-blogs/p/5340027.html
Copyright © 2011-2022 走看看