溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

android中怎么實現(xiàn)下載功能

發(fā)布時間:2021-06-29 15:58:27 來源:億速云 閱讀:242 作者:Leah 欄目:移動開發(fā)

這篇文章將為大家詳細講解有關android中怎么實現(xiàn)下載功能,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

一:使用多線程實現(xiàn)下載

    private EditText etpath;//服務地址
    private LinearLayout ll ;
    // 訪問服務器
    String path ;
    // 設定線程的數(shù)量
    int threadcount = 3;
    //定義正在執(zhí)行的線程數(shù)量
    int runningThreadcount = threadcount ;   
    //建一個集合存放進度條
    List<ProgressBar> list = new ArrayList<ProgressBar>() ;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        etpath = (EditText) findViewById(R.id.etpath);       
        ll = (LinearLayout) findViewById(R.id.ll) ;   

        // 加載進度條控件
        for (int i = 0; i < threadcount; i++) {
            ProgressBar pb = (ProgressBar)View.inflate(this, R.layout.pb, null) ;           
        }
    }

    public void download(View view){

        //將進度條加入到線性組件中顯示出來

        for(int i = 0; i < threadcount; i++){

        ll.addView(list.get(i));}

        new Thread() {
            public void run() {
                
                path = etpath.getText().toString().trim();

                if (TextUtils.isEmpty(path)) {
                    runOnUiThread(new Runnable() {

                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, "路徑不能為空", 0)
                                    .show();
                        }
                    });
                    return;
                }
                // 下載文件
                try {
                    // 創(chuàng)建連接服務器對象
                    URL url = new URL(path);
                    HttpURLConnection http = (HttpURLConnection) url
                            .openConnection();
                    // 設定連接參數(shù)
                    http.setRequestMethod("GET");
                    // 設定連接的超時時間
                    http.setConnectTimeout(5000);
                    // 獲取返回的狀態(tài)嗎
                    int code = http.getResponseCode();
                    if (code == 200) {
                        // 獲得返回的文件的大小
                        int length = http.getContentLength();
                        // 2.創(chuàng)建一個文件和下載的文件大小一樣
                        RandomAccessFile raf = new RandomAccessFile(
                                getFileName(path), "rw");
                        // 設置文件的大小
                        raf.setLength(length);
                        // 3.啟動多個線程下載文件
                        for (int id = 0; id < threadcount; id++) {
                            // 計算每個線程要下載的區(qū)塊大小
                            int blocksize = length / threadcount;
                            // 計算每個線程下載的開始和結束位置
                            int startIndex = id * blocksize;
                            int endIndex = (id + 1) * blocksize - 1;
                            // 特殊情況:最后一個線程需要承擔更多的數(shù)據(jù)
                            if (id == threadcount - 1) {
                                endIndex = length - 1;
                            }
                            // 啟動線程下載數(shù)據(jù)
                            DownLoadThread dlt = new DownLoadThread(path, id,
                                    startIndex, endIndex);
                            dlt.start();
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    runOnUiThread(new Runnable() {
                        
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, "網絡連接錯誤", 0).show() ;
                        }
                    }) ;
                }
            };
        }.start();

}

//專門下載的類

    // 專門下載的類
    public class DownLoadThread extends Thread {
        private String path;
        private int id;
        private int startIndex;
        private int endIndex;

        public DownLoadThread(String path, int id, int startIndex, int endIndex) {
            this.path = path;
            this.id = id;
            this.startIndex = startIndex;
            this.endIndex = endIndex;
        }
        @Override
        public void run() {           
            //設置進度條
            ProgressBar pb =  list.get(id) ;                      
            int total = 0;// 記錄每個線程已經下載了多少字節(jié)
            try {
                URL url = new URL(path);
                HttpURLConnection http = (HttpURLConnection) url
                        .openConnection();
                http.setRequestMethod("GET");
                http.setConnectTimeout(5000);
                // 讀取相應的文件,判斷文件是否存在,存在的話,應讀取里面的數(shù)據(jù)
                //拿到sd卡的文件an存儲路徑
                String cunPath = Environment.getExternalStorageDirectory().getAbsolutePath() ;
                File file = new File(cunPath + "/" + id + ".txt");
                if (file.exists() && file.length() > 0) {
                    FileInputStream fis = new FileInputStream(file);
                    BufferedReader br = new BufferedReader(
                            new InputStreamReader(fis));
                    total = Integer.parseInt(br.readLine());
                    br.close();
                    // 改變線程下載的起始位置
                    startIndex =  startIndex + total;
                    System.out.println("線程" + id + "下載的真實范圍:" + startIndex
                            + "~" + endIndex);
                }              
                //設置最大值
                pb.setMax(endIndex-startIndex) ;

                // 注意,一定要設置一個請求頭(范圍),指定此線程要下載的數(shù)據(jù)的范圍
                http.setRequestProperty("Range", "bytes=" + startIndex + "-"
                        + endIndex);

                int code = http.getResponseCode();
                // 200代表的是服務器把數(shù)據(jù)向客戶端傳輸完畢,206代表的是服務端傳輸局部數(shù)據(jù)完畢
                System.out.println("code =" + code);
                if (code == 206) {

                    InputStream is = http.getInputStream();
                    // 拿到已經在硬盤上的對應的文件
                    RandomAccessFile raf = new RandomAccessFile(
                            getFileName(path), "rw");
                    // 將文件的指針移動到開始寫入的位置
                    raf.seek(startIndex);
                    // 將流中的數(shù)據(jù)寫入到文件中

                    byte[] bs = new byte[1024];
                    int b = 0;

                    while ((b = is.read(bs)) != -1) {
                        raf.write(bs, 0, b);

                        total += b;

                        // 真正同步寫入到底層的存儲設備上
                        RandomAccessFile f = new RandomAccessFile(cunPath + "/" + id + ".txt",
                                "rws");
                        f.write((total + "").getBytes());
                        f.close();
                        
                        //改變進度條的當前位置
                        pb.setProgress(total) ;
                    }

                    raf.close();
                    is.close();

                    System.out.println("線程" + id + "下載完畢");
                    System.out.println("線程" + id + "下載的范圍是:" + startIndex
                            + " ~" + endIndex);
                    
                    runningThreadcount-- ;
                    System.out.println(runningThreadcount);
                    if(runningThreadcount == 0){
                        //所有的線程都下載完畢了
                        runOnUiThread(new Runnable() {
                            
                            @Override
                            public void run() {
                                Toast.makeText(MainActivity.this, "文件下載成功", 0).show() ;
                            }
                        }) ;
                    }
                    // 將對應的臨時文件刪除
                    File tempFile = new File(cunPath + "/" + id + ".txt");
                    if (tempFile.exists())
                        tempFile.delete();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 通過用戶傳遞的路徑拿到文件名
     *
     * @param path
     * @return
     */
    public static String getFileName(String path) {
        String externalPath = Environment.getExternalStorageDirectory().getAbsolutePath() ;
        return  externalPath + "/" +path.substring(path.lastIndexOf("/") + 1);
    }

關于android中怎么實現(xiàn)下載功能就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI