下面是要实现的效果

 

     这个demo,主要实现的功能有:多线程上传,断点续传, Notification的使用。多线程下载的主要原理是,对要下载的文件进行分割,每个线程取一个独立的区域进行下载。

     

 URL url = new URL(path);  
 HttpURLConnection conn = (HttpURLConnection)url.openConnection();  
  conn.setRequestMethod("GET");  
//startIndex和endIndex表示当前需要下载的文件的开始和结束的字节 conn.setRequestProperty(
"Range", "bytes="+startIndex+""+endIndex);

    写入的时候是通过java的RandomAccessFile 类来获取写入的开始位置,获取了开始的位置后,由于已经对服务器的文件大小进行了分割,依次写入流文件即可。

    对于单线程情况下的断点续传,一般情况下是通过计算已经下载的文件的大小,然后从末尾处选择开始下载。多线程情况下,感觉应该是对于每个线程下的位置进行记录,然后从记录的位置开始下载。

    本文并没有从头到尾写一个这样的过程,android开源框架Xutils提供了这一整套的类库和方法,github地址是https://github.com/wyouflf/xUtils。使用该类库需要网络和读写SD卡的权限,

      <uses-permission android:name="android.permission.INTERNET" />
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

下面呈现核心的代码。布局文件只有一个按钮没什么好说的。首先初始化这样一些变量:

    int id =1;
    private Button mButton;
    private  NotificationManager mNotifyManager;
    NotificationCompat.Builder mBuilder ;

然后在onCreate方法中,对它们进行初始化。

 mButton = (Button) findViewById(R.id.id_bt_startNotificationDownload);
        mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        mBuilder = new NotificationCompat.Builder(this);
        mBuilder.setContentTitle("内容下载").setContentText("下载中,请骚等").setSmallIcon(R.drawable.notification);
//点击按钮,开始下载
mButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
download("https://github.com/wyouflf/xCombine/archive/master.zip",
"/sdcard/xCombine_master.zip");
}
});

下面是使用Xutil的类库进行多线程下载的方法。

private void download(String url, String filePath){
        HttpUtils httpUtils = new HttpUtils();
        //可以设置线程池的大小,下载充实的次数,超时时间等等。
        HttpHandler hanlder = httpUtils.configRequestThreadPoolSize(5).download(url, filePath, true, true, new RequestCallBack<File>() {
            @Override
            public void onSuccess(ResponseInfo<File> responseInfo) {
                //成功后将setProgress的两个变量设置为0,progress就会消失。setProgerss第三个参数的含义是,如果能确定进度条执行的时间,就传入true,否则是false,此处直接传入false即可。
                mBuilder.setProgress(0, 0,false).setContentText("已经下载完成");
                mNotifyManager.notify(id, mBuilder.build());
            }
            @Override
            public void onFailure(HttpException e, String s) {
                //失败后执行的方法
                Toast.makeText(MainActivity.this,"fali , try again",Toast.LENGTH_LONG).show();
            }
            @Override
            public void onStart() {
                //开始时候,初始化进度条
                mBuilder.setProgress(100, 0,false);
                mNotifyManager.notify(id, mBuilder.build());
            }
            @Override
            public void onLoading(long total, long current, boolean isUploading) {
                //更新进度条
                int currentNum = (int) (100*current/total);
                mBuilder.setProgress(100, currentNum,false);
                mNotifyManager.notify(id, mBuilder.build());
            }
        });

    }