- 普通的Get请求
case R.id.get:
HttpManager.getInstance().getRequest(getUri,this);
break;
//方法的回调
@Override
public void onFailure(Call call, IOException e) {//子线程
Log.d("flag", "----------------->onFailure: ");
}
@Override
public void onResponse(Call call, Response response) throws IOException {
byte[] bytes = response.body().bytes();
Log.d("flag", "------>onResponse: 获取图片字节长度: " +bytes.length);
final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
runOnUiThread(new Runnable() {
@Override
public void run() {
mImageView.setImageBitmap(bitmap);
Log.d("flag", "------->run: 图片加载成功");
}
});
}
为了方便调用请求,创建单例模式调用方法
public void getRequest(String url, Callback callback){
Request request = new Request.Builder()
.url(url)
.build();
mOkHttpClient.newCall(request).enqueue(callback);
}
OkHttp是在子线程中,注意更新UI操作
- POST请求
public void postRequest(String url, RequestBody requestBody, Callback callback){
Request request = new Request.Builder()
.url(url)
.post(requestBody)//请求体,参数
.build();
mOkHttpClient.newCall(request).enqueue(callback);
}
case R.id.post:
RequestBody requestBody = new FormBody.Builder()
.add("name","michael")
.add("age","25")
.add("tel","666")
.build();
HttpManager.getInstance().postRequest(postUri,requestBody,this);
此处的回调方法依旧是Get请求当中的加载图片
- 文件的上传(post类似,添加请求体)
//上传数据给服务器
public void uploadImage(String url, RequestBody uploadBody, Callback callback) {
Request request = new Request.Builder()
.url(url)
.post(uploadBody)
.build();
mOkHttpClient.newCall(request).enqueue(callback);
}
addFormDataPart(请求体)
case upload://上传数据给服务器,也是post请求,post请求有请求体,将文件包裹到请求体,进行上传
//multipart/form-data 上传文件
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath()
+ File.separator + "icon.jpg";
File file = new File(path);
RequestBody body = RequestBody.create(MediaType.parse("image/*"),file);
RequestBody uploadBody = new MultipartBody.Builder()
.addFormDataPart("name","softpo")
.addFormDataPart("age","34")
.addFormDataPart("tel","0987654321")
.addFormDataPart("image","softpo.jpg",body)
.build();
HttpManager.getInstance().uploadImage(uploadUri,uploadBody, new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.d("flag", "----------------->onFailure: " +e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
Log.d("flag", "----------------->onResponse: " +response.body().string());
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "文件上传成功", Toast.LENGTH_SHORT).show();
}
});
}
});
break;
- 文件的断点续传
核心:
1.请求网址计算内容的总长度
2.创建线程池的对象
3.分配线程的执行长度(开始和结束)
4.根据开始和结束-添加addHeader请求头
5.根据Respose获取输入流,读取写入文件
6.接口回调,加载图片
case R.id.download_range:
DownloadManager.getInstance().download(imageUrl,this);
break;
public class DownloadManager {
//线程池
public static final int MAX_SIZE = 2;
private ThreadPoolExecutor mThreadPoolExecutor = new ThreadPoolExecutor(
MAX_SIZE,
MAX_SIZE,
60,
TimeUnit.MILLISECONDS,
new SynchronousQueue<Runnable>(),//线程管理队列
new ThreadFactory() {
AtomicInteger mAtomicInteger = new AtomicInteger();
@Override
public Thread newThread(Runnable r) {
//参数二区分线程
Thread thread =
new Thread(r,"Thread Number # "+mAtomicInteger.getAndIncrement());
return thread;
}
}
);
private static DownloadManager ourInstance = new DownloadManager();
public static DownloadManager getInstance() {
return ourInstance;
}
private DownloadManager() {
}
public void download(final String url, final Callback callback){
HttpManager.getInstance().getRequest(url, new okhttp3.Callback() {
@Override
public void onFailure(Call call, IOException e) {
callback.onFailure(e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
//要下载内容的总长度
long contentLength = response.body().contentLength();
//多线程下载
processDownload(url,contentLength,callback);
}
});
}
private void processDownload(String url, long contentLength, Callback callback) {
int length = (int) (contentLength/MAX_SIZE);
for (int i = 0; i < MAX_SIZE; i++) {//执行两次
int start = i*length;
//奇数:9 4.5 0-4 --- 4+
//偶数:10 5 0-4 --- 4+
int end = 0;
//奇数偶数(类似)
if(contentLength%2==1){
end = (i+1)*length;
}else {//偶数
end = (i+1)*length-1;
}
mThreadPoolExecutor.execute(new DownloadRunnable(url,start,end,callback));
}
}
}
根据循环每个线程去执行start和end
public class DownloadRunnable implements Runnable {
private String mUrl;
private int mStart;
private int mEnd;
private Callback mCallback;
public DownloadRunnable(String url, int start, int end, Callback callback) {
this.mUrl = url;
this.mStart = start;
this.mEnd = end;
this.mCallback = callback;
}
@Override
public void run() {//子线程
Response response = HttpManager.getInstance().asyncGetRangeBytes(mUrl, mStart, mEnd);
try {
InputStream is = response.body().byteStream();
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
.getAbsolutePath() + File.separator
+ mUrl.substring(mUrl.lastIndexOf("/") + 1);
File file = new File(path);
RandomAccessFile randomAccessFile = new RandomAccessFile(file,"rwd");//rwd:可读可写可追加
//!!!
randomAccessFile.seek(mStart);
//写数据
int len = 0;
byte[] buf = new byte[1024*8];
while((len = is.read(buf))!=-1){
randomAccessFile.write(buf,0,len);
}
//回调
mCallback.onSuccess(file);
} catch (IOException e) {
e.printStackTrace();
}
}
}
HttpManager中创建获取RangeBytes的方法
public Response asyncGetRangeBytes(String imageUrl,int start,int end){
//断点获取服务器的数据
Request request = new Request.Builder()
.url(imageUrl)
.addHeader("range","bytes="+start+"-"+end)//请求头
.build();
//execute OkHttp执行联网请求,下载数据
try {
return mOkHttpClient.newCall(request).execute();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
接口回调,设置图片
@Override
public void onFailure(String message) {
Log.d("flag", "----------------->onFailure: 多线程下载失败");
}
@Override
public void onSuccess(File file) {
Log.d("flag", "----------------->onSuccess: 多线程下载图片成功");
final Bitmap bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
runOnUiThread(new Runnable() {
@Override
public void run() {
mImageView.setImageBitmap(bitmap);
}
});
}
所用的接口
public interface Callback {
void onFailure(String message);
void onSuccess(File file);
}
代码已经上传: