亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

OkHttp基本使用(三)上傳下載功能實現

2019-11-06 09:44:53
字體:
來源:轉載
供稿:網友
前言本篇將使用OkHttp實現文件的上傳和下載,以及下載實現斷點續傳功能。因為是基本的使用,此系列文章主要是以大家會用為主而寫的。當然,只要會用了,后面的優化、封裝等等就不難了。下載使用OkHttp完成下載功能,實現斷點續傳,并附帶進度條顯示下載進度。文件下載的交互過程: 下載的流程: 文件下載的代碼:public class DownloadActivity extends AppCompatActivity {    PRivate ProgressBar mProgressBar;    //準備下載    public static final int BEGIN = 0;    //正在下載    public static final int DOWNLOADING = 1;    //結束下載    public static final int END = 2;    //下載的進度    private static int progress;    //是否停止下載    private boolean cancel ;    OkHttpClient okHttpClient = new OkHttpClient();    MyHandler mHandler = new MyHandler(this);    private ImageView mShowImage;    ByteArrayOutputStream baos = new ByteArrayOutputStream();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_download);        mProgressBar = (ProgressBar) findViewById(R.id.down_progress_bar);        mShowImage = (ImageView) findViewById(R.id.down_image);    }    public void click2(View view) {        cancel = true;    }    public void click(View view) {        cancel = false;        new Thread(new Runnable() {            @Override            public void run() {                //實例化Builder對象                Request.Builder builder = new Request.Builder();                //設置Url                builder.url(Config.IMAGE_URL);                //獲取已經下載的大小                int size = baos.size();                //size表示已經下載的大小。如果不為0,則進行斷點續傳。                if (size > 0) {                    //設置斷點續傳的開始位置,格式bytes=123456-                    builder.header("Range", "bytes=" + size + "-");                    //設置ProgressBar的當前進度從停止位置開始                    progress = size;                }                //創建Request對象                Request request = builder.build();                try {                    //執行下載請求,并獲得Response對象                    Response response = okHttpClient.newCall(request).execute();                    //請求成功                    if (response.isSuccessful()) {                        //從Response對象中獲取輸入流對象                        InputStream inputStream = response.body().byteStream();                        //size==0表示第一次下載,非斷點續傳                        if (size == 0) {                            //獲取文件的大小                            int contentLength = (int) response.body().contentLength();                            //將文件總大小通過Handler傳遞到UI線程,設置ProgressBar的總進度值                            mHandler.obtainMessage(BEGIN,contentLength,0).sendToTarget();                        }                        int len = 0;                        byte[] buffer = new byte[1024];                        //循環讀取文件流,開始下載                        while((len = inputStream.read(buffer)) != -1) {                            if (cancel) {                                //如果點擊了停止按鈕,cancel為true。則結束循環                                break;                            }                            //將流寫入緩存                            baos.write(buffer,0,len);                            baos.flush();                            //發送下載進度                            mHandler.obtainMessage(DOWNLOADING,len,0).sendToTarget();                        }                        //下載完成,結束請求,關閉body                        response.body().close();                        //將字節轉成Bitmap對象                        byte[] bytes = baos.toByteArray();                        Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);                        //下載完成通知更新試圖                        mHandler.obtainMessage(END,bitmap).sendToTarget();                    }                } catch (IOException e) {                    e.printStackTrace();                }            }        }).start();    }    static class MyHandler extends Handler {        private WeakReference<DownloadActivity> activityWeakReference;        public MyHandler(DownloadActivity activity) {            this.activityWeakReference = new WeakReference<DownloadActivity>(activity);        }        @Override        public void handleMessage(Message msg) {            switch (msg.what) {                case BEGIN:                    activityWeakReference.get().mProgressBar.setMax(msg.arg1);                    break;                case DOWNLOADING:                    progress += msg.arg1;                    activityWeakReference.get().mProgressBar.setProgress(progress);                    break;                case END:                    progress = 0;                    activityWeakReference.get().mShowImage.setImageBitmap((Bitmap)msg.obj);                    break;            }        }    }}復制代碼以上是文件下的代碼。實現了斷點續傳,其中能進行斷點續傳的關鍵代碼為builder.header("Range", "bytes=" + size + "-");代碼中都有注釋,結合上面的流程圖應該不難理解。代碼解釋:源碼的效果是點擊開始按鈕出發click事件開始下載,點擊停止按鈕觸發click2事件中斷下載。下載的進度監聽是在while循環中,通過Handler進行的進度更新。文件上傳本案例中,實現帶參數的文件上傳功能-----同時完成參數傳遞和文件上傳。代碼如下:public class UploadActivity extends AppCompatActivity {    public static final int GET_PIC = 1;    private ImageView mShowImage;    private Uri uri;    OkHttpClient okHttpClient = new OkHttpClient();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_upload);        mShowImage = (ImageView) findViewById(R.id.upload_show_image);    }    public void click(View view) {        switch (view.getId()) {            case R.id.upload_choose_file:                choosePic();//選擇圖片                break;            case R.id.upload_start:                upload();//上傳                break;        }    }    /**     * 上傳     */    private void upload() {        if (uri == null) {            Toast.makeText(UploadActivity.this, "請先選擇文件", Toast.LENGTH_SHORT).show();            return;        }        //設置文件的媒體類型,image/*表示匹配所有的圖片文件        MediaType mediaType = MediaType.parse("image/*");        MultipartBody.Builder builder = new MultipartBody.Builder();        //文件上傳,此處是關鍵,設置媒體類型為multipart/form-data,表示多種格式的表單數據上傳      builder.setType(MultipartBody.FORM);        //添加上傳的參數username=androidxx        builder.addFormDataPart("username","androidxx");        //添加上傳的文件。文件是從相冊讀取的文件流。        try {            //獲得需要上傳的文件流            InputStream inputStream = getContentResolver().openInputStream(uri);            int len = 0;            byte[] buffer = new byte[1024];            ByteArrayOutputStream baos = new ByteArrayOutputStream();            while((len = inputStream.read(buffer)) != -1) {                baos.write(buffer, 0, len);            }            inputStream.close();            /*             * 添加文件到Builder中。如果要實現多文件同時上傳,可以添加多個addFormDataPart。             * 注意:             * 參數一:上傳的文件的標示,同username。也就是可以在服務器端通過upload找到對應的文件流             * 參數二:文件的名稱。上傳到服務器之后以此名稱命名文件             * 參數三:需要上傳的文件。包含在RequestBody中             * RequestBody.create方法有多個重載的方法,可以選擇不同的數據源。此處選擇的是字節形式(baos.toByteArray())的數據眼。             */builder.addFormDataPart("upload", "test.jpg", RequestBody.create(mediaType, baos.toByteArray()));        } catch (IOException e) {            e.printStackTrace();        }        //創建MultipartBody對象,MultipartBody是RequestBody的子類,用于文件上傳。        MultipartBody multipartBody = builder.build();        Request request = new Request.Builder()                .url("http://192.168.3.4:8080/WebServer/upload.do")//上傳的服務器地址                .post(multipartBody)                .build();        //開始上傳。采用Post異步請求的方式        okHttpClient.newCall(request).enqueue(new Callback() {            @Override            public void onFailure(Call call, IOException e) {                Log.d("androidxx.cn","--" + e.getMessage());                e.printStackTrace();            }            @Override            public void onResponse(Call call, Response response) throws IOException {                //接受到成功的返回結果                if (response.isSuccessful()) {                    Log.d("androidxx.cn","-上傳成功-");                } else {                    Log.d("androidxx.cn","-失敗--" + response.body().string());                }            }        });    }    /**     * 打開相冊,選擇文件后返回     */    private void choosePic() {        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);        intent.setType("image/*");        startActivityForResult(intent,GET_PIC);    }    /**     * 接收選擇的圖片     * @param requestCode     * @param resultCode     * @param data     */    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        if (resultCode == RESULT_CANCELED) {            return;        }        //獲得圖片的URI        uri = data.getData();        //通過ContentResolver獲得圖片對象        ContentResolver contentResolver = getContentResolver();        InputStream inputStream = null;        try {            inputStream = contentResolver.openInputStream(uri);        } catch (FileNotFoundException e) {            e.printStackTrace();        }        //將流轉換成圖片,顯示到ImageView中        Bitmap bitmap = BitmapFactory.decodeStream(inputStream);        mShowImage.setImageBitmap(bitmap);    }}復制代碼如上代碼,第37行和第59行是上傳能成功的重點。多文件長傳實現多文件上傳,只需將上面單文件上傳中的builder.addFormDataPart("upload", "test.jpg", RequestBody.create(mediaType, baos.toByteArray()));這一句執行多次,即使用多個addFormDataPart方法添加多個文件,然后就可以同時上傳多個文件了。總結1、文件上傳和下載的過程其實就是一種特殊的Post和Get請求??傮w的過程與Post請求和Get請求方式一樣。2、下載相當于一個特殊的Get請求,只是服務器返回的數據格式是文件流。我們也只能通過讀取流來獲得數據。3、上傳相當于一個特殊的Post請求,前面我們說過,Post請求就是傳參數比較特殊和多樣化。文件上傳就是一種特殊的參數傳遞----參數是一個文件。大家在看如上代碼的時候,不要覺得陌生,其實代碼的流程和邏輯同Post和Get請求一樣,只是多了幾行代碼。本案例的android端源碼:Github本案例的上傳服務器配置方式【點擊查看】,上傳服務端源碼:Github     服務器端代碼請閱讀Github中的readme.md文件。服務器端代碼導入工程沒有錯之后,可以將代碼加載到服務器,之后啟動服務器就可以運行。本案例使用的是Tomcat服務器。備注:對于android程序員如果想運行服務器代碼,按照readme.md文檔。然后有不懂的,可以留言。轉載請注明:androidxx.cn最后附上下載效果(注意點擊按鈕開始和停止后下載進度條的變化,實現斷點續傳)。 
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品福利无圣光在线一区| 91久久精品久久国产性色也91| 久久久亚洲网站| 亚洲人成网站777色婷婷| 国产精品一区二区久久久| 亚洲天堂第一页| 国产精品中文在线| 亚州成人av在线| 81精品国产乱码久久久久久| 久久久久久网址| 国产欧美精品日韩| 日韩电影中文字幕| 国产精品丝袜久久久久久高清| www.亚洲天堂| 久久这里只有精品视频首页| 在线日韩第一页| 成人免费网视频| 国产97在线观看| 亚洲精品中文字幕有码专区| 97国产精品免费视频| 国产亚洲精品久久久久久| 亚洲大胆美女视频| 国产精品视频精品视频| 成人看片人aa| 视频在线一区二区| 伊人久久久久久久久久| 在线激情影院一区| 国产精品久久久久7777婷婷| 亚洲欧洲高清在线| 欧美日韩福利视频| 国产主播喷水一区二区| 亚洲人成欧美中文字幕| 亚洲小视频在线| 国产在线拍揄自揄视频不卡99| 久久久最新网址| 久久精品一偷一偷国产| 国产精品久久激情| 日本精品va在线观看| 欧美在线免费看| 久久久久久久久91| 中文字幕综合一区| 成人激情视频小说免费下载| 国产精品99久久久久久久久久久久| 亚洲第一男人av| 日本亚洲精品在线观看| 亚洲精品免费在线视频| 成人女保姆的销魂服务| 欧美视频在线看| 国自在线精品视频| 国产高清视频一区三区| 亚洲第一精品自拍| 国产精品久久久久久久久久新婚| 欧美成人午夜视频| 国产欧亚日韩视频| 国产亚洲欧洲黄色| 亚洲性av网站| 久久久99免费视频| 97免费中文视频在线观看| 欧美福利视频在线| 亚洲第一色中文字幕| 日本成人精品在线| 亚洲性猛交xxxxwww| 欧美猛交免费看| 国产成人精品日本亚洲专区61| 亚洲午夜未满十八勿入免费观看全集| 日韩中文字幕在线| 日韩成人av一区| 久久夜色精品国产欧美乱| 色无极影院亚洲| 欧美精品久久久久a| 欧美大胆a视频| 欧美大片免费观看在线观看网站推荐| 亚洲第一二三四五区| 国产亚洲精品久久久久动| 亚洲精品日韩激情在线电影| 中文字幕综合在线| 国产精品女人网站| 欧美中文在线观看国产| 中文字幕精品在线视频| 欧美日韩亚洲网| 久久久成人av| 欧美大尺度激情区在线播放| 亚洲аv电影天堂网| 国自产精品手机在线观看视频| 久久精品国产2020观看福利| 欧美亚洲在线播放| 欧美视频中文字幕在线| 国产午夜精品久久久| 久久久久国产精品免费网站| 97精品伊人久久久大香线蕉| 亚洲专区在线视频| 欧美男插女视频| 亚洲精品久久久久中文字幕欢迎你| 日韩视频精品在线| 欧美成人亚洲成人| 亚洲欧美日韩久久久久久| 欧美国产高跟鞋裸体秀xxxhd| 97在线看免费观看视频在线观看| 日韩大胆人体377p| 美女视频久久黄| 色诱女教师一区二区三区| 91国内精品久久| 狠狠躁18三区二区一区| 96精品久久久久中文字幕| 久久久爽爽爽美女图片| 中文字幕一区二区三区电影| 97在线视频免费看| 中国日韩欧美久久久久久久久| 亚洲亚裔videos黑人hd| 2019中文字幕全在线观看| 久久久久久这里只有精品| 亚洲欧美自拍一区| 成人春色激情网| 亚洲精品福利在线观看| 久久色免费在线视频| 91福利视频网| 欧美大片欧美激情性色a∨久久| 国产欧美一区二区三区在线| 操91在线视频| 中文字幕亚洲欧美一区二区三区| 中文字幕日韩精品在线| 亚洲欧洲美洲在线综合| 久久久久久久久久久网站| 亚洲成人精品在线| 欧美一区二区三区……| 亚洲肉体裸体xxxx137| 精品视频在线播放免| 91精品在线观看视频| 亚洲国产欧美精品| 日韩av在线免费观看一区| 欧美一级在线播放| 国产婷婷色综合av蜜臀av| 国产精品日日做人人爱| 久久这里有精品视频| 成人国产精品一区二区| 国产精品视频免费观看www| 欧美精品video| 国产成人亚洲综合91| 黑人极品videos精品欧美裸| 亚洲欧美日韩直播| 欧美精品中文字幕一区| 欧美国产精品va在线观看| 国产一区二区av| …久久精品99久久香蕉国产| 欧美日韩ab片| 国产亚洲欧美日韩精品| 成人网欧美在线视频| 国产精品吹潮在线观看| 国产精品美女久久| 在线观看亚洲视频| 欧美中文字幕第一页| 人九九综合九九宗合| 国产精品永久免费视频| 欧美另类高清videos| 日韩av免费一区| 午夜精品久久久久久久男人的天堂| 日韩欧美亚洲一二三区| 一区二区中文字幕| 欧美精品福利在线| 亚洲成人黄色网| 97人人爽人人喊人人模波多| 欧美巨大黑人极品精男| 精品视频在线导航| 亚洲国产福利在线|