OkHttp是比較火的網(wǎng)絡(luò)框架,它支持同步與異步請(qǐng)求,支持緩存,可以攔截,更方便下載大文件與上傳文件的操作。下面我們用OkHttp來下載文件并帶進(jìn)度條!
目前創(chuàng)新互聯(lián)公司已為1000+的企業(yè)提供了網(wǎng)站建設(shè)、域名、雅安服務(wù)器托管、網(wǎng)站托管、企業(yè)網(wǎng)站設(shè)計(jì)、涿鹿網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。
相關(guān)資料:
官網(wǎng)地址:http://square.github.io/okhttp/
github源碼地址:https://github.com/square/okhttp
一、服務(wù)器端簡(jiǎn)單搭建
可以參考搭建本地Tomcat服務(wù)器及相關(guān)配置 這篇文章。
新建項(xiàng)目OkHttpServer,在WebContent目錄下新建downloadfile目錄,將要下載的jpg文件放在項(xiàng)目下。如下圖:
啟動(dòng)服務(wù)器,文件下載地址為http://localhost:8080/OkHttpServer/download/2.jpg 。這樣我們服務(wù)器就搭好了。
二、Android端
下面我們進(jìn)入正題。
1.build.gradle的dependencies配置如下
compile 'com.android.support:appcompat-v7:24.1.1' compile 'com.squareup.okhttp3:okhttp:3.2.0' compile 'com.squareup.okio:okio:1.7.0'
2.activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
3.編寫OkHttpUtil如下:
private static OkHttpClient okHttpClient = new OkHttpClient.Builder().connectTimeout(10000, TimeUnit.MILLISECONDS) .readTimeout(10000,TimeUnit.MILLISECONDS) .writeTimeout(10000,TimeUnit.MILLISECONDS).build(); //下載文件方法 public static void downloadFile(String url, final ProgressListener listener, Callback callback){ //增加攔截器 OkHttpClient client = okHttpClient.newBuilder().addNetworkInterceptor(new Interceptor() { @Override public Response intercept(Chain chain) throws IOException { Response response = chain.proceed(chain.request()); return response.newBuilder().body(new ProgressResponseBody(response.body(),listener)).build(); } }).build(); Request request = new Request.Builder().url(url).build(); client.newCall(request).enqueue(callback); }
4.上面代碼中的ProgressResponseBody是自己編寫的類,ProgressListener 是監(jiān)聽的接口:
ProgressListener 接口
public interface ProgressListener { //已完成的 總的文件長(zhǎng)度 是否完成 void onProgress(long currentBytes, long contentLength, boolean done); }
ProgressResponseBody繼承ResponseBody ,返回監(jiān)聽進(jìn)度
public class ProgressResponseBody extends ResponseBody { public static final int UPDATE = 0x01; public static final String TAG = ProgressResponseBody.class.getName(); private ResponseBody responseBody; private ProgressListener mListener; private BufferedSource bufferedSource; private Handler myHandler; public ProgressResponseBody(ResponseBody body, ProgressListener listener) { responseBody = body; mListener = listener; if (myHandler==null){ myHandler = new MyHandler(); } } /** * 將進(jìn)度放到主線程中顯示 */ class MyHandler extends Handler { public MyHandler() { super(Looper.getMainLooper()); } @Override public void handleMessage(Message msg) { switch (msg.what){ case UPDATE: ProgressModel progressModel = (ProgressModel) msg.obj; //接口返回 if (mListener!=null)mListener.onProgress(progressModel.getCurrentBytes(),progressModel.getContentLength(),progressModel.isDone()); break; } } } @Override public MediaType contentType() { return responseBody.contentType(); } @Override public long contentLength() { return responseBody.contentLength(); } @Override public BufferedSource source() { if (bufferedSource==null){ bufferedSource = Okio.buffer(mySource(responseBody.source())); } return bufferedSource; } private Source mySource(Source source) { return new ForwardingSource(source) { long totalBytesRead = 0L; @Override public long read(Buffer sink, long byteCount) throws IOException { long bytesRead = super.read(sink, byteCount); totalBytesRead +=bytesRead!=-1?bytesRead:0; //發(fā)送消息到主線程,ProgressModel為自定義實(shí)體類 Message msg = Message.obtain(); msg.what = UPDATE; msg.obj = new ProgressModel(totalBytesRead,contentLength(),totalBytesRead==contentLength()); myHandler.sendMessage(msg); return bytesRead; } }; } }
5.MainActivity的代碼:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{ public static final String TAG = MainActivity.class.getName(); private ProgressBar download_progress; private TextView download_text; public static String basePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/okhttp"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); download_progress = (ProgressBar) findViewById(R.id.download_progress); download_text = (TextView) findViewById(R.id.download_text); findViewById(R.id.ok_download).setOnClickListener(this); } @Override public void onClick(View view) { switch (view.getId()){ case R.id.ok_download: String url = "http://192.168.0.104:8080/OkHttpServer/download/2.jpg"; final String fileName = url.split("/")[url.split("/").length - 1]; Log.i(TAG, "fileName==" + fileName); OkHttpUtil.downloadFile(url, new ProgressListener() { @Override public void onProgress(long currentBytes, long contentLength, boolean done) { Log.i(TAG, "currentBytes==" + currentBytes + "==contentLength==" + contentLength + "==done==" + done); int progress = (int) (currentBytes * 100 / contentLength); download_progress.setProgress(progress); download_text.setText(progress + "%"); } }, new Callback() { @Override public void onFailure(Call call, IOException e) { } @Override public void onResponse(Call call, Response response) throws IOException { if (response != null) { InputStream is = response.body().byteStream(); FileOutputStream fos = new FileOutputStream(new File(basePath + "/" + fileName)); int len = 0; byte[] buffer = new byte[2048]; while (-1 != (len = is.read(buffer))) { fos.write(buffer, 0, len); } fos.flush(); fos.close(); is.close(); } } }); break; } } }
6.最后不要忘了添加權(quán)限:
源碼下載
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。