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,自己也是准备在现在的项目中去试用这个官方的框架。一起学习。谢谢观看! |
失败是什么?没有什么,只是更走近成功一步;成功是什么?就是走过了所有通向失败的路,只剩下一条路,那就是成功的路。
posted on 2016-03-31 10:00 Sun‘刺眼的博客 阅读(1502) 评论(0) 编辑 收藏 举报