-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 = "\r\n"; /** 結束符 */
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 ?>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM