Android实现网络多线程断点续传下载.docx

上传人:b****9 文档编号:25220980 上传时间:2023-06-06 格式:DOCX 页数:23 大小:168.66KB
下载 相关 举报
Android实现网络多线程断点续传下载.docx_第1页
第1页 / 共23页
Android实现网络多线程断点续传下载.docx_第2页
第2页 / 共23页
Android实现网络多线程断点续传下载.docx_第3页
第3页 / 共23页
Android实现网络多线程断点续传下载.docx_第4页
第4页 / 共23页
Android实现网络多线程断点续传下载.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

Android实现网络多线程断点续传下载.docx

《Android实现网络多线程断点续传下载.docx》由会员分享,可在线阅读,更多相关《Android实现网络多线程断点续传下载.docx(23页珍藏版)》请在冰豆网上搜索。

Android实现网络多线程断点续传下载.docx

Android实现网络多线程断点续传下载

 

使用多线程的好处:

使用多线程下载会提升文件下载的速度。

那么多线程下载文件的过程是:

 

 

(1)首先获得下载文件的长度,然后设置本地文件的长度。

    HttpURLConnection.getContentLength();//获取下载文件的长度

   RandomAccessFilefile=newRandomAccessFile("QQWubiSetup.exe","rwd");

     file.setLength(filesize);//设置本地文件的长度

 

  

(2)根据文件长度和线程数计算每条线程下载的数据长度和下载位置。

    如:

文件的长度为6M,线程数为3,那么,每条线程下载的数据长度为2M,每条线程开始下载的位置如下图所示。

  

   例如10M大小,使用3个线程来下载,

     线程下载的数据长度 (10%3==0?

10/3:

10/3+1),第1,2个线程下载长度是4M,第三个线程下载长度为2M

      下载开始位置:

线程id*每条线程下载的数据长度=?

     下载结束位置:

(线程id+1)*每条线程下载的数据长度-1=?

 

  (3)使用Http的Range头字段指定每条线程从文件的什么位置开始下载,下载到什么位置为止,

      如:

指定从文件的2M位置开始下载,下载到位置(4M-1byte)为止

      代码如下:

HttpURLConnection.setRequestProperty("Range","bytes=2097152-4194303");

 

  (4)保存文件,使用RandomAccessFile类指定每条线程从本地文件的什么位置开始写入数据。

RandomAccessFile threadfile =new RandomAccessFile("QQWubiSetup.exe","rwd");

threadfile.seek(2097152);//从文件的什么位置开始写入数据

 

  程序结构如下图所示:

 

 

  string.xml文件中代码:

 

xml version="1.0" encoding="utf-8"?

    Hello World, MainActivity!

    Android网络多线程断点下载

    下载路径

    下载

    SDCard不存在或者写保护

    下载完成

    下载失败

 main.xml文件中代码:

 

 

xml version="1.0" encoding="utf-8"?

>   

android="

android:

orientation="vertical"   

android:

layout_width="fill_parent"    

android:

layout_height="fill_parent">

    

-- 下载路径 -->

    

        android:

layout_width="fill_parent"

        android:

layout_height="wrap_content"

        android:

text="@string/path"/>

    

        android:

id="@+id/path" 

        android:

text=" 

        android:

layout_width="fill_parent" 

        android:

layout_height="wrap_content">

    

    

-- 下载按钮 -->

    

        android:

layout_width="wrap_content"

        android:

layout_height="wrap_content"

        android:

text="@string/downloadbutton"

        android:

id="@+id/button"/>

    

-- 进度条 -->

    

        android:

layout_width="fill_parent"

        android:

layout_height="20dip"

        style="?

android:

attr/progressBarStyleHorizontal"

        android:

id="@+id/downloadbar" />

    

        android:

layout_width="fill_parent"

        android:

layout_height="wrap_content"

        android:

gravity="center"

        android:

id="@+id/resultView" />

    

 

AndroidManifest.xml文件中代码:

 

xml version="1.0" encoding="utf-8"?

>

android="      package="com.android.downloader"      android:

versionCode="1"      android:

versionName="1.0">

    

minSdkVersion="8" />

    

icon="@drawable/icon" android:

label="@string/app_name">

        

name=".MainActivity"

                  android:

label="@string/app_name">

            

                

name="android.intent.action.MAIN" />

                

name="android.intent.category.LAUNCHER" />

            

        

    

    

    

-- 在SDCard中创建与删除文件权限 -->

    

name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

    

    

-- 往SDCard写入数据权限 -->

    

name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    

    

-- 访问internet权限 -->

    

name="android.permission.INTERNET"/>

  

 MainActivity中代码:

 

package com.android.downloader;

import java.io.File;

import work.DownloadProgressListener;

import work.FileDownloader;

import android.app.Activity;

import android.os.Bundle;

import android.os.Environment;

import android.os.Handler;

