HttpURLConnection实现多线程网络下载

第一步:设计布局文件如下:

 
  



   
    
    
运行效果如下:(以下载图片为例)
HttpURLConnection实现多线程网络下载_第1张图片
第二步:编写下载工具类(多线程下载)
 
  
public class DownUtil{
    //  定义下载路径
    private String path;
    //  要下载到的文件路径
    private String targetFile;
    private int threadNum;
    private DownThread[] threads;
    //  定义下载文件的总大小
    private int fileSize;

    public DownUtil(){

    }
    //  初始化下载所需数据
    public DownUtil(String path,String targetFile,int threadNum){
        this.path = path;
        this.targetFile = targetFile;
        this.threadNum = threadNum;
        threads = new DownThread[threadNum];
    }
    //  定义下载方法
    public void download(){
        try {
            URL url = new URL(path);
            //  获得到资源的链接
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestProperty("Accept-Encoding","identity");
            conn.setConnectTimeout(5*10000);
            conn.setRequestMethod("GET");
            conn.setRequestProperty("Charset","UTF-8");
            conn.setRequestProperty("Accept-language","zh-CN");
            conn.setRequestProperty("Connection","Keep-Alive");
            //  获取要下载的文件的大小
            fileSize = conn.getContentLength();
            conn.disconnect();
            int currentPartSize = fileSize / threadNum + 1;
            //  创建一个文件读取流去读取targetFile所定义的文件,权限为读写
            RandomAccessFile file = new RandomAccessFile(targetFile,"rw");
            file.setLength(fileSize);
            file.close();
            for (int i = 0; i 0){
                    currentPart.write(buf,0,hasRead);
                    length +=hasRead;
                }
                currentPart.close();
                is.close();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    //  定义一个为InputStream跳过bytes字节的方法
    //  因为输入流的skip方法有时候会读取不完整 所以创建一个读取方法循环读取知道读完为止
    public  static void skipFully(InputStream is,long bytes){
        long remainning = bytes;
        long len = 0;
        while(remainning > 0){
            try {
                len = is.skip(remainning);
                remainning -= len;
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
第三步:在MainActivity中编写代码,实现下载功能并预览图片,因为下载任务是个耗时操作应放在线程中操作,对于UI的改变操作应该使用handler进行处理,使用定时器和ProgressBard对下载状态进行更新和显示:
 
  
public class MainActivity extends Activity {
    EditText url,target;
    Button btn_download;
    ProgressBar bar;
    ImageView show;
    DownUtil downUtill;
    //  定义进度条的状态值
    private int mDownStatus;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        url = (EditText) findViewById(R.id.id_url);
        target = (EditText) findViewById(R.id.id_targetFile);
        btn_download = (Button) findViewById(R.id.id_download);
        bar = (ProgressBar) findViewById(R.id.id_progress);
        show = (ImageView) findViewById(R.id.id_show);
        final Handler handler = new Handler(){
            public void handleMessage(Message msg){
                if(msg.what == 0x123){
                    if(mDownStatus == 100){
                        Toast.makeText(MainActivity.this, "download task done", Toast.LENGTH_SHORT).show();
                        Bitmap bitmap = BitmapFactory.decodeFile("/mnt/sdcard/a.chm");
                        show.setImageBitmap(bitmap);
                    }
                    bar.setProgress(mDownStatus);
                }
            }
        };
        btn_download.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                downUtill = new DownUtil(url.getText().toString(),target.getText().toString(),6);
                Log.i("KKK",url.getText().toString()+"-----"+target.getText().toString());
                new Thread(){
                    public void run(){
                        downUtill.download();
                        final Timer timer = new Timer();
                        timer.schedule(new TimerTask() {
                            @Override
                            public void run() {
                                double completeRate = downUtill.getConpleteRate();
                                mDownStatus = (int) completeRate * 100;
                                Log.i("KKK",mDownStatus+"%");
                                handler.sendEmptyMessage(0x123);
                                if(mDownStatus>=100){
                                    Log.i("KKK","下载完成");
                                    timer.cancel();
                                }
                            }
                        },0,100);
                    }

                }.start();
            }
        });
    }
}
注意事项:需要在AndroidManifest.xml中定义如下权限:
 
  
<uses-permission android:name="android.permission.INTERNET"/>     联网权限
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>     创建删除文件权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>    写入SD卡权限
 
  
所出现的问题:
     1.  is.getContentLength结果为0,可能是要下载的资源没有给出下载权限 或是服务器没有给出Content-Length字段,需要换一个资源下载进行测试。
     2.  getContentLength返回结果-1,可能是缺少  conn.setRequestProperty("Accept-Encoding","identity");这行代码。

 
  




你可能感兴趣的:(android)