标签:
参考疯狂android讲义,重点在于学习1、HttpConnection访问网络2、多线程下载文件的处理
主activity:
package com.example.multithreaddownload; import java.util.Timer; import java.util.TimerTask; //import org.crazyit.net.R; import android.annotation.SuppressLint; 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; @SuppressLint("HandlerLeak") public class MultiThreadDown extends Activity { EditText target; EditText url; Button downButton; ProgressBar bar; DownUtil downUtil; private int mDownloadStatus; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); url = (EditText) findViewById(R.id.url); target = (EditText) findViewById(R.id.target); downButton = (Button) findViewById(R.id.down); bar = (ProgressBar) findViewById(R.id.bar); final Handler handler = new Handler(){ public void handleMessage(Message msg) { if(msg.what == 0x123) { bar.setProgress(mDownloadStatus); } } }; downButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // downUtil = new DownUtil(url.getText().toString(), target.getText().toString(),5); try{ downUtil.download(); }catch(Exception e) { e.printStackTrace(); } //设置定时器 final Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { // double completeRate = downUtil.getCompleteRate(); mDownloadStatus = (int) (completeRate * 100); handler.sendEmptyMessage(0x123); if(mDownloadStatus >= 100) { timer.cancel(); } } }, 0, 100); } }); } }
package com.example.multithreaddownload; import java.io.InputStream; import java.io.RandomAccessFile; import java.net.HttpURLConnection; import java.net.URL; public class DownUtil { private String path; private String targetFile; private int threadNum; private DownloadThread[] threads; private int fileSize; public DownUtil(String path, String targetFile, int threadNum) { super(); this.path = path; this.targetFile = targetFile; //初始化thread数组 threads = new DownloadThread[threadNum]; this.threadNum = threadNum; } public void download() throws Exception { URL url = new URL(path); HttpURLConnection connection = (HttpURLConnection) url.openConnection();//开启http链接 connection.setRequestMethod("GET");//向服务器发送GET请求获取数据 connection.setConnectTimeout(5000);//设置连接超时为5s // connection.setRequestProperty( // "Accept", // "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*"); // connection.setRequestProperty("Accept-Language", "zh-CN"); // connection.setRequestProperty("Charset", "UTF-8"); // connection.setRequestProperty( // "User-Agent", // "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; Trident/4.0; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"); // connection.setRequestProperty("Connection", "Keep-Alive"); fileSize = connection.getContentLength();//获取文件大小 connection.disconnect();//关闭http连接 int currentPartSize = fileSize / threadNum +1;//按线程数分割后文件块的大小 RandomAccessFile file = new RandomAccessFile(targetFile, "rw");//随机产生本地目标文件 file.setLength(fileSize);//根据fileSize设置本地文件大小 file.close();//关闭文件 for(int i = 0; i < threadNum; i++) { //计算每条线程下载的开始位置 int startPos = i * currentPartSize; //每个线程使用一个RandomAccessFile进行下载 RandomAccessFile currentPart = new RandomAccessFile(targetFile, "rw"); //定位该线程的下载位置 currentPart.seek(startPos); //创建下载线程 threads[i] = new DownloadThread(startPos, currentPartSize, currentPart); threads[i].start(); } } // 获取下载的完成百分比 public double getCompleteRate() { // 统计多条线程已经下载的总大小 int sumSize = 0; for (int i = 0; i < threadNum; i++) { sumSize += threads[i].length; } // 返回已经完成的百分比 return sumSize * 1.0 / fileSize; } private class DownloadThread extends Thread{ //当前线程下载的位置 private int startPos; //定义当前线程负责下载的文件大小 private int currentPartSize; //定义当前线程负责的下载块 private RandomAccessFile currentPart; //定义该线程已下载的字节数 public int length; public DownloadThread(int startPos, int currentPartSize, RandomAccessFile currentPart) { // super(); this.startPos = startPos; this.currentPartSize = currentPartSize; this.currentPart = currentPart; } @Override public void run() { super.run(); try{ URL url = new URL(path); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); // connection.setReadTimeout(5000); // connection.setRequestProperty( // "Accept", // "image/gif, image/jpeg, image/pjpeg, image/pjpeg, application/x-shockwave-flash, application/xaml+xml, application/vnd.ms-xpsdocument, application/x-ms-xbap, application/x-ms-application, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*"); // connection.setRequestProperty("Accept-Language", "zh-CN"); // connection.setRequestProperty("Charset", "UTF-8"); InputStream in = connection.getInputStream(); //跳过startPos个字节,只下载本线程负责的文件块 in.skip(this.startPos); byte[] buffer = new byte[1024]; int hasRead = 0; while((length < currentPartSize) && (hasRead = in.read(buffer)) != -1) { currentPart.write(buffer, 0, hasRead); length += hasRead; } currentPart.close(); in.close(); }catch(Exception e) { e.printStackTrace(); } } } }
activity_main.xml文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="要下载的资源的URL:" /> <EditText android:id="@+id/url" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="http://www.crazyit.org/attachment.php?aid=1093&k=4ec76aeaa41ee84acf667b420e926783&t=1297311085" /> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="目标文件:" /> <EditText android:id="@+id/target" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="/mnt/sdcard/a.rar" /> <Button android:id="@+id/down" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/down" /> <!-- 定义一个水平进度条,用于显示下载进度 --> <ProgressBar android:id="@+id/bar" android:layout_width="fill_parent" android:layout_height="wrap_content" android:max="100" style="@android:style/Widget.ProgressBar.Horizontal" /> </LinearLayout>
strings.xml:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="down">下载</string> <string name="app_name">多线程下载</string> <string name="action_settings">Settings</string> </resources>
AndroidManifest.xml配置文件添加以下权限:
<!-- 在SD卡中创建与删除文件权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!-- 向SD卡写入数据权限 --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <!-- 授权访问网络 --> <uses-permission android:name="android.permission.INTERNET"/>
运行结果:
标签:
原文地址:http://www.cnblogs.com/CoolRandy/p/4324542.html