最近项目中要用优化文件上传操作,因此对Android端文件上传做下总结。测试服务器端就用PHP写了,比较简单,代码如下:

查看文本 打印 ?
  1. <?php  
  2. $base_path = "./uploads/"//接收文件目录  
  3. $target_path = $base_path . basename ( $_FILES ['uploadfile'] ['name'] );  
  4. if (move_uploaded_file ( $_FILES ['uploadfile'] ['tmp_name'], $target_path )) {  
  5.     $array = array ("code" => "1""message" => $_FILES ['uploadfile'] ['name'] );  
  6.     echo json_encode ( $array );  
  7. else {  
  8.     $array = array ("code" => "0""message" => "There was an error uploading the file, please try again!" . $_FILES ['uploadfile'] ['error'] );  
  9.     echo json_encode ( $array );  
  10. }  
  11. ?>  

     我主要写了三种上传:人造POST请求、httpclient4(需要httpmime-4.1.3.jar)、AsyncHttpClient(对appache的HttpClient进行了进一步封装,了解更多...),当然为了并列起来看比较方便,前两种上传我直接写在主线程了,不知道对速度测试有没有影响,老鸟看到请给予批评指正,嘿嘿,下面上代码:

查看文本 打印 ?
  1. package com.example.fileupload;  
  2.   
  3. import java.io.BufferedReader;  
  4. import java.io.DataOutputStream;  
  5. import java.io.File;  
  6. import java.io.FileInputStream;  
  7. import java.io.FileNotFoundException;  
  8. import java.io.IOException;  
  9. import java.io.InputStream;  
  10. import java.io.InputStreamReader;  
  11. import java.net.HttpURLConnection;  
  12. import java.net.URL;  
  13.   
  14. import org.apache.http.HttpEntity;  
  15. import org.apache.http.HttpResponse;  
  16. import org.apache.http.HttpVersion;  
  17. import org.apache.http.client.ClientProtocolException;  
  18. import org.apache.http.client.HttpClient;  
  19. import org.apache.http.client.methods.HttpPost;  
  20. import org.apache.http.entity.mime.MultipartEntity;  
  21. import org.apache.http.entity.mime.content.FileBody;  
  22. import org.apache.http.impl.client.DefaultHttpClient;  
  23. import org.apache.http.params.CoreProtocolPNames;  
  24. import org.apache.http.util.EntityUtils;  
  25.   
  26. import android.app.Activity;  
  27. import android.os.Bundle;  
  28. import android.util.Log;  
  29. import android.view.View;  
  30. import android.view.View.OnClickListener;  
  31. import android.widget.Button;  
  32.   
  33. import com.loopj.android.http.AsyncHttpClient;  
  34. import com.loopj.android.http.AsyncHttpResponseHandler;  
  35. import com.loopj.android.http.RequestParams;  
  36.   
  37. /** 
  38.  *  
  39.  * ClassName:UploadActivity Function: TODO 测试上传文件,PHP服务器端接收 Reason: TODO ADD 
  40.  * REASON 
  41.  *  
  42.  * @author Jerome Song 
  43.  * @version 
  44.  * @since Ver 1.1 
  45.  * @Date 2013 2013-4-20 上午8:53:44 
  46.  *  
  47.  * @see 
  48.  */  
  49. public class UploadActivity extends Activity implements OnClickListener {  
  50.     private final String TAG = "UploadActivity";  
  51.   
  52.     private static final String path = "/mnt/sdcard/Desert.jpg";  
  53.     private String uploadUrl = "http://192.168.1.102:8080/Android/testupload.php";  
  54.     private Button btnAsync, btnHttpClient, btnCommonPost;  
  55.     private AsyncHttpClient client;  
  56.   
  57.     @Override  
  58.     protected void onCreate(Bundle savedInstanceState) {  
  59.         super.onCreate(savedInstanceState);  
  60.         setContentView(R.layout.activity_upload);  
  61.         initView();  
  62.         client = new AsyncHttpClient();  
  63.     }  
  64.   
  65.     private void initView() {  
  66.         btnCommonPost = (Button) findViewById(R.id.button1);  
  67.         btnHttpClient = (Button) findViewById(R.id.button2);  
  68.         btnAsync = (Button) findViewById(R.id.button3);  
  69.         btnCommonPost.setOnClickListener(this);  
  70.         btnHttpClient.setOnClickListener(this);  
  71.         btnAsync.setOnClickListener(this);  
  72.     }  
  73.   
  74.     @Override  
  75.     public void onClick(View v) {  
  76.         long startTime = System.currentTimeMillis();  
  77.         String tag = null;  
  78.         try {  
  79.             switch (v.getId()) {  
  80.             case R.id.button1:  
  81.                 upLoadByCommonPost();  
  82.                 tag = "CommonPost====>";  
  83.                 break;  
  84.             case R.id.button2:  
  85.                 upLoadByHttpClient4();  
  86.                 tag = "HttpClient====>";  
  87.                 break;  
  88.             case R.id.button3:  
  89.                 upLoadByAsyncHttpClient();  
  90.                 tag = "AsyncHttpClient====>";  
  91.                 break;  
  92.             default:  
  93.                 break;  
  94.             }  
  95.         } catch (Exception e) {  
  96.             e.printStackTrace();  
  97.   
  98.         }  
  99.         Log.i(TAG, tag + "wasteTime = "  
  100.                 + (System.currentTimeMillis() - startTime));  
  101.     }  
  102.   
  103.     /** 
  104.      * upLoadByAsyncHttpClient:由人造post上传 
  105.      *  
  106.      * @return void 
  107.      * @throws IOException 
  108.      * @throws 
  109.      * @since CodingExample Ver 1.1 
  110.      */  
  111.     private void upLoadByCommonPost() throws IOException {  
  112.         String end = "\r\n";  
  113.         String twoHyphens = "--";  
  114.         String boundary = "******";  
  115.         URL url = new URL(uploadUrl);  
  116.         HttpURLConnection httpURLConnection = (HttpURLConnection) url  
  117.                 .openConnection();  
  118.         httpURLConnection.setChunkedStreamingMode(128 * 1024);// 128K  
  119.         // 允许输入输出流  
  120.         httpURLConnection.setDoInput(true);  
  121.         httpURLConnection.setDoOutput(true);  
  122.         httpURLConnection.setUseCaches(false);  
  123.         // 使用POST方法  
  124.         httpURLConnection.setRequestMethod("POST");  
  125.         httpURLConnection.setRequestProperty("Connection""Keep-Alive");  
  126.         httpURLConnection.setRequestProperty("Charset""UTF-8");  
  127.         httpURLConnection.setRequestProperty("Content-Type",  
  128.                 "multipart/form-data;boundary=" + boundary);  
  129.   
  130.         DataOutputStream dos = new DataOutputStream(  
  131.                 httpURLConnection.getOutputStream());  
  132.         dos.writeBytes(twoHyphens + boundary + end);  
  133.         dos.writeBytes("Content-Disposition: form-data; name=\"uploadfile\"; filename=\""  
  134.                 + path.substring(path.lastIndexOf("/") + 1) + "\"" + end);  
  135.         dos.writeBytes(end);  
  136.   
  137.         FileInputStream fis = new FileInputStream(path);  
  138.         byte[] buffer = new byte[8192]; // 8k  
  139.         int count = 0;  
  140.         // 读取文件  
  141.         while ((count = fis.read(buffer)) != -1) {  
  142.             dos.write(buffer, 0, count);  
  143.         }  
  144.         fis.close();  
  145.         dos.writeBytes(end);  
  146.         dos.writeBytes(twoHyphens + boundary + twoHyphens + end);  
  147.         dos.flush();  
  148.         InputStream is = httpURLConnection.getInputStream();  
  149.         InputStreamReader isr = new InputStreamReader(is, "utf-8");  
  150.         BufferedReader br = new BufferedReader(isr);  
  151.         String result = br.readLine();  
  152.         Log.i(TAG, result);  
  153.         dos.close();  
  154.         is.close();  
  155.     }  
  156.   
  157.     /** 
  158.      * upLoadByAsyncHttpClient:由HttpClient4上传 
  159.      *  
  160.      * @return void 
  161.      * @throws IOException 
  162.      * @throws ClientProtocolException 
  163.      * @throws 
  164.      * @since CodingExample Ver 1.1 
  165.      */  
  166.     private void upLoadByHttpClient4() throws ClientProtocolException,  
  167.             IOException {  
  168.         HttpClient httpclient = new DefaultHttpClient();  
  169.         httpclient.getParams().setParameter(  
  170.                 CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);  
  171.         HttpPost httppost = new HttpPost(uploadUrl);  
  172.         File file = new File(path);  
  173.         MultipartEntity entity = new MultipartEntity();  
  174.         FileBody fileBody = new FileBody(file);  
  175.         entity.addPart("uploadfile", fileBody);  
  176.         httppost.setEntity(entity);  
  177.         HttpResponse response = httpclient.execute(httppost);  
  178.         HttpEntity resEntity = response.getEntity();  
  179.         if (resEntity != null) {  
  180.             Log.i(TAG, EntityUtils.toString(resEntity));  
  181.         }  
  182.         if (resEntity != null) {  
  183.             resEntity.consumeContent();  
  184.         }  
  185.         httpclient.getConnectionManager().shutdown();  
  186.     }  
  187.   
  188.     /** 
  189.      * upLoadByAsyncHttpClient:由AsyncHttpClient框架上传 
  190.      *  
  191.      * @return void 
  192.      * @throws FileNotFoundException 
  193.      * @throws 
  194.      * @since CodingExample Ver 1.1 
  195.      */  
  196.     private void upLoadByAsyncHttpClient() throws FileNotFoundException {  
  197.         RequestParams params = new RequestParams();  
  198.         params.put("uploadfile"new File(path));  
  199.         client.post(uploadUrl, params, new AsyncHttpResponseHandler() {  
  200.             @Override  
  201.             public void onSuccess(int arg0, String arg1) {  
  202.                 super.onSuccess(arg0, arg1);  
  203.                 Log.i(TAG, arg1);  
  204.             }  
  205.         });  
  206.     }  
  207.   
  208. }  


    Andriod被我们熟知的上传就是由appache提供给的httpclient4了,毕竟比较简单,腾讯微博什么的sdk也都是这么做的,大家可以参考:

查看文本 打印 ?
  1. /** 
  2.      * Post方法传送文件和消息 
  3.      *  
  4.      * @param url  连接的URL 
  5.      * @param queryString 请求参数串 
  6.      * @param files 上传的文件列表 
  7.      * @return 服务器返回的信息 
  8.      * @throws Exception 
  9.      */  
  10.     public String httpPostWithFile(String url, String queryString, List files) throws Exception {  
  11.   
  12.         String responseData = null;  
  13.   
  14.         URI tmpUri=new URI(url);  
  15.         URI uri = URIUtils.createURI(tmpUri.getScheme(), tmpUri.getHost(), tmpUri.getPort(), tmpUri.getPath(),   
  16.                 queryString, null);  
  17.         Log.i(TAG, "QHttpClient httpPostWithFile [1]  uri = "+uri.toURL());  
  18.           
  19.           
  20.         MultipartEntity mpEntity = new MultipartEntity();  
  21.         HttpPost httpPost = new HttpPost(uri);  
  22.         StringBody stringBody;  
  23.         FileBody fileBody;  
  24.         File targetFile;  
  25.         String filePath;  
  26.         FormBodyPart fbp;  
  27.           
  28.         List queryParamList=QStrOperate.getQueryParamsList(queryString);  
  29.         for(NameValuePair queryParam:queryParamList){  
  30.             stringBody=new StringBody(queryParam.getValue(),Charset.forName("UTF-8"));  
  31.             fbp= new FormBodyPart(queryParam.getName(), stringBody);  
  32.             mpEntity.addPart(fbp);  
  33. //            Log.i(TAG, "------- "+queryParam.getName()+" = "+queryParam.getValue());  
  34.         }  
  35.           
  36.         for (NameValuePair param : files) {  
  37.             filePath = param.getValue();  
  38.             targetFile= new File(filePath);  
  39.             fileBody = new FileBody(targetFile,"application/octet-stream");  
  40.             fbp= new FormBodyPart(param.getName(), fileBody);  
  41.             mpEntity.addPart(fbp);  
  42.               
  43.         }  
  44.   
  45. //        Log.i(TAG, "---------- Entity Content Type = "+mpEntity.getContentType());  
  46.   
  47.         httpPost.setEntity(mpEntity);  
  48.           
  49.         try {  
  50.             HttpResponse response=httpClient.execute(httpPost);  
  51.             Log.i(TAG, "QHttpClient httpPostWithFile [2] StatusLine = "+response.getStatusLine());  
  52.             responseData =EntityUtils.toString(response.getEntity());  
  53.         } catch (Exception e) {  
  54.             e.printStackTrace();  
  55.         }finally{  
  56.           httpPost.abort();  
  57.         }  
  58.         Log.i(TAG, "QHttpClient httpPostWithFile [3] responseData = "+responseData);  
  59.         return responseData;  
  60.     }  


    很明显,开源框架的写法最简单有效,而且为异步的,提供出Handler进行结果返回,普通人造post代码量最大,上传速度大家也可以测一下,我附一张图,我上传的图片850kb左右

    总体看来,代码量最多的写法可能上传速度好点儿,asyncHttpClient的上传方式速度也很理想,主要是用起来简单。

   有时可能还会有上传进度返回的需求,第一种流的读写方式应该很简单解决,后两种可能还得下点儿功夫研究研究,有兴趣的朋友可以一块儿交流研究。

更多相关文章

  1. ButterKnife的用法。针对android studio3.6.1 ButterKnife10.0.0
  2. Android多语言切换,字体风格,简体转繁体
  3. 1.2android——UI界面之ScrollView实现上下文滚动
  4. Android(安卓)libmp3lame详解
  5. 如何从一个activity启动另外一个activity Android(安卓)Eclipse
  6. Android使用wheelView实现简单类似ios PickerView选择器效果
  7. Android之DatePicker和TimePicker实现以及自定义大小
  8. Android中使用代码截图的各种方法总结
  9. Android(安卓)国际化和屏幕适配

随机推荐

  1. Android(安卓)更改键盘Enter键文字
  2. android之【代码实现ImageView图片切换】
  3. Delphi XE5 Android 调用 Google ZXing
  4. android 图片叠加效果——两种方法
  5. [掌眼]iOS / Android / java / node.js
  6. Android startActivities()的使用
  7. 启动android模拟器没有反应,Failed to ope
  8. Android实现ListView点击事件+SQLite数据
  9. android典型监听事件实
  10. Android(安卓)Sensor感应器介绍(一)重力感