okHttp封装,使用超简单的网络请求实现
2016-08-12 23:57
891 查看
文章内容概要:
框架需要解决的问题,及思路;具体实施。
说明
okHttp是一款实用高效,使用简单的网络模块实现,虽然使用简单,但要在项目中使用还是得进行简单的封装,不可能每次请求都去写十几,甚至几十行相同的代码,这样是相当低效的,说这么多都算是废话。来看看本次封装我想要达到的效果:
1. 调用起来要简单,我可以选择请求方式:getAsyn、getSync、post、fileUpload、fileDownload、displayImage。调用者只提供请求url,请求参数。至于内部如何发起请求,肯定是调用者所不关心的。
2. 返回值是调用者所关心的,调用成功或失败是调用者关心的,成功后我可以拿到返回结果,调用失败我可以选择是否处理,或者我不处理的时候可以默认提示请求失败。像显示图片这种请求,请求完后希望能直接更新UI。当然也可以选择显示完后进行回调。反正一句话,调用者想做什么都能做,什么都不做的时候程序不会出错。
实现
首先想到下面第一种方法。1.在okHttp几大方法已经封装在一个思HttpUtil的类里,而且假设都是静态方法。这里在Activity中只需要调用譬如,HttpUtil.getAsyn(url,param);类似这样的调用即可,看起来调用还是挺方便的。来看返回,返回有成功和失败两种情况,okHttp本身提供了Callback接口,我们是否可以实现这个接口就可以拿到返回了,于是调用就成这样了
HttpUtil.getAsyn(url,param,new Callback() { @Override public void onFailure(Request request, IOException e) { } @Override public void onResponse(final Response response) throws IOException { } });
但是这样有一个问题,就是我调用方法的时候,我必须去实现这个接口,如果我不想去关心返回结果,那我还要去实现这个接口就太不友好了。那如果你不关心,大不了Activity实现这个接口,实现两个空方法,调用方法就变成了
HttpUtil.getAsyn(url,param,this);//this指的是Activity,必须实现Callback接口。
这样看起来是比匿名内部类简洁一点。如果实在不愿意去实现接口,那大不了HttpUtil多重载一个方法出来,不要求传Callback实现就行了。这也不失为一种解决办法。呵呵,这是我写之前没有想到的,似乎这么简单封装就能达到我们的要求了。
HttpUtil.getAsyn(url,param);//不关心返回时调用。
下面把我的封装说一下,用的java三大特性:封闭、继承、多态。呵呵,瞬间高大上了。
给所有 Activity 创建了一个父类:BaseActivity,父类中定义了一个属性:HttpUtil(非静态),在父类OnCreate中初始化HttpUtil。HttpUtil中保有BaseActivity的引用。
//BaseActivity部分代码 public abstract class BaseActivity extends Activity { public static final String TAG = BaseActivity.class.getSimpleName(); protected Handler mHandler = null; public BaseUtil baseUtil; public HttpUtil httpUtil; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); baseUtil = new BaseUtil(this); //初始化httpUtil,并将this引用作为参数 httpUtil = new HttpUtil(this); //初始化mHandler,用于子线程向主线程发消息 initHandler(); } //实现了一个http请求返回调用的空方法 protected void httpResponse(String url, Map<String, Object> params, Object result) { } //文件下载完成后回调,空方法 protected void completeDownload(String abstractPath) { } ////请求出错回调,默认提示网络请求失败 void httpError(String url, Map<String, Object> params) { mHandler.post(new Runnable() { @Override public void run() { Toast.makeText(BaseActivity.this, "网络请求失败", 300).show(); } }); } . . . }
//HttpUtil部分代码,这里也并非面对真正的okHttp封装,而在之上又包了一层。 //边写边想的时候发现这一层如果拿掉也不是不可以,但这样至少我们直接面对的代码是比较简洁的。 public class HttpUtil { private BaseActivity activity; public HttpUtil(BaseActivity activity) { this.activity = activity; } public Map<String, Object> getSyncHttp(String url) { try { Response response = OkHttpEngine.getInstance().getSyncHttp(activity, url); Map<String, Object> result = new HashMap<>(); return result; } catch (IOException e) { return null; } } . . . }
进行了这两层封装,请求的返回方法已经被BaseActivity实现,子类Activity如果不关心,完全不用实现任何接口,请求之后的事情完全可以由BaseActivity消化吸收。若需要对返回值进行处理,子类实现httpResponse()方法即可。
Activity中调用网络请求方法:
public void httpTest(){ this.httpUtil.getAsynHttp("https://www.baidu.com", p1); ImageView view = findView(R.id.imageview); // 加载图片 this.httpUtil.displayImage(mHandler, view, "https://www.baidu.com/img/bd_logo1.png", R.drawable.no_image); String p = MyApplication.mkdirs("/net_image/a/b"); //下载文件保存到sdcard/net_image/a/b文件夹下。 this.httpUtil.downloadFile("http://a4.att.hudong.com/23/09/01300000165488122547095974400.jpg", p); }
直接上代码了。来一张代码结构图
从上到下
BaseActivity.java
创建了mHandler,保证了如果子类不创建handler时,子类调用http请求后,父类可以代为处理响应,更新UI,显示提示信息等。创建了httpUtil,将父类的引用传递到httpUtil中,请求返回后,直接调用响应成功或失败方法,如果子类实现了响应方法,调用会直达子类实现,这就是继承时多态。
实现了响应回调方法,若子类未实现时,父类可以代为处理。
package com.mydemo.common; import java.util.Map; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.view.View; import android.widget.Toast; public abstract class BaseActivity extends Activity { public static final String TAG = BaseActivity.class.getSimpleName(); protected Handler mHandler = null; public BaseUtil baseUtil; public HttpUtil httpUtil; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); baseUtil = new BaseUtil(this); httpUtil = new HttpUtil(this); initHandler(); } protected void initHandler() { mHandler = new Handler(); } public <T> T findView(int id) { View view = findViewById(id); if (view == null || view.toString().equals("")) { return null; } return (T) view; } /** * 通过类名启动Activity * * @param pClass */ protected void openActivity(Class<?> pClass) { openActivity(pClass, null); } /** * 通过类名启动Activity,并且含有Bundle数据 * * @param pClass * @param pBundle */ protected void openActivity(Class<?> pClass, Bundle pBundle) { Intent intent = new Intent(this, pClass); if (pBundle != null) { intent.putExtras(pBundle); } startActivity(intent); } /** * 通过Action启动Activity * * @param pAction */ protected void openActivity(String pAction) { openActivity(pAction, null); } /** * 通过Action启动Activity,并且含有Bundle数据 * * @param pAction * @param pBundle */ protected void openActivity(String pAction, Bundle pBundle) { Intent intent = new Intent(pAction); if (pBundle != null) { intent.putExtras(pBundle); } startActivity(intent); } protected void httpResponse(String url, Map<String, Object> params, Object result) { } protected void completeDownload(String abstractPath) { } protected void httpError(String url, Map<String, Object> params, final Exception e) { mHandler.post(new Runnable() { @Override public void run() { Toast.makeText(BaseActivity.this, "网络请求失败:" + e.getMessage(), 4000).show(); } }); } void httpError(String url, Map<String, Object> params) { mHandler.post(new Runnable() { @Override public void run() { Toast.makeText(BaseActivity.this, "网络请求失败", 300).show(); } }); } }
[b]BaseUtil
这个类是工具类,一并承上,非本人原创。package com.mydemo.common; import java.util.Locale; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.telephony.TelephonyManager; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; import android.widget.Toast; public class BaseUtil { private Context context; protected InputMethodManager imm; private TelephonyManager tManager; public BaseUtil(Context context) { this.context = context; tManager = (TelephonyManager) context.getSystemService(context.TELEPHONY_SERVICE); imm = (InputMethodManager) context.getSystemService(context.INPUT_METHOD_SERVICE); } public void DisPlay(String content) { Toast.makeText(context, content, 1).show(); } public void DisplayToast(String str) { Toast.makeText(context, str, Toast.LENGTH_SHORT).show(); } public void hideOrShowSoftInput(boolean isShowSoft, EditText editText) { if (isShowSoft) { imm.showSoftInput(editText, 0); } else { imm.hideSoftInputFromWindow(editText.getWindowToken(), 0); } } // 获得当前程序版本信息 public String getVersionName() throws Exception { // 获取packagemanager的实例 PackageManager packageManager = context.getPackageManager(); // getPackageName()是你当前类的包名,0代表是获取版本信息 PackageInfo packInfo = packageManager.getPackageInfo(context.getPackageName(), 0); return packInfo.versionName; } // 獲得設備信息 public String getDeviceId() throws Exception { String deviceId = tManager.getDeviceId(); return deviceId; } /** * 获取SIM卡序列号 * * @return */ public String getToken() { return tManager.getSimSerialNumber(); } /* 獲得系統版本 */ public String getClientOs() { return android.os.Build.ID; } /* 獲得系統版本號 */ public String getClientOsVer() { return android.os.Build.VERSION.RELEASE; } // 獲得系統語言包 public String getLanguage() { return Locale.getDefault().getLanguage(); } public String getCountry() { return Locale.getDefault().getCountry(); } }
HttpUtil
该类在BaseActivity中创建,并且保存BaseActivity对象引用。1.使得调用都不需要将自身作为参数进行传递,减小了调用复杂度,
2.使得OkHttpEngine不需要BaseActivity进行绑定,使OkHttpEngine作为完全独立的存在。
package com.mydemo.common; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import android.os.Handler; import android.widget.ImageView; import com.squareup.okhttp.Response; public class HttpUtil { private BaseActivity activity; public HttpUtil(BaseActivity activity) { this.activity = activity; } public void getAsynHttp(String url, Map<String, Object> params) { OkHttpEngine.getInstance().getAsynHttp(activity, url); } public Map<String, Object> getSyncHttp(String url) { try { Response response = OkHttpEngine.getInstance().getSyncHttp(activity, url); Map<String, Object> result = new HashMap<>(); return result; } catch (IOException e) { return null; } } public void post(String url, Map<String, Object> params) { OkHttpEngine.getInstance().postAsynHttp(activity, url, params); } public void downloadFile(final String url, final String destFileDir) { OkHttpEngine.getInstance().downloadFile(activity, url, destFileDir); } public void displayImage(final Handler mHandler, final ImageView view, final String imgUrl, final int errorResId) { OkHttpEngine.getInstance().displayImage(mHandler, view, imgUrl, errorResId); } public void fileUpload(final String url, final Map<String, Object> params, File[] files, String[] fileKeys) { OkHttpEngine.getInstance().fileUpload(activity, url, params, files, fileKeys); } }
ImageUtil
与图片处理相关工具类,非本人原创,一并承上。package com.mydemo.common; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.lang.reflect.Field; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.util.DisplayMetrics; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; /** */ public class ImageUtils { /** * 根据InputStream获取图片实际的宽度和高度 */ public static ImageSize getImageSize(InputStream imageStream) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeStream(imageStream, null, options); return new ImageSize(options.outWidth, options.outHeight); } public static class ImageSize { int width; int height; public ImageSize() { } public ImageSize(int width, int height) { this.width = width; this.height = height; } @Override public String toString() { return "ImageSize{" + "width=" + width + ", height=" + height + '}'; } } public static int calculateInSampleSize(ImageSize srcSize, ImageSize targetSize) { // 源图片的宽度 int width = srcSize.width; int height = srcSize.height; int inSampleSize = 1; int reqWidth = targetSize.width; int reqHeight = targetSize.height; if (width > reqWidth && height > reqHeight) { // 计算出实际宽度和目标宽度的比率 int widthRatio = Math.round((float) width / (float) reqWidth); int heightRatio = Math.round((float) height / (float) reqHeight); inSampleSize = Math.max(widthRatio, heightRatio); } return inSampleSize; } /** * 根据ImageView获适当的压缩的宽和高 */ public static ImageSize getImageViewSize(View view) { ImageSize imageSize = new ImageSize(); imageSize.width = getExpectWidth(view); imageSize.height = getExpectHeight(view); return imageSize; } /** * 根据view获得期望的高度 */ private static int getExpectHeight(View view) { int height = 0; if (view == null) return 0; final ViewGroup.LayoutParams params = view.getLayoutParams(); // 如果是WRAP_CONTENT,此时图片还没加载,getWidth根本无效 if (params != null && params.height != ViewGroup.LayoutParams.WRAP_CONTENT) { height = view.getWidth(); // 获得实际的宽度 } if (height <= 0 && params != null) { height = params.height; // 获得布局文件中的声明的宽度 } if (height <= 0) { height = getImageViewFieldValue(view, "mMaxHeight");// 获得设置的最大的宽度 } // 如果宽度还是没有获取到,憋大招,使用屏幕的宽度 if (height <= 0) { DisplayMetrics displayMetrics = view.getContext().getResources().getDisplayMetrics(); height = displayMetrics.heightPixels; } return height; } /** * 根据view获得期望的宽度 */ private static int getExpectWidth(View view) { int width = 0; if (view == null) return 0; final ViewGroup.LayoutParams params = view.getLayoutParams(); // 如果是WRAP_CONTENT,此时图片还没加载,getWidth根本无效 if (params != null && params.width != ViewGroup.LayoutParams.WRAP_CONTENT) { width = view.getWidth(); // 获得实际的宽度 } if (width <= 0 && params != null) { width = params.width; // 获得布局文件中的声明的宽度 } if (width <= 0) { width = getImageViewFieldValue(view, "mMaxWidth");// 获得设置的最大的宽度 } // 如果宽度还是没有获取到,憋大招,使用屏幕的宽度 if (width <= 0) { DisplayMetrics displayMetrics = view.getContext().getResources().getDisplayMetrics(); width = displayMetrics.widthPixels; } return width; } /** * 通过反射获取imageview的某个属性值 */ private static int getImageViewFieldValue(Object object, String fieldName) { int value = 0; try { Field field = ImageView.class.getDeclaredField(fieldName); field.setAccessible(true); int fieldValue = field.getInt(object); if (fieldValue > 0 && fieldValue < Integer.MAX_VALUE) { value = fieldValue; } } catch (Exception e) { } return value; } public static Bitmap getLoacalBitmap(String url) { try { FileInputStream fis = new FileInputStream(url); return BitmapFactory.decodeStream(fis); } catch (FileNotFoundException e) { e.printStackTrace(); return null; } } }
okHttp封装
说明,这里方法调用里,使用BaseActivity作为参数,可能不是最好的方法,可以考虑使用实现了接口,可能更为妥当。本次暂不深究了。package com.mydemo.common; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.FileNameMap; import java.net.URLConnection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.concurrent.TimeUnit; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Handler; import android.widget.ImageView; import com.squareup.okhttp.Cache; import com.squareup.okhttp.Call; import com.squareup.okhttp.Callback; import com.squareup.okhttp.FormEncodingBuilder; import com.squareup.okhttp.Headers; import com.squareup.okhttp.MediaType; import com.squareup.okhttp.MultipartBuilder; import com.squareup.okhttp.OkHttpClient; import com.squareup.okhttp.Request; import com.squareup.okhttp.RequestBody; import com.squareup.okhttp.Response; public class OkHttpEngine { private static OkHttpEngine okHttpEngine; private OkHttpClient mOkHttpClient; public static synchronized void initEngine() { okHttpEngine = new OkHttpEngine(); } public static OkHttpEngine getInstance() { if (okHttpEngine == null) { initEngine(); } return okHttpEngine; } private OkHttpEngine() { mOkHttpClient = new OkHttpClient(); mOkHttpClient.setConnectTimeout(15, TimeUnit.SECONDS); mOkHttpClient.setWriteTimeout(20, TimeUnit.SECONDS); mOkHttpClient.setReadTimeout(20, TimeUnit.SECONDS); } public OkHttpEngine setCache(Context mContext) { File sdcache = mContext.getExternalCacheDir(); int cacheSize = 10 * 1024 * 1024; mOkHttpClient.setCache(new Cache(sdcache.getAbsoluteFile(), cacheSize)); return okHttpEngine; } /** * @param currentActivity * 当前活动的activity对象 * @param url * 请求地址 * @param params * 参数 */ public void getAsynHttp(final BaseActivity currentActivity, final String url) { final Request request = new Request.Builder().url(url).build(); Call call = mOkHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Request request, IOException e) { } @Override public void onResponse(final Response response) throws IOException { String str = response.body().string(); currentActivity.httpResponse(url, null, str); } }); } public Response getSyncHttp(final BaseActivity currentActivity, final String url) throws IOException { // OkHttpClient mOkHttpClient = new OkHttpClient(); final Request request = new Request.Builder().url(url).build(); Call call = mOkHttpClient.newCall(request); Response mResponse = call.execute(); if (mResponse.isSuccessful()) { currentActivity.httpResponse(url, null, mResponse.body().string()); return mResponse; } else { currentActivity.httpError(url, null); } return null; } public void postAsynHttp(final BaseActivity currentActivity, final String url, final Map<String, Object> params) { // OkHttpClient mOkHttpClient = new OkHttpClient(); FormEncodingBuilder builer = _getFormBuilder(params); Request request = new Request.Builder().url(url).post(builer.build()).build(); Call call = mOkHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Request request, IOException e) { currentActivity.httpError(url, params); } @Override public void onResponse(Response response) throws IOException { currentActivity.httpResponse(url, params, response.body().string()); } }); } public void fileUpload(final BaseActivity currentActivity, final String url, final Map<String, Object> params, File[] files, String[] fileKeys) { Request request = buildMultipartFormRequest(url, files, fileKeys, params); Call call = mOkHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Request request, IOException e) { currentActivity.httpError(url, params); } @Override public void onResponse(Response response) throws IOException { String str = response.body().string(); currentActivity.httpResponse(url, params, response.body().string()); } }); } /** * 下载文件,返回文件绝对路径 * * @param currentActivity * @param url * 文件网络地址 * @param destFileDir * 文件存储位置 */ public void downloadFile(final BaseActivity currentActivity, final String url, final String destFileDir) { final Request request = new Request.Builder().url(url).build(); final Call call = mOkHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(final Request request, final IOException e) { currentActivity.httpError(url, new HashMap<String, Object>()); } @Override public void onResponse(Response response) { InputStream is = null; byte[] buf = new byte[2048]; int len = 0; FileOutputStream fos = null; try { is = response.body().byteStream(); File file = new File(destFileDir, getFileName(url)); fos = new FileOutputStream(file); while ((len = is.read(buf)) != -1) { fos.write(buf, 0, len); } fos.flush(); Map<String, Object> params = new HashMap<String, Object>(); currentActivity.completeDownload(file.getAbsolutePath()); } catch (IOException e) { e.printStackTrace(); currentActivity.httpError(url, new HashMap<String, Object>(), e); } finally { try { if (is != null) is.close(); } catch (IOException e) { } try { if (fos != null) fos.close(); } catch (IOException e) { } } } }); } public void displayImage(final Handler mHandler, final ImageView view, final String imgUrl, final int errorResId) { final Request request = new Request.Builder().url(imgUrl).build(); Call call = mOkHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Request request, IOException e) { mHandler.post(new Runnable() { @Override public void run() { view.setImageResource(errorResId); } }); } @Override public void onResponse(Response response) { InputStream is = null; try { is = response.body().byteStream(); ImageUtils.ImageSize actualImageSize = ImageUtils.getImageSize(is); ImageUtils.ImageSize imageViewSize = ImageUtils.getImageViewSize(view); int inSampleSize = ImageUtils.calculateInSampleSize(actualImageSize, imageViewSize); try { is.reset(); } catch (IOException e) { response = _getAsyn(imgUrl); is = response.body().byteStream(); } BitmapFactory.Options ops = new BitmapFactory.Options(); ops.inJustDecodeBounds = false; ops.inSampleSize = inSampleSize; final Bitmap bm = BitmapFactory.decodeStream(is, null, ops); mHandler.post(new Runnable() { @Override public void run() { view.setImageBitmap(bm); } }); } catch (Exception e) { setErrorResId(mHandler, view, errorResId); } finally { if (is != null) try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } }); } /** * 同步的Get请求 * * @param url * @return Response */ private Response _getAsyn(String url) throws IOException { final Request request = new Request.Builder().url(url).build(); Call call = mOkHttpClient.newCall(request); Response execute = call.execute(); return execute; } private FormEncodingBuilder _getFormBuilder(Map<String, Object> params) { FormEncodingBuilder builder = new FormEncodingBuilder(); if (params != null && params.size() > 0) { Set<Entry<String, Object>> set = params.entrySet(); Iterator<Entry<String, Object>> iterator = set.iterator(); while (iterator.hasNext()) { Entry<String, Object> entry = iterator.next(); builder.add(entry.getKey(), entry.getValue().toString()); } } return builder; } private Request buildMultipartFormRequest(String url, File[] files, String[] fileKeys, final Map<String, Object> params) { MultipartBuilder builder = new MultipartBuilder().type(MultipartBuilder.FORM); if (params != null && params.size() > 0) { Set<Entry<String, Object>> set = params.entrySet(); Iterator<Entry<String, Object>> iterator = set.iterator(); while (iterator.hasNext()) { Entry<String, Object> entry = iterator.next(); builder.addPart(Headers.of(String.format("Content-Disposition", "form-data; name=\"%s\"", entry.getKey())), RequestBody.create(null, entry.getValue().toString())); } } if (files != null) { RequestBody fileBody = null; for (int i = 0; i < files.length; i++) { File file = files[i]; String fileName = file.getName(); fileBody = RequestBody.create(MediaType.parse(guessMimeType(fileName)), file); // TODO 根据文件名设置contentType builder.addPart(Headers.of("Content-Disposition", "form-data; name=\"" + fileKeys[i] + "\"; filename=\"" + fileName + "\""), fileBody); } } RequestBody requestBody = builder.build(); return new Request.Builder().url(url).post(requestBody).build(); } private String guessMimeType(String path) { FileNameMap fileNameMap = URLConnection.getFileNameMap(); String contentTypeFor = fileNameMap.getContentTypeFor(path); if (contentTypeFor == null) { contentTypeFor = "application/octet-stream"; } return contentTypeFor; } private String getFileName(String path) { int separatorIndex = path.lastIndexOf("/"); return (separatorIndex < 0) ? path : path.substring(separatorIndex + 1, path.length()); } private void setErrorResId(final Handler mHandler, final ImageView view, final int errorResId) { mHandler.post(new Runnable() { @Override public void run() { view.setImageResource(errorResId); } }); } }
MainActivity
package com.mydemo.ui; import java.util.HashMap; import java.util.Map; import com.mydemo.MyApplication; import com.mydemo.common.BaseActivity; import com.mydemo.common.ImageUtils; import com.mydemo.okhttp.R; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.widget.ImageView; import android.widget.TextView; public class MainActivity extends BaseActivity { private final String BAIDU_INDEX1 = "http://www.baidu.com"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mHandler = new Handler(getMainLooper()) { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 1: break; } } }; Map<String, Object> p1 = new HashMap<String, Object>(); this.httpUtil.getAsynHttp(BAIDU_INDEX1, p1); // this.getAsynHttp(BAIDU_INDEX2, p1); // // this.getAsynHttp(BAIDU_INDEX3, p1); // 要调用同步GET方法,但需要另起一个子线程发起请求,而不能直接在主线程发起请求。 /* * Thread t = new Thread(new Runnable() { * @Override * public void run() { * Map<String, Object> p1 = new HashMap<>(); * p1.put("s", System.currentTimeMillis()); * MainActivity.this.getSyncHttp(BAIDU_INDEX4, p1); * } * }); * t.start(); */ this.httpUtil.getAsynHttp(BAIDU_INDEX1, p1); ImageView view = findView(R.id.imageview); // 加载图片 this.httpUtil.displayImage(mHandler, view, "https://www.baidu.com/img/bd_logo1.png", R.drawable.no_image); String p = MyApplication.mkdirs("/net_image/a/b"); this.httpUtil.downloadFile("http://a4.att.hudong.com/23/09/01300000165488122547095974400.jpg", p); } @Override public void httpResponse(String url, Map<String, Object> params, Object result) { Message msg = new Message(); switch (url) { case BAIDU_INDEX1: msg.what = 1; msg.obj = result; mHandler.sendMessage(msg); break; } } @Override public void completeDownload(final String abstractPath) { super.completeDownload(abstractPath); mHandler.post(new Runnable() { @Override public void run() { ImageView view5 = findView(R.id.imageview2); view5.setImageBitmap(ImageUtils.getLoacalBitmap(abstractPath)); TextView view1 = findView(R.id.result5); view1.setText("存储位置:" + abstractPath); } }); } @Override protected void httpError(String url, Map<String, Object> params, final Exception e) { mHandler.post(new Runnable() { @Override public void run() { TextView view4 = findView(R.id.result5); view4.setText(e.getMessage()); } }); } }
Application
package com.mydemo; import java.io.File; import android.app.Application; import android.os.Environment; public class MyApplication extends Application { static MyApplication application = new MyApplication(); @Override public void onCreate() { super.onCreate(); } private MyApplication() { } public static MyApplication getApplication() { return application; } public static String getSDPath() { File sdDir = null; boolean sdCardExist = Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);// 判断sd卡是否存在 if (sdCardExist) { sdDir = Environment.getExternalStorageDirectory();// 获取跟目录 } return sdDir.toString(); } public static String mkdirs(String path) { String sdcard = getSDPath(); if (path.indexOf(getSDPath()) == -1) { path = sdcard + (path.indexOf("/") == 0 ? "" : "/") + path; } File destDir = new File(path); if (!destDir.exists()) { path = createDir(path); if (path == null) { return null; } } return path; } //不限层级创建文件夹, private static String createDir(String path) { String sdPath = getSDPath(); String[] dirs = path.replace(sdPath, "").split("/"); StringBuffer filePath = new StringBuffer(sdPath); for (String dir : dirs) { if (!"".equals(dir) && !dir.equals(sdPath)) { filePath.append("/").append(dir); File destDir = new File(filePath.toString()); if (!destDir.exists()) { boolean b = destDir.mkdirs(); if (!b) { return null; } } } } return filePath.toString(); } }
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginLeft="20dp" android:orientation="vertical" > <TextView android:id="@+id/result1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="@string/hello_world" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="百度图片是直接显示的网络图片" /> <ImageView android:id="@+id/imageview" android:layout_width="200dp" android:layout_height="200dp" android:layout_gravity="center_horizontal" android:layout_marginTop="5dp" android:contentDescription="网络图片" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="5dp" android:text="下面这张图是下载在本地后,再加载显示的" /> <TextView android:id="@+id/result5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="@string/hello_world" /> <ImageView android:id="@+id/imageview2" android:layout_width="300dp" android:layout_height="300dp" android:layout_gravity="center_horizontal" android:layout_marginTop="5dp" android:contentDescription="网络图片" /> </LinearLayout>
原谅,代码中注释太少,以后一定改正。
gitHub地址,欢迎Star or Fork!
https://github.com/luodengzhong/okHttpDemo
原源码奉上:
http://download.csdn.net/detail/ldz_wolf/9619513
相关文章推荐
- 简单的封装了一个OKHttp网络请求工具类,直接粘贴进去调用使用,很方便
- 网络请求框架 okhttp 简单的使用总结(一)
- okhttp网络请求框架的简单使用
- android 开发使用okhttp进行网络请求简单介绍(未测试)
- 安卓网络请求框架okHttp的使用与封装
- 使用Retrofit和Okhttp实现网络缓存。无网读缓存,有网根据过期时间重新请求 (转)
- OkGo___简单易用的OkHttp网络请求封装库
- 使用基于Android网络通信的OkHttp库实现Get和Post方式简单操作服务器JSON格式数据
- Android使用Retrofit+OkHttp实现网络请求
- 【封装】使用okHttp发送网络请求及上传下载进度监听
- Retrofit+okhttp3的简单封装实现网络请求和拦截
- 学习笔记 Tianmao 篇 OkHttp 网络的使用的简单封装 获取Json用GSON来解析
- Retrofit + RxJava + OkHttp 让网络请求变的简单-封装篇
- 使用Retrofit和Okhttp实现网络缓存。无网读缓存,有网根据过期时间重新请求
- Retrofit + RxJava + OkHttp 让网络请求变的简单-封装篇
- 网络请求框架(二)----改善的okHttp封装库okhttputils的使用
- 优雅设计封装基于Okhttp3的网络框架(二):多线程下载功能原理设计 及 简单实现
- retrofit+RxJava+okhttp简便封装实现网络请求(详解)
- Android--menu和OkHttp框架(未封装),结合Executors(线程池)实现网络请求的案例
- Android使用okhttpfinal+gson实现网络请求