技术选型
封装思路
封装okhttp
请求参数的封装:
public class RequestParams {
public ConcurrentHashMap < String , String > urlParams = new ConcurrentHashMap < String , String > ( ) ;
public ConcurrentHashMap < String , Object > fileParams = new ConcurrentHashMap < String , Object > ( ) ;
public RequestParams ( ) {
this ( ( Map < String , String > ) null ) ;
}
public RequestParams ( Map < String , String > source) {
if ( source != null ) {
for ( Map. Entry < String , String > entry : source. entrySet ( ) ) {
put ( entry. getKey ( ) , entry. getValue ( ) ) ;
}
}
}
public RequestParams ( final String key, final String value) {
this ( new HashMap < String , String > ( ) {
{
put ( key, value) ;
}
} ) ;
}
public void put ( String key, String value) {
if ( key != null && value != null ) {
urlParams. put ( key, value) ;
}
}
public void put ( String key, Object object) throws FileNotFoundException {
if ( key != null ) {
fileParams. put ( key, object) ;
}
}
public boolean hasParams ( ) {
if ( urlParams. size ( ) > 0 || fileParams. size ( ) > 0 ) {
return true ;
}
return false ;
}
}
对okhttp的request的封装:
public class CommonRequest {
public static Request createPostRequest ( String url, RequestParams params) {
return createPostRequest ( url, params, null ) ;
}
public static Request createPostRequest ( String url, RequestParams params, RequestParams headers) {
FormBody. Builder mFormBodyBuild = new FormBody. Builder ( ) ;
if ( params != null ) {
for ( Map. Entry < String , String > entry : params. urlParams. entrySet ( ) ) {
mFormBodyBuild. add ( entry. getKey ( ) , entry. getValue ( ) ) ;
}
}
Headers. Builder mHeaderBuild = new Headers. Builder ( ) ;
if ( headers != null ) {
for ( Map. Entry < String , String > entry : headers. urlParams. entrySet ( ) ) {
mHeaderBuild. add ( entry. getKey ( ) , entry. getValue ( ) ) ;
}
}
FormBody mFormBody = mFormBodyBuild. build ( ) ;
Headers mHeader = mHeaderBuild. build ( ) ;
Request request = new Request. Builder ( ) . url ( url) .
post ( mFormBody) .
headers ( mHeader)
. build ( ) ;
return request;
}
public static Request createGetRequest ( String url, RequestParams params) {
return createGetRequest ( url, params, null ) ;
}
public static Request createGetRequest ( String url, RequestParams params, RequestParams headers) {
StringBuilder urlBuilder = new StringBuilder ( url) . append ( "?" ) ;
if ( params != null ) {
for ( Map. Entry < String , String > entry : params. urlParams. entrySet ( ) ) {
urlBuilder. append ( entry. getKey ( ) ) . append ( "=" ) . append ( entry. getValue ( ) ) . append ( "&" ) ;
}
}
Headers. Builder mHeaderBuild = new Headers. Builder ( ) ;
if ( headers != null ) {
for ( Map. Entry < String , String > entry : headers. urlParams. entrySet ( ) ) {
mHeaderBuild. add ( entry. getKey ( ) , entry. getValue ( ) ) ;
}
}
Headers mHeader = mHeaderBuild. build ( ) ;
return new Request. Builder ( ) .
url ( urlBuilder. substring ( 0 , urlBuilder. length ( ) - 1 ) )
. get ( )
. headers ( mHeader)
. build ( ) ;
}
private static final MediaType FILE_TYPE = MediaType . parse ( "application/octet-stream" ) ;
public static Request createMultiPostRequest ( String url, RequestParams params) {
MultipartBody. Builder requestBody = new MultipartBody. Builder ( ) ;
requestBody. setType ( MultipartBody . FORM) ;
if ( params != null ) {
for ( Map. Entry < String , Object > entry : params. fileParams. entrySet ( ) ) {
if ( entry. getValue ( ) instanceof File ) {
requestBody. addPart ( Headers . of ( "Content-Disposition" , "form-data; name=\"" + entry. getKey ( ) + "\"" ) ,
RequestBody . create ( FILE_TYPE, ( File ) entry. getValue ( ) ) ) ;
} else if ( entry. getValue ( ) instanceof String ) {
requestBody. addPart ( Headers . of ( "Content-Disposition" , "form-data; name=\"" + entry. getKey ( ) + "\"" ) ,
RequestBody . create ( null , ( String ) entry. getValue ( ) ) ) ;
}
}
}
return new Request. Builder ( ) . url ( url) . post ( requestBody. build ( ) ) . build ( ) ;
}
}
对JsonCallback 的封装:
* @function 专门处理JSON的回调
* /
public class CommonJsonCallback implements Callback {
protected final String RESULT_CODE = "ecode" ;
protected final int RESULT_CODE_VALUE = 0 ;
protected final String ERROR_MSG = "emsg" ;
protected final String EMPTY_MSG = "" ;
protected final int NETWORK_ERROR = - 1 ;
protected final int JSON_ERROR = - 2 ;
protected final int OTHER_ERROR = - 3 ;
private Handler mDeliveryHandler;
private DisposeDataListener mListener;
private Class < ? > mClass;
public CommonJsonCallback ( DisposeDataHandle handle) {
this . mListener = handle. mListener;
this . mClass = handle. mClass;
this . mDeliveryHandler = new Handler ( Looper . getMainLooper ( ) ) ;
}
@Override
public void onFailure ( final Call call, final IOException ioexception) {
mDeliveryHandler. post ( new Runnable ( ) {
@Override
public void run ( ) {
mListener. onFailure ( new OkHttpException ( NETWORK_ERROR, ioexception) ) ;
}
} ) ;
}
@Override
public void onResponse ( final Call call, final Response response) throws IOException {
final String result = response. body ( ) . string ( ) ;
mDeliveryHandler. post ( new Runnable ( ) {
@Override
public void run ( ) {
handleResponse ( result) ;
}
} ) ;
}
private void handleResponse ( Object responseObj) {
if ( responseObj == null || responseObj. toString ( ) . trim ( ) . equals ( "" ) ) {
mListener. onFailure ( new OkHttpException ( NETWORK_ERROR, EMPTY_MSG) ) ;
return ;
}
try {
JSONObject result = new JSONObject ( responseObj. toString ( ) ) ;
if ( mClass == null ) {
mListener. onSuccess ( result) ;
} else {
Object obj = new Gson ( ) . fromJson ( responseObj. toString ( ) , mClass) ;
if ( obj != null ) {
mListener. onSuccess ( obj) ;
} else {
mListener. onFailure ( new OkHttpException ( JSON_ERROR, EMPTY_MSG) ) ;
}
}
} catch ( Exception e) {
mListener. onFailure ( new OkHttpException ( OTHER_ERROR, e. getMessage ( ) ) ) ;
e. printStackTrace ( ) ;
}
}
}
业务逻辑层真正处理的地方,包括java层异常和业务层异常:
public interface DisposeDataListener {
void onSuccess ( Object responseObj) ;
void onFailure ( Object reasonObj) ;
}
public class DisposeDataHandle
{
public DisposeDataListener mListener = null ;
public Class < ? > mClass = null ;
public String mSource = null ;
public DisposeDataHandle ( DisposeDataListener listener)
{
this . mListener = listener;
}
public DisposeDataHandle ( DisposeDataListener listener, Class < ? > clazz)
{
this . mListener = listener;
this . mClass = clazz;
}
public DisposeDataHandle ( DisposeDataListener listener, String source)
{
this . mListener = listener;
this . mSource = source;
}
}
自定义异常类,返回ecode,emsg到业务层:
public class OkHttpException extends Exception {
private static final long serialVersionUID = 1L ;
private int ecode;
private Object emsg;
public OkHttpException ( int ecode, Object emsg) {
this . ecode = ecode;
this . emsg = emsg;
}
public int getEcode ( ) {
return ecode;
}
public Object getEmsg ( ) {
return emsg;
}
}
专门处理文件下载回调:
public class CommonFileCallback implements Callback {
protected final int NETWORK_ERROR = - 1 ;
protected final int IO_ERROR = - 2 ;
protected final String EMPTY_MSG = "" ;
private static final int PROGRESS_MESSAGE = 0x01 ;
private Handler mDeliveryHandler;
private DisposeDownloadListener mListener;
private String mFilePath;
private int mProgress;
public CommonFileCallback ( DisposeDataHandle handle) {
this . mListener = ( DisposeDownloadListener ) handle. mListener;
this . mFilePath = handle. mSource;
this . mDeliveryHandler = new Handler ( Looper . getMainLooper ( ) ) {
@Override
public void handleMessage ( Message msg) {
switch ( msg. what) {
case PROGRESS_MESSAGE:
mListener. onProgress ( ( int ) msg. obj) ;
break ;
}
}
} ;
}
@Override
public void onFailure ( final Call call, final IOException ioexception) {
mDeliveryHandler. post ( new Runnable ( ) {
@Override
public void run ( ) {
mListener. onFailure ( new OkHttpException ( NETWORK_ERROR, ioexception) ) ;
}
} ) ;
}
@Override
public void onResponse ( Call call, Response response) throws IOException {
final File file = handleResponse ( response) ;
mDeliveryHandler. post ( new Runnable ( ) {
@Override
public void run ( ) {
if ( file != null ) {
mListener. onSuccess ( file) ;
} else {
mListener. onFailure ( new OkHttpException ( IO_ERROR, EMPTY_MSG) ) ;
}
}
} ) ;
}
private File handleResponse ( Response response) {
if ( response == null ) {
return null ;
}
InputStream inputStream = null ;
File file = null ;
FileOutputStream fos = null ;
byte [ ] buffer = new byte [ 2048 ] ;
int length;
int currentLength = 0 ;
double sumLength;
try {
checkLocalFilePath ( mFilePath) ;
file = new File ( mFilePath) ;
fos = new FileOutputStream ( file) ;
inputStream = response. body ( ) . byteStream ( ) ;
sumLength = ( double ) response. body ( ) . contentLength ( ) ;
while ( ( length = inputStream. read ( buffer) ) != - 1 ) {
fos. write ( buffer, 0 , length) ;
currentLength += length;
mProgress = ( int ) ( currentLength / sumLength * 100 ) ;
mDeliveryHandler. obtainMessage ( PROGRESS_MESSAGE, mProgress) . sendToTarget ( ) ;
}
fos. flush ( ) ;
} catch ( Exception e) {
file = null ;
} finally {
try {
if ( fos != null ) {
fos. close ( ) ;
}
if ( inputStream != null ) {
inputStream. close ( ) ;
}
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
}
return file;
}
private void checkLocalFilePath ( String localFilePath) {
File path = new File ( localFilePath. substring ( 0 ,
localFilePath. lastIndexOf ( "/" ) + 1 ) ) ;
File file = new File ( localFilePath) ;
if ( ! path. exists ( ) ) {
path. mkdirs ( ) ;
}
if ( ! file. exists ( ) ) {
try {
file. createNewFile ( ) ;
} catch ( IOException e) {
e. printStackTrace ( ) ;
}
}
}
}
封装OkHttpClient,用来发送get, post请求的工具类,包括设置一些请求的共用参数
public class CommonOkHttpClient {
private static final int TIME_OUT = 30 ;
private static OkHttpClient mOkHttpClient;
static {
OkHttpClient. Builder okHttpClientBuilder = new OkHttpClient. Builder ( ) ;
okHttpClientBuilder. hostnameVerifier ( new HostnameVerifier ( ) {
@Override
public boolean verify ( String hostname, SSLSession session) {
return true ;
}
} ) ;
okHttpClientBuilder. addInterceptor ( new Interceptor ( ) {
@Override
public Response intercept ( Chain chain) throws IOException {
Request request =
chain. request ( ) . newBuilder ( ) . addHeader ( "User-Agent" , "Imooc-Mobile" )
. build ( ) ;
return chain. proceed ( request) ;
}
} ) ;
okHttpClientBuilder. cookieJar ( new SimpleCookieJar ( ) ) ;
okHttpClientBuilder. connectTimeout ( TIME_OUT, TimeUnit . SECONDS) ;
okHttpClientBuilder. readTimeout ( TIME_OUT, TimeUnit . SECONDS) ;
okHttpClientBuilder. writeTimeout ( TIME_OUT, TimeUnit . SECONDS) ;
okHttpClientBuilder. followRedirects ( true ) ;
okHttpClientBuilder. sslSocketFactory ( HttpsUtils . initSSLSocketFactory ( ) ,
HttpsUtils . initTrustManager ( ) ) ;
mOkHttpClient = okHttpClientBuilder. build ( ) ;
}
public static OkHttpClient getOkHttpClient ( ) {
return mOkHttpClient;
}
public static Call get ( Request request, DisposeDataHandle handle) {
Call call = mOkHttpClient. newCall ( request) ;
call. enqueue ( new CommonJsonCallback ( handle) ) ;
return call;
}
public static Call post ( Request request, DisposeDataHandle handle) {
Call call = mOkHttpClient. newCall ( request) ;
call. enqueue ( new CommonJsonCallback ( handle) ) ;
return call;
}
public static Call downloadFile ( Request request, DisposeDataHandle handle) {
Call call = mOkHttpClient. newCall ( request) ;
call. enqueue ( new CommonFileCallback ( handle) ) ;
return call;
}
}
请求中心
public class RequestCenter {
static class HttpConstants {
private static final String ROOT_URL = "http://imooc.com/api" ;
private static String HOME_RECOMMAND = ROOT_URL + "/module_voice/home_recommand" ;
private static String HOME_RECOMMAND_MORE = ROOT_URL + "/module_voice/home_recommand_more" ;
private static String HOME_FRIEND = ROOT_URL + "/module_voice/home_friend" ;
public static String LOGIN = ROOT_URL + "/module_voice/login_phone" ;
}
public static void getRequest ( String url, RequestParams params, DisposeDataListener listener,
Class < ? > clazz) {
CommonOkHttpClient . get ( CommonRequest .
createGetRequest ( url, params) , new DisposeDataHandle ( listener, clazz) ) ;
}
public static void requestRecommandData ( DisposeDataListener listener) {
RequestCenter . getRequest ( HttpConstants . HOME_RECOMMAND, null , listener,
BaseRecommandModel . class ) ;
}
public static void requestRecommandMore ( DisposeDataListener listener) {
RequestCenter . getRequest ( HttpConstants . HOME_RECOMMAND_MORE, null , listener,
BaseRecommandMoreModel . class ) ;
}
public static void requestFriendData ( DisposeDataListener listener) {
RequestCenter . getRequest ( HttpConstants . HOME_FRIEND, null , listener, BaseFriendModel . class ) ;
}
public static void login ( DisposeDataListener listener) {
RequestParams params = new RequestParams ( ) ;
params. put ( "mb" , "18734924592" ) ;
params. put ( "pwd" , "999999q" ) ;
RequestCenter . getRequest ( HttpConstants . LOGIN, params, listener, User . class ) ;
}
}