一、排坑

HttpClient、Header飘红

Android 6.0 已经移除了httpClient

module下的build.gradle中加入:

android{useLibrary 'org.apache.http.legacy'
}

导入jar包

放入libs文件夹,右键选择add as library

退出整个程序

MainActivity内加入

public static List<Activity> activityList = new LinkedList();

    public void exit()  {  for(Activity act:activityList)  {  act.finish();  }  System.exit(0);  }

在每个activity的oncreat里面写上如下这么一句代码,记得要写在 setContentView 之后:

MainActivity.activityList.add(this)

退出

exit();

存储路径

sdcard:实际上只是一个快捷方式,指向了/storage/self/primary

下载速度

使用BufferedRandomAccessFile代替RandomAccessFile

真机比模拟器明显快很多

二、HttpClient

public class MainActivity extends Activity {Handler handler = new Handler(){@Overridepublic void handleMessage(Message msg) {Toast.makeText(MainActivity.this, (String)msg.obj, 0).show();}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void get(View v){EditText et_name = (EditText) findViewById(R.id.et_name);EditText et_pass = (EditText) findViewById(R.id.et_pass);final String name = et_name.getText().toString();final String pass = et_pass.getText().toString();Thread t = new Thread(){@Overridepublic void run() {String path = "http://10.32.189.73:8080/d0301/LoginServlet?username=" + URLEncoder.encode(name) + "&password=" + pass;//使用httpClient框架做get方式提交//1.创建HttpClient对象HttpClient hc = new DefaultHttpClient();//2.创建httpGet对象,构造方法的参数就是网址HttpGet hg = new HttpGet(path);//3.使用客户端对象,把get请求对象发送出去try {HttpResponse hr = hc.execute(hg);//拿到响应头中的状态行StatusLine sl = hr.getStatusLine();if(sl.getStatusCode() == 200){//拿到响应头的实体HttpEntity he = hr.getEntity();//拿到实体中的内容,其实就是服务器返回的输入流InputStream is = he.getContent();String text = Utils.getTextFromStream(is);//发送消息,让主线程刷新ui显示textMessage msg = handler.obtainMessage();msg.obj = text;handler.sendMessage(msg);}} catch (Exception e) {// TODO Auto-generated catch block
                    e.printStackTrace();}}};t.start();}public void post(View v){EditText et_name = (EditText) findViewById(R.id.et_name);EditText et_pass = (EditText) findViewById(R.id.et_pass);final String name = et_name.getText().toString();final String pass = et_pass.getText().toString();Thread t = new Thread(){@Overridepublic void run() {String path = "http://10.32.189.73:8080/d0301/LoginServlet";//1.创建客户端对象HttpClient hc = new DefaultHttpClient();//2.创建post请求对象HttpPost hp = new HttpPost(path);//封装form表单提交的数据BasicNameValuePair bnvp = new BasicNameValuePair("username", name);BasicNameValuePair bnvp2 = new BasicNameValuePair("password", pass);List<BasicNameValuePair> parameters = new ArrayList<BasicNameValuePair>();//把BasicNameValuePair放入集合中
                parameters.add(bnvp);parameters.add(bnvp2);try {//要提交的数据都已经在集合中了,把集合传给实体对象UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters, "utf-8");//设置post请求对象的实体,其实就是把要提交的数据封装至post请求的输出流中
                    hp.setEntity(entity);//3.使用客户端发送post请求HttpResponse hr = hc.execute(hp);if(hr.getStatusLine().getStatusCode() == 200){InputStream is = hr.getEntity().getContent();String text = Utils.getTextFromStream(is);//发送消息,让主线程刷新ui显示textMessage msg = handler.obtainMessage();msg.obj = text;handler.sendMessage(msg);}} catch (Exception e) {// TODO Auto-generated catch block
                    e.printStackTrace();}}};t.start();}
}

三、异步HttpClient框架

源码:https://github.com/loopj/android-async-http

public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}public void get(View v){EditText et_name = (EditText) findViewById(R.id.et_name);EditText et_pass = (EditText) findViewById(R.id.et_pass);final String name = et_name.getText().toString();final String pass = et_pass.getText().toString();String url = "http://10.32.189.73:8080/d0301/LoginServlet?username=" + URLEncoder.encode(name) + "&password=" + pass;//创建异步httpclientAsyncHttpClient ahc = new AsyncHttpClient();//发送get请求提交数据ahc.get(url, new MyResponseHandler());}public void post(View v){EditText et_name = (EditText) findViewById(R.id.et_name);EditText et_pass = (EditText) findViewById(R.id.et_pass);final String name = et_name.getText().toString();final String pass = et_pass.getText().toString();String url = "http://10.32.189.73:8080/d0301/LoginServlet";//创建异步httpclientAsyncHttpClient ahc = new AsyncHttpClient();//发送post请求提交数据//把要提交的数据封装至RequestParams对象RequestParams params = new RequestParams();params.add("username", name);params.add("password", pass);ahc.post(url, params, new MyResponseHandler());}class MyResponseHandler extends AsyncHttpResponseHandler {//请求服务器成功时,此方法调用
        @Overridepublic void onSuccess(int statusCode, org.apache.http.Header[] headers,byte[] responseBody) {Toast.makeText(MainActivity.this, new String(responseBody), Toast.LENGTH_SHORT).show();}//请求失败此方法调用
        @Overridepublic void onFailure(int statusCode, org.apache.http.Header[] headers,byte[] responseBody, Throwable error) {Toast.makeText(MainActivity.this, "请求失败", Toast.LENGTH_SHORT).show();}}
}

