• -Android -线程池 批量上传图片 -附php接收代码


    (出处:http://www.cnblogs.com/linguanh/)

    目录:

      1,前序

      2,类特点

      3,用法

      4,java代码

      5,php代码

    1,前序

      还是源于重构,看着之前为赶时间写着的碎片化的代码,甚是悲剧,臃肿且长,其实重构也是一个提高的过程,重构过程中会接触到更多的知识点。至少,我现在意识到,那怕是听过、有这样的意识而没真正动过手都是不行的,多线程并发最好使用线程池而不要一味地 new Thread(...).start()。下面我分享个自己刚写好的图片批量上传类,顺带server端接口代码,已经过测试,一套直接可用。

    2,本类特点

      1、耦合度低,操作简单、使用时仅 6 行代码即可直接 批量上传完图片;

      2、使用的是软化线程池对象,内存消耗这方面可以放心地交给系统处理;

      3、采用链式操作,配置方便;

      4、自带上传函数,光学习这个都够了;

      5、懒人必备...

    3,使用例子

    new PicUpLoadExecutor(3)// 并发数       
         .withUpLoadUrl(url) // 服务端接口文件的url

    .withHandler(handler) // 发完后发消息的handler
    .exec(picBitmaps); // 要上传的图片bitmaps

    4,client端java类

    注释已经很丰富,不懂请留言

      1 package cn.share.bananacloud.post.send;
      2 
      3 import android.graphics.Bitmap;
      4 import android.os.Handler;
      5 import android.util.Log;
      6 
      7 import java.io.BufferedReader;
      8 import java.io.ByteArrayInputStream;
      9 import java.io.ByteArrayOutputStream;
     10 import java.io.DataOutputStream;
     11 import java.io.InputStream;
     12 import java.io.InputStreamReader;
     13 import java.lang.ref.SoftReference;
     14 import java.net.HttpURLConnection;
     15 import java.net.URL;
     16 import java.util.concurrent.ExecutorService;
     17 import java.util.concurrent.Executors;
     18 import java.util.concurrent.ThreadFactory;
     19 
     20 /**
     21  *  Created by 林冠宏 on 2016/4/30.
     22  *
     23  *  1,线程池批量上传图片类,选用 newFixedThreadPool
     24  *  2,以 Bitmap 数组为例子
     25  *  3,自定义一个 图片上传 函数
     26  *
     27  */
     28 
     29 public class PicUpLoadExecutor {
     30 
     31     private static final String TAG = "PicUpLoadHelper";
     32     public static final int UpLoadFinish = 0x321;
     33 
     34     /** 如果你不想内存不足是它们被gc掉,请换为强引用 */
     35     private SoftReference<ExecutorService> fixedThreadPool = null;
     36 
     37     /** 并发数>0 --1 ~ 128,用 short 足以 */
     38     private short poolSize = 1;
     39     private Handler handler = null;
     40     private ExecListenter ExecListenter;
     41     private String url = null;
     42 
     43     public PicUpLoadExecutor(short poolSize){
     44         fixedThreadPool = new SoftReference<ExecutorService>(Executors.newFixedThreadPool(poolSize));
     45     }
     46 
     47     public PicUpLoadExecutor(short poolSize,ThreadFactory threadFactory){
     48         fixedThreadPool = new SoftReference<ExecutorService>(Executors.newFixedThreadPool(poolSize,threadFactory));
     49     }
     50 
     51     /** 设置并发数 */
     52     /*public PicUpLoadExecutor withPoolSize(short poolSize){
     53         this.poolSize = poolSize;
     54         return this;
     55     }*/
     56 
     57     /** 设置图片总数,已直接换为图片数目 */
     58     /*public PicUpLoadHelper withPicSize(short poolSize){
     59         this.picSize = picSize;
     60         return this;
     61     }*/
     62 
     63     /** 设置图片上传路径 */
     64     public PicUpLoadExecutor withUpLoadUrl(String url){
     65         this.url = url;
     66         return this;
     67     }
     68 
     69     /** 设置handler */
     70     public PicUpLoadExecutor withHandler(Handler handler){
     71         this.handler = handler;
     72         return this;
     73     }
     74 
     75     /** 设置自定义 run 函数接口 */
     76     /*public PicUpLoadHelper withExecRunnableListenter(ExecRunnableListenter ExecRunnableListenter){
     77         this.ExecRunnableListenter = ExecRunnableListenter;
     78         return this;
     79     }*/
     80 
     81     /** 设置开始前接口 */
     82     public PicUpLoadExecutor withBeforeExecListenter(ExecListenter ExecListenter){
     83         this.ExecListenter = ExecListenter;
     84         return this;
     85     }
     86 
     87 
     88     public ExecutorService getFixedThreadPool(){
     89         return fixedThreadPool.get();
     90     }
     91 
     92     /** 开发原则--接口分离 */
     93 
     94     /** 自定义run接口 */
     95     public interface ExecRunnableListenter{
     96         void onRun(int i);
     97     }
     98 
     99     /** 开始任务前接口,没用到,可自行设置 */
    100     public interface ExecListenter{
    101         void onBeforeExec();
    102     }
    103 
    104     /** 为减少 程序计数器 每次在循环时花费在 if else 的时间,这里还是 重载一次 好 */
    105 
    106     public void exec(final Bitmap[] bitmaps,final ExecRunnableListenter ExecRunnableListenter){
    107         if(bitmaps==null){
    108             return;
    109         }
    110         if(ExecRunnableListenter!=null){
    111             int picNums = bitmaps.length;
    112             for(int i=0;i<picNums;i++){
    113                 /** 自定义执行上传任务 */
    114                 final int picIndex = i;
    115                 fixedThreadPool.get().execute(new Runnable() {
    116                     @Override
    117                     public void run() {
    118                         ExecRunnableListenter.onRun(picIndex);
    119                     }
    120                 });
    121             }
    122         }
    123     }
    124 
    125     public void exec(final Bitmap[] bitmaps){
    126         if(bitmaps==null){
    127             return;
    128         }
    129         int picNums = bitmaps.length;
    130         for(int i=0;i<picNums;i++){
    131             /** 默认执行上传任务 */
    132             final int picIndex = i;
    133             fixedThreadPool.get().execute(new Runnable() {
    134                 @Override
    135                 public void run() {
    136                     /** 批量 上传 图片,此静态函数若有使用全局变量,必须要 加 synchronized */
    137                     String json = uploadPic
    138                             (
    139                                     url,
    140                                     "" + picIndex + ".jpg", /** 我自己情况的上传 */
    141                                     bitmaps[picIndex]       /** 对应的图片流 */
    142                             );
    143                     if(json!=null){
    144                         /** 服务器上传成功返回的标示, 自己修改吧,我这里是我的情况 */
    145                         if(json.trim().equals("yes")){
    146                             /** UpLoadFinish 是每次传完一张发信息的信息标示 */
    147                             handler.sendEmptyMessage(UpLoadFinish);
    148                         }
    149                     }
    150                     Log.d(TAG,"pic "+picIndex+" upLoad json ---> "+json);
    151                 }
    152             });
    153         }
    154     }
    155 
    156     /** 若有依赖全局变量必须加 synchronized */
    157     /** 此函数采用 tcp 数据包传输 */
    158     public static String uploadPic(String uploadUrl,String filename,Bitmap bit){
    159         String end = "
    "; /** 结束符 */
    160         String twoHyphens = "--";
    161         String boundary = "******"; /** 数据包头,设置格式没强性要求 */
    162         int compress=100; /** 压缩初始值 */
    163         try{
    164             HttpURLConnection httpURLConnection
    165                     = (HttpURLConnection) new URL(uploadUrl).openConnection();
    166             /** 设置每次传输的流大小,可以有效防止手机因为内存不足崩溃 */
    167             /** 此方法用于在预先不知道内容长度时启用没有进行内部缓冲的 HTTP 请求正文的流。*/
    168             httpURLConnection.setChunkedStreamingMode(256 * 1024);// 256K
    169 
    170             httpURLConnection.setConnectTimeout(10*1000);
    171             httpURLConnection.setDoInput(true);
    172             httpURLConnection.setDoOutput(true);
    173             httpURLConnection.setUseCaches(false);
    174 
    175             httpURLConnection.setRequestMethod("POST");
    176             /** tcp链接,防止丢包,需要进行长链接设置 */
    177             httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
    178             httpURLConnection.setRequestProperty("Charset", "UTF-8");
    179             httpURLConnection.setRequestProperty("Content-Type","multipart/form-data;boundary=" + boundary);
    180 
    181             /** 发送报头操作,dos 也是流发送体 */
    182             DataOutputStream dos = new DataOutputStream(httpURLConnection.getOutputStream());
    183             dos.writeBytes(twoHyphens + boundary + end);
    184             /** uploadedfile 是接口文件的接受流的键,client 和 server 要同步 */
    185             dos.writeBytes("Content-Disposition: form-data; name="uploadedfile"; filename=""
    186                     + filename.substring(filename.lastIndexOf("/") + 1)
    187                     + """
    188                     + end);
    189             dos.writeBytes(end);
    190 
    191             /** 下面是压缩操作 */
    192             ByteArrayOutputStream baos = new ByteArrayOutputStream();
    193             bit.compress(Bitmap.CompressFormat.JPEG, compress, baos);
    194             while (baos.toByteArray().length / 1024 > 500) {
    195                 Log.d(TAG,"compress time ");
    196                 baos.reset();
    197                 compress -= 10;
    198                 if(compress==0){
    199                     bit.compress(Bitmap.CompressFormat.JPEG, compress, baos);
    200                     break;
    201                 }
    202                 bit.compress(Bitmap.CompressFormat.JPEG, compress, baos);
    203             }
    204 
    205             /** 发送比特流 */
    206             InputStream fis = new ByteArrayInputStream(baos.toByteArray());
    207             byte[] buffer = new byte[10*1024]; // 8k+2k
    208             int count = 0;
    209             while ((count = fis.read(buffer)) != -1) {
    210                 dos.write(buffer, 0, count);
    211             }
    212             fis.close();
    213             dos.writeBytes(end);
    214             dos.writeBytes(twoHyphens + boundary + twoHyphens + end);
    215             dos.flush();
    216 
    217             /** 获取返回值 */
    218             InputStream is = httpURLConnection.getInputStream();
    219             InputStreamReader isr = new InputStreamReader(is, "utf-8");
    220             BufferedReader br = new BufferedReader(isr);
    221             String result = br.readLine();
    222 
    223             Log.d(TAG, "send pic result "+result);
    224             dos.close();
    225             is.close();
    226             return result;
    227         } catch (Exception e){
    228             e.printStackTrace();
    229             Log.d(TAG, e.toString());
    230             return null;
    231         }
    232     }
    233 }
    View Code

    5,server端接受代码 php

     1 <?php
     2 /**
     3  * Created by PhpStorm.
     4  * User: Administrator
     5  * Date: 2016/4/30
     6  * Time: 15:37
     7  */
     8 
     9 // $_FILES['uploadedfile']['name'] 是传过来的图片名称
    10 
    11 $target_path = "要保存到的路径";
    12 
    13 if(move_uploaded_file($_FILES['uploadedfile']['tmp_name'], $target_path)) {
    14     echo "yes";
    15 }  else{
    16     echo "no";
    17 }
    18 
    19 
    20 ?>
  • 相关阅读:
    最近在项目中使用ibatis小结
    35 岁前程序员要规划好的四件事
    C# webbrowser小结
    高并发网站架构
    高斯混合模型(GMM)
    EM算法学习(Expectation Maximization Algorithm)
    如何用CSS3美化菜单
    Intellij IDEA配置自动同步到FTP服务器
    Mac 快速休眠关机重启锁屏
    JavaScript并行运算新机遇——Web Workers的神奇魔法
  • 原文地址:https://www.cnblogs.com/linguanh/p/5449191.html
Copyright © 2020-2023  润新知