Android 多线程断点下载的实现方法

来源:互联网 发布:淘宝返现最多的app 编辑:程序博客网 时间:2024/04/29 02:02

本文实例讲述了Android实现多线程断点下载的方法。分享给大家供大家参考。具体实现方法如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
package cn.itcast.download; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.RandomAccessFile; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.ProtocolException; 
import java.net.URL; 
import cn.itcast.mutiledownload.StreamTool; 
import android.app.Activity; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.Button; 
import android.widget.EditText; 
import android.widget.ProgressBar; 
import android.widget.TextView; 
import android.widget.Toast; 
public class MutiledownloadActivity extendsActivity implementsOnClickListener { 
  privateProgressBar pb; 
  privateButton bt; 
  privateTextView tv; 
  privateEditText et; 
  booleanflag = true
  booleanstopflag = false
  privateHandler handler = newHandler() { 
    @Override 
    publicvoid handleMessage(Message msg) { 
      pb.setProgress(total); 
      intmax = pb.getMax(); 
      if(total >= (max - 1)) { 
        total = max; 
        flag =false
      
      intresult = total * 100/ max; 
      tv.setText("当前进度 :"+ result + "%"); 
      super.handleMessage(msg); 
    
  }; 
  inttotal = 0
  @Override 
  publicvoid onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    pb = (ProgressBar)this.findViewById(R.id.pb); 
    bt = (Button)this.findViewById(R.id.bt); 
    tv = (TextView)this.findViewById(R.id.tv_process); 
    et = (EditText)this.findViewById(R.id.et); 
    bt.setOnClickListener(this); 
  
  @Override 
  publicvoid onClick(View v) { 
    switch(v.getId()) { 
    caseR.id.bt: 
      // 创建一个子线程 定期的更新ui 
      if("开始下载".equals(bt.getText().toString())){ 
        bt.setText("暂停"); 
        stopflag =false; //开始下载  
      
      else
        bt.setText("开始下载"); 
        stopflag =true
      
        newThread() { 
          @Override 
          publicvoid run() { 
            super.run(); 
            while(flag) { 
              try
                sleep(1000); 
                // 如果total > = 文件长度 
                Message msg =new Message(); 
                handler.sendMessage(msg); 
              }catch (InterruptedException e) { 
                e.printStackTrace(); 
              
            
          
        }.start(); 
   
        // 开始执行下载的操作 
        String path = et.getText().toString().trim(); 
        if("".equals(path)) { 
          Toast.makeText(this,"路径不能为空", 1).show(); 
          return
        
        try
          URL url =new URL(path); 
          HttpURLConnection conn = (HttpURLConnection) url 
              .openConnection(); 
          conn.setRequestMethod("GET"); 
          conn.setConnectTimeout(5000); 
          conn.setRequestProperty("User-Agent"
              "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"); 
          intcode = conn.getResponseCode(); 
          if(code == 200) { 
            intlen = conn.getContentLength(); 
            RandomAccessFile file =new RandomAccessFile( 
                "/mnt/sdcard/"+ getFilenName(path), "rwd"); 
            // 1.设置本地文件大小跟服务器的文件大小一致 
            file.setLength(len); 
            // 设置进度条的最大值 
            pb.setMax(len); 
            // 2 .假设开启3 个线程 
            intthreadnumber = 3
            intblocksize = len / threadnumber; 
            /** 
             * 线程1 0~ blocksize 线程2 1*bolocksize ~ 2*blocksize 线程3 
             * 2*blocksize ~ 文件末尾 
             */ 
            for(int i = 0; i < threadnumber; i++) { 
              intstartposition = i * blocksize; 
              intendpositon = (i + 1) * blocksize; 
              if(i == (threadnumber - 1)) { 
                // 最后一个线程 
                endpositon = len; 
              
              DownLoadTask task =new DownLoadTask(i, path, 
                  startposition, endpositon); 
              task.start(); 
            
          
        }catch (Exception e) { 
          Toast.makeText(this,"下载出现异常", 0).show(); 
          e.printStackTrace(); 
        
      break
    
  
  classDownLoadTask extendsThread { 
    intthreadid; 
    String filepath; 
    intstartposition; 
    intendpositon; 
    publicDownLoadTask(intthreadid, String filepath, intstartposition, 
        intendpositon) { 
      this.threadid = threadid; 
      this.filepath = filepath; 
      this.startposition = startposition; 
      this.endpositon = endpositon; 
    
    @Override 
    publicvoid run() { 
      try
        File postionfile =new File("/mnt/sdcard/"+ threadid + ".txt"); 
        URL url =new URL(filepath); 
        HttpURLConnection conn = (HttpURLConnection) url 
            .openConnection(); 
        System.out.println("线程"+ threadid + "正在下载 "+ "开始位置 : " 
            + startposition +"结束位置 " + endpositon); 
        if(postionfile.exists()) { 
          FileInputStream fis =new FileInputStream(postionfile); 
          byte[] result = StreamTool.getBytes(fis); 
          String str =new String(result); 
          if(!"".equals(str)) { 
            intnewstartposition = Integer.parseInt(str); 
            if(newstartposition > startposition) { 
              startposition = newstartposition; 
            
          
        
        // "Range", "bytes=2097152-4194303") 
        conn.setRequestProperty("Range","bytes=" + startposition +"-" 
            + endpositon); 
        conn.setRequestMethod("GET"); 
        conn.setConnectTimeout(5000); 
        conn.setRequestProperty("User-Agent"
            "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"); 
        InputStream is = conn.getInputStream(); 
        RandomAccessFile file =new RandomAccessFile("/mnt/sdcard/" 
            + getFilenName(filepath),"rwd"); 
        // 设置 数据从文件哪个位置开始写 
        file.seek(startposition); 
        byte[] buffer =new byte[1024]; 
        intlen = 0
        // 代表当前读到的服务器数据的位置 ,同时这个值已经存储的文件的位置 
        intcurrentPostion = startposition; 
        // 创建一个文件对象 ,记录当前某个文件的下载位置 
        while((len = is.read(buffer)) != -1) { 
          if(stopflag) { 
            return
          
          file.write(buffer,0, len); 
          synchronized(MutiledownloadActivity.this) { 
            total += len; 
          
          currentPostion += len; 
          // 需要把currentPostion 信息给持久化到存储设备 
          String position = currentPostion +""
          FileOutputStream fos =new FileOutputStream(postionfile); 
          fos.write(position.getBytes()); 
          fos.flush(); 
          fos.close(); 
        
        file.close(); 
        System.out.println("线程"+ threadid + "下载完毕"); 
        // 当线程下载完毕后 把文件删除掉 
        if(postionfile.exists()) { 
          postionfile.delete(); 
        
      }catch (Exception e) { 
        e.printStackTrace(); 
      
      super.run(); 
    
  
  publicString getFilenName(String path) { 
    intstart = path.lastIndexOf("/") +1
    returnpath.substring(start, path.length()); 
  
}

希望本文所述对大家的Android程序设计有所帮助。

0 0
原创粉丝点击