四、断点续传多线程下载器

添加BufferedRandomAccessFile

源码:https://files.cnblogs.com/files/index42/BufferedRandomAccessFile.zip

public class MainActivity extends AppCompatActivity {private static int ThreadCount = 3;private static int finishedThread = 0;public static List<Activity> activityList = new LinkedList();private String filepath= Environment.getExternalStorageDirectory()+"/ahmk/";private String downloadFilename=filepath+"test.zip";private static final String TAG = "MainActivity";int currentProgress;private int length;private String fileName = "test.zip";private static class Lock{};private static Object lock=new Lock();//确定下载地址private String path = "https://files.cnblogs.com/files/index42/" + fileName;private ProgressBar pb;TextView tv;Handler handler = new Handler() {public void handleMessage(android.os.Message msg) {//把变量改成long,在long下运算tv.setText((long) pb.getProgress() * 100 / pb.getMax() + "%");}};Handler handler2 = new Handler() {public void handleMessage(android.os.Message msg) {//把变量改成long,在long下运算tv.setText("文件已存在");}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);MainActivity.activityList.add(this);Log.e(TAG, filepath);pb = (ProgressBar) findViewById(R.id.pb);tv = (TextView) findViewById(R.id.tv);if (ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED  ){//申请权限ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE},1);}else {//把动作告诉系统
}}public void click(View v) {Thread t = new Thread() {@Overridepublic void run() {//发送get请求,请求这个地址的资源try {File file = new File(downloadFilename);if(file.exists()) {handler2.sendEmptyMessage(1);Log.e(TAG, "已经存在文件");return;}URL url = new URL(path);HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("GET");conn.setConnectTimeout(5000);conn.setReadTimeout(5000);Log.e(TAG, conn.getResponseCode()+"");if (conn.getResponseCode() == 200) {//拿到所请求资源文件的长度length = conn.getContentLength();Log.e(TAG, length+"");//设置进度条的最大值就是原文件的总长度
                        pb.setMax(length);Log.e(TAG, "run3: ");File dir = new File(filepath);if(!dir.exists()){dir.mkdirs();}//生成临时文件BufferedRandomAccessFile raf = new BufferedRandomAccessFile(file, "rwd");//设置临时文件的大小
                        raf.setLength(length);raf.close();//计算出每个线程应该下载多少字节int size = length / ThreadCount;for (int i = 0; i < ThreadCount; i++) {//计算线程下载的开始位置和结束位置int startIndex = i * size;int endIndex = (i + 1) * size - 1;//如果是最后一个线程,那么结束位置写死if (i == ThreadCount - 1) {endIndex = length - 1;}
//                            System.out.println("线程" + i + "的下载区间是:" + startIndex + "---" + endIndex);new DownLoadThread(startIndex, endIndex, i).start();}}} catch (Exception e) {// TODO Auto-generated catch block
                    e.printStackTrace();}}};t.start();}class DownLoadThread extends Thread{int startIndex;int endIndex;int threadId;public DownLoadThread(int startIndex, int endIndex, int threadId) {super();this.startIndex = startIndex;this.endIndex = endIndex;this.threadId = threadId;}@Overridepublic void run() {//再次发送http请求,下载原文件try {File progressFile = new File(filepath,threadId + ".txt");//判断进度临时文件是否存在if(progressFile.exists()){FileInputStream fis = new FileInputStream(progressFile);BufferedReader br = new BufferedReader(new InputStreamReader(fis));//从进度临时文件中读取出上一次下载的总进度,然后与原本的开始位置相加,得到新的开始位置int lastProgress = Integer.parseInt(br.readLine());startIndex += lastProgress;//把上次下载的进度显示至进度条currentProgress += lastProgress;pb.setProgress(currentProgress);//发送消息,让主线程刷新文本进度handler.sendEmptyMessage(1);fis.close();}Log.e(TAG, "线程" + threadId + "的下载区间是:" + startIndex + "---" + endIndex);HttpURLConnection conn;URL url = new URL(path);conn = (HttpURLConnection) url.openConnection();conn.setRequestMethod("GET");conn.setConnectTimeout(5000);conn.setReadTimeout(5000);//设置本次http请求所请求的数据的区间conn.setRequestProperty("Range", "bytes=" + startIndex + "-" + endIndex);//请求部分数据,相应码是206if(conn.getResponseCode() == 206){//流里此时只有1/3原文件的数据InputStream is = conn.getInputStream();byte[] b = new byte[1024];int len = 0;int total = 0;//拿到临时文件的输出流File file = new File(downloadFilename);BufferedRandomAccessFile raf = new BufferedRandomAccessFile(file, "rwd");//把文件的写入位置移动至startIndex
                    raf.seek(startIndex);while((len = is.read(b)) != -1){//每次读取流里数据之后,同步把数据写入临时文件raf.write(b, 0, len);total += len;//Log.e(TAG, "线程" + threadId + "下载了" + total);//每次读取流里数据之后,把本次读取的数据的长度显示至进度条currentProgress += len;pb.setProgress(currentProgress);//发送消息,让主线程刷新文本进度handler.sendEmptyMessage(1);//生成一个专门用来记录下载进度的临时文件BufferedRandomAccessFile progressRaf = new BufferedRandomAccessFile(progressFile, "rwd");//每次读取流里数据之后,同步把当前线程下载的总进度写入进度临时文件中progressRaf.write((total + "").getBytes());progressRaf.close();}Log.e(TAG, "线程" + threadId + "下载完毕-------------------小志参上!");raf.close();finishedThread++;synchronized (lock) {Log.e(TAG, "synchron");if(finishedThread == ThreadCount){for (int i = 0; i < ThreadCount; i++) {File f = new File(filepath, i + ".txt");f.delete();}Log.e(TAG, "over synchron");finishedThread = 0;pb.setProgress(length);handler.sendEmptyMessage(1);}}}} catch (Exception e) {// TODO Auto-generated catch block
                e.printStackTrace();}}}public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {switch (requestCode){case 1://权限回调if (grantResults[0]==PackageManager.PERMISSION_GRANTED&&grantResults[1]==PackageManager.PERMISSION_GRANTED){}else {//提示用户权限未被授予Log.e("MainActivity","未授予权限");exit();}break;}}public void exit(){for(Activity act:activityList){act.finish();}System.exit(0);}
}

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity" android:orientation="vertical"><Buttonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="开始下载" android:onClick="click"/><ProgressBar android:id="@+id/pb"android:layout_width="match_parent"android:layout_height="wrap_content"style="@android:style/Widget.ProgressBar.Horizontal"/><TextView android:id="@+id/tv"android:layout_width="wrap_content"android:layout_height="wrap_content"/>
</LinearLayout>

五、HttpUtils的使用

源码:https://github.com/wyouflf/xUtils

public class MainActivity extends Activity {private TextView tv_failure;private TextView tv_progress;private ProgressBar pb;public static List<Activity> activityList = new LinkedList();private static final String TAG = "MainActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);MainActivity.activityList.add(this);tv_failure = (TextView) findViewById(R.id.tv_failure);tv_progress = (TextView) findViewById(R.id.tv_progress);pb = (ProgressBar) findViewById(R.id.pb);if (ContextCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED  ){//申请权限ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,Manifest.permission.READ_EXTERNAL_STORAGE},1);}else {//把动作告诉系统
}}public void click(View v){HttpUtils utils = new HttpUtils();String fileName = "test.zip";//确定下载地址String path = "https://files.cnblogs.com/files/index42/" + fileName;String filepath= Environment.getExternalStorageDirectory()+"/ahmk/";String downloadFilename=filepath+"test.zip";File file = new File(downloadFilename);if(file.exists()) {tv_progress.setText("已经存在文件");Log.e(TAG, "已经存在文件");return;}utils.download(path, //下载地址downloadFilename, //文件保存路径true,//是否支持断点续传true, new RequestCallBack<File>() {//下载成功后调用
                    @Overridepublic void onSuccess(ResponseInfo<File> arg0) {Toast.makeText(MainActivity.this, arg0.result.getPath(), Toast.LENGTH_SHORT).show();}//下载失败调用
                    @Overridepublic void onFailure(HttpException arg0, String arg1) {// TODO Auto-generated method stub
                        tv_failure.setText(arg1);}@Overridepublic void onLoading(long total, long current,boolean isUploading) {// TODO Auto-generated method stubsuper.onLoading(total, current, isUploading);pb.setMax((int)total);pb.setProgress((int)current);tv_progress.setText(current * 100 / total + "%");}});}public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {switch (requestCode){case 1://权限回调if (grantResults[0]==PackageManager.PERMISSION_GRANTED&&grantResults[1]==PackageManager.PERMISSION_GRANTED){}else {//提示用户权限未被授予Log.e("MainActivity","未授予权限");exit();}break;}}public void exit(){for(Activity act:activityList){act.finish();}System.exit(0);}
}

转载于:https://www.cnblogs.com/index42/p/10458701.html

安卓day29网络编程 HttpClient AsyncHttpClient 断点续传多线程下载器 HttpUtils相关推荐

  1. 如何实现 HTTP 断点续传多线程下载

    1. HTTP断点续传多线程下载 一个比较常见的场景,就是断点续传/下载,在网络情况不好的时候,可以在断开连接以后,仅继续获取部分内容. 例如在网上下载软件,已经下载了 95% 了,此时网络断了,如果 ...

  2. 断点续传---多线程下载进阶(一)

    打算总结7篇笔记.来学习下断点续传---多线程下载进阶 AndroidManifest.xml <?xml version="1.0" encoding="utf- ...

  3. curl命令断点续传多线程下载文件

    新版本发布 curl命令7.66.0版本支持多线程下载 参考:https://daniel.haxx.se/blog/2019/09/11/curl-7-66-0-the-parallel-http- ...

  4. JAVA多线程下载器

    大二末了,选好了方向,而去也喜欢网络并发,多线程之类的,就决定做个多线程下载器,学习学习文件,网络,线程间通讯的方法. 代码其实早就开始写,只是一直比较忙,也没写多少.今天认真花了一天把下载线程写了. ...

  5. python编写下载器可暂停_python多进程断点续传分片下载器

    python多进程断点续传分片下载器 标签:python 下载器 多进程 因为爬虫要用到下载器,但是直接用urllib下载很慢,所以找了很久终于找到一个让我欣喜的下载器.他能够断点续传分片下载,极大提 ...

  6. 【python爬虫】实现多线程下载器

    写在前面 为什么要多线程?单个线程不能下载吗?多线程能占满网络实现宽带的满速下载而单线程不能. 举个栗子:你的宽带是100Mb/s,理论上最大下载速度是100/8=12.5MB/s.你要下载一个843 ...

  7. 手把手教你实现一个 Python 多线程下载器

    前言 下载文件是我们生活中的一个常见的需求,因此衍生的下载工具也非常多,各有各的优势以及不足之处.作为一个编程爱好者,我喜欢去研究它们是怎么实现文件下载功能的. 我的主要使用的编程语言是 Python ...

  8. python多进程断点续传分片下载器

    python多进程断点续传分片下载器 标签:python 下载器 多进程 因为爬虫要用到下载器,但是直接用urllib下载很慢,所以找了很久终于找到一个让我欣喜的下载器.他能够断点续传分片下载,极大提 ...

  9. Python:教你如何实现多线程下载器

    hello,大家好,我是wangzirui32,今天我们来学习如何使用Python实现多线程下载器,开始学习吧! 1. 流程&原理 将HEAD请求发送到目标URL,获取文件的大小 根据文件大小 ...

最新文章

  1. vim 删除操作命令
  2. 24个很酷的 CSS3 文本效果示例及教程
  3. python生成100个随机数_Python_0——100闭区间产生3个随机数,两种方法排序
  4. 非归档下oracle的备份和恢复
  5. 【Python】学习笔记总结(第一阶段(1-6)——汇总篇)
  6. python head 函数_python爬虫中header是什么?怎么用?
  7. 前端学习(325):javascript历史
  8. date设置时间_解决 IDEA 无法找到 java.util.Date 的问题
  9. es解决只能查询10000条数据方案
  10. 关于AdvancedDataGrid的header的数据传递
  11. c语言输入一个字符 对其进行归类,计算机二级C语言改错题归类 - 图文
  12. 状态机详解(一段式、二段式、三段式)
  13. 2022危险化学品经营单位安全管理人员特种作业证考试题库及在线模拟考试
  14. CefSharp截取完整网页图片,网页截图
  15. 给华为服务器RH2288V3(hm23-03)安装驱动
  16. 2018.12.31 NOIP训练 czy的后宫6(线性dp)
  17. 知乎上102个简短而深刻的回答:看完人生豁然开朗
  18. 为战而生的联想拯救者Pro,你值得拥有的手游神器
  19. 负数在计算机中表示方法
  20. 随机过程、马尔可夫链 详解

热门文章

  1. flash mx拖拽实例_集成Flash MX 2004和Director MX 2004
  2. **公司软件开发人员绩效评价标准(zt)
  3. html图片怎么装修到店铺,PS店铺装修和HTML基本操作
  4. 记一次 Redis 连接池泄漏问题排查
  5. web页面 新消息提示音
  6. Win11开机提示音要怎么改?
  7. Android:rk3588 kernel单编
  8. 一个netdisk storage backend app webos和增强的全功能网站云设想
  9. 微信小程序自定义导航栏,实现自适应
  10. debugx5.qq.com清除微信浏览器缓存