import android.os.Message;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.ProgressBar;

import android.widget.TextView;

import android.widget.Toast;

public class MainActivity extends Activity {

    private EditText downloadpathText;

    private TextView resultView;

    private ProgressBar progressBar;

    

    /**

     * 当Handler被创建会关联到创建它的当前线程的消息队列,该类用于往消息队列发送消息

     * 消息队列中的消息由当前线程内部进行处理

     */

    private Handler handler = new Handler(){

        @Override

        public void handleMessage(Message msg) {            

            switch (msg.what) {

            case 1:

                

                progressBar.setProgress(msg.getData().getInt("size"));

                float num = (float)progressBar.getProgress()/(float)progressBar.getMax();

                int result = (int)(num*100);

                resultView.setText(result+ "%");

                

                if(progressBar.getProgress()==progressBar.getMax()){

                    Toast.makeText(MainActivity.this, R.string.success, 1).show();

                }

                break;

            case -1:

                Toast.makeText(MainActivity.this, R.string.error, 1).show();

                break;

            }

        }

    };

    

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        

        downloadpathText = (EditText) this.findViewById(R.id.path);

        progressBar = (ProgressBar) this.findViewById(R.id.downloadbar);

        resultView = (TextView) this.findViewById(R.id.resultView);

        Button button = (Button) this.findViewById(R.id.button);

        

        button.setOnClickListener(new View.OnClickListener() {

            

            @Override

            public void onClick(View v) {

                // TODO Auto-generated method stub

                String path = downloadpathText.getText().toString();

                System.out.println(Environment.getExternalStorageState()+"------"+Environment.MEDIA_MOUNTED);

                

                if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){

                    download(path, Environment.getExternalStorageDirectory());

                }else{

                    Toast.makeText(MainActivity.this, R.string.sdcarderror, 1).show();

                }

            }

        });

    }

    

      /**

       * 主线程(UI线程)

       * 对于显示控件的界面更新只是由UI线程负责,如果是在非UI线程更新控件的属性值,更新后的显示界面不会反映到屏幕上

       * @param path

       * @param savedir

       */

    private void download(final String path, final File savedir) {

        new Thread(new Runnable() {            

            @Override

            public void run() {

                FileDownloader loader = new FileDownloader(MainActivity.this, path, savedir, 3);

                progressBar.setMax(loader.getFileSize());//设置进度条的最大刻度为文件的长度

                

                try {

                    loader.download(new DownloadProgressListener() {

                        @Override

                        public void onDownloadSize(int size) {//实时获知文件已经下载的数据长度

                            Message msg = new Message();

                            msg.what = 1;

                            msg.getData().putInt("size", size);

                            handler.sendMessage(msg);//发送消息

                        }

                    });

                } catch (Exception e) {

                    handler.obtainMessage(-1).sendToTarget();

                }

            }

        }).start();

    }

}  

DBOpenHelper中代码:

 

package com.android.service;

import android.content.Context;

import android.database.sqlite.SQLiteDatabase;

import android.database.sqlite.SQLiteOpenHelper;

public class DBOpenHelper extends SQLiteOpenHelper {

    private static final String DBNAME = "down.db";

    private static final int VERSION = 1;

    

    public DBOpenHelper(Context context) {

        super(context, DBNAME, null, VERSION);

    }

    

    @Override

    public void onCreate(SQLiteDatabase db) {

        db.execSQL("CREATE TABLE IF NOT EXISTS filedownlog (id integer primary key autoincrement, downpath varchar(100), threadid INTEGER, downlength INTEGER)");

    }

    @Override

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        db.execSQL("DROP TABLE IF EXISTS filedownlog");

        onCreate(db);

    }

}

  

FileService中代码:

 

package com.android.service;

import java.util.HashMap;

import java.util.Map;

import android.content.Context;

import android.database.Cursor;

import android.database.sqlite.SQLiteDatabase;

public class FileService {

    private DBOpenHelper openHelper;

    public FileService(Context context) {

        openHelper = new DBOpenHelper(context);

    }

    

    /**

     * 获取每条线程已经下载的文件长度

     * @param path

     * @return

     */

    public Map getData(String path){

        SQLiteDatabase db = openHelper.getReadableDatabase();

        Cursor cursor = db.rawQuery("select threadid, downlength from filedownlog where downpath=?

", new String[]{path});

        Map data = new HashMap();

        

        while(cursor.moveToNext()){

            data.put(cursor.getInt(0), cursor.getInt

(1));

        }

        

        cursor.close();

        db.close();

        return data;

    }

    

    /**

     * 保存每条线程已经下载的文件长度

     * @param path

     * @param map

     */

    public void save(String path,  Map map){//int threadid, int position

        SQLiteDatabase db = openHelper.getWritableDatabase();

        db.beginTransaction();

        

        try{

            for(Map.Entry

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 社交礼仪

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1