接上一篇文章《Android上传文件到Web服务器,PHP接收文件(一)》,这次在之前的基础上添加进度显示,Java代码如下所示:

package com.lenovo.uptest;import java.io.DataInputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.net.HttpURLConnection;import java.net.URL;import android.app.Activity;import android.app.AlertDialog;import android.app.ProgressDialog;import android.content.DialogInterface;import android.os.AsyncTask;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.TextView;public class UploadtestActivity extends Activity {/** Called when the activity is first created. *//** * Upload file to web server with progress status, client: android; * server:php * **/private TextView mtv1 = null;private TextView mtv2 = null;private Button bupload = null;private String uploadFile = "/sdcard/testimg.jpg";private String actionUrl = "http://10.100.1.208/receive_file.php";@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);mtv1 = (TextView) findViewById(R.id.mtv1);mtv1.setText("文件路径:\n" + uploadFile);mtv2 = (TextView) findViewById(R.id.mtv2);mtv2.setText("上传地址:\n" + actionUrl);bupload = (Button) findViewById(R.id.bupload);bupload.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubFileUploadTask fileuploadtask = new FileUploadTask();fileuploadtask.execute();}});}// show Dialog methodprivate void showDialog(String mess) {new AlertDialog.Builder(UploadtestActivity.this).setTitle("Message").setMessage(mess).setNegativeButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {}}).show();}class FileUploadTask extends AsyncTask<Object, Integer, Void> {private ProgressDialog dialog = null;HttpURLConnection connection = null;DataOutputStream outputStream = null;DataInputStream inputStream = null;//the file path to uploadString pathToOurFile = "/sdcard/testimg.jpg";//the server address to process uploaded fileString urlServer = "http://10.100.1.208/receive_file.php";String lineEnd = "\r\n";String twoHyphens = "--";String boundary = "*****";File uploadFile = new File(pathToOurFile);long totalSize = uploadFile.length(); // Get size of file, bytes@Overrideprotected void onPreExecute() {dialog = new ProgressDialog(UploadtestActivity.this);dialog.setMessage("正在上传...");dialog.setIndeterminate(false);dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);dialog.setProgress(0);dialog.show();}@Overrideprotected Void doInBackground(Object... arg0) {long length = 0;int progress;int bytesRead, bytesAvailable, bufferSize;byte[] buffer;int maxBufferSize = 256 * 1024;// 256KBtry {FileInputStream fileInputStream = new FileInputStream(new File(pathToOurFile));URL url = new URL(urlServer);connection = (HttpURLConnection) url.openConnection();// Set size of every block for postconnection.setChunkedStreamingMode(256 * 1024);// 256KB// Allow Inputs & Outputsconnection.setDoInput(true);connection.setDoOutput(true);connection.setUseCaches(false);// Enable POST methodconnection.setRequestMethod("POST");connection.setRequestProperty("Connection", "Keep-Alive");connection.setRequestProperty("Charset", "UTF-8");connection.setRequestProperty("Content-Type","multipart/form-data;boundary=" + boundary);outputStream = new DataOutputStream(connection.getOutputStream());outputStream.writeBytes(twoHyphens + boundary + lineEnd);outputStream.writeBytes("Content-Disposition: form-data; name=\"uploadedfile\";filename=\""+ pathToOurFile + "\"" + lineEnd);outputStream.writeBytes(lineEnd);bytesAvailable = fileInputStream.available();bufferSize = Math.min(bytesAvailable, maxBufferSize);buffer = new byte[bufferSize];// Read filebytesRead = fileInputStream.read(buffer, 0, bufferSize);while (bytesRead > 0) {outputStream.write(buffer, 0, bufferSize);length += bufferSize;progress = (int) ((length * 100) / totalSize);publishProgress(progress);bytesAvailable = fileInputStream.available();bufferSize = Math.min(bytesAvailable, maxBufferSize);bytesRead = fileInputStream.read(buffer, 0, bufferSize);}outputStream.writeBytes(lineEnd);outputStream.writeBytes(twoHyphens + boundary + twoHyphens+ lineEnd);publishProgress(100);// Responses from the server (code and message)int serverResponseCode = connection.getResponseCode();String serverResponseMessage = connection.getResponseMessage();/* 将Response显示于Dialog */// Toast toast = Toast.makeText(UploadtestActivity.this, ""// + serverResponseMessage.toString().trim(),// Toast.LENGTH_LONG);// showDialog(serverResponseMessage.toString().trim());/* 取得Response内容 */// InputStream is = connection.getInputStream();// int ch;// StringBuffer sbf = new StringBuffer();// while ((ch = is.read()) != -1) {// sbf.append((char) ch);// }//// showDialog(sbf.toString().trim());fileInputStream.close();outputStream.flush();outputStream.close();} catch (Exception ex) {// Exception handling// showDialog("" + ex);// Toast toast = Toast.makeText(UploadtestActivity.this, "" +// ex,// Toast.LENGTH_LONG);}return null;}@Overrideprotected void onProgressUpdate(Integer... progress) {dialog.setProgress(progress[0]);}@Overrideprotected void onPostExecute(Void result) {try {dialog.dismiss();// TODO Auto-generated method stub} catch (Exception e) {}}}}

服务器端仍然和之前的一样。

这里使用了AsyncTask,它使创建需要与用户界面交互的长时间运行的任务变得更简单,适用于简单的异步处理,不需要借助线程和Handler即可实现。
AsyncTask是抽象类.AsyncTask定义了三种泛型类型 Params,Progress和Result。
  Params 启动任务执行的输入参数,比如HTTP请求的URL。
  Progress 后台任务执行的百分比。
  Result 后台执行任务最终返回的结果,比如String。

AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。
  1) 子类化AsyncTask
  2) 实现AsyncTask中定义的下面一个或几个方法
  onPreExecute(), 该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。
  doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
  onProgressUpdate(Progress...),在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
  onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread.

为了正确的使用AsyncTask类,以下是几条必须遵守的准则:
  1) Task的实例必须在UI thread中创建
  2) execute方法必须在UI thread中调用
  3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法
  4) 该task只能被执行一次,否则多次调用时将会出现异常
doInBackground方法和onPostExecute的参数必须对应,这两个参数在AsyncTask声明的泛型参数列表中指定,第一个为doInBackground接受的参数,第二个为显示进度的参数,第三个为doInBackground返回和onPostExecute传入的参数。

运行结果如下:


更多相关文章

  1. Android关机流程解析
  2. Android常用Manager
  3. android 清除所有activity
  4. RelativeLayout相对布局方法总结
  5. Android全屏时软键盘遮住输入框修改布局解决方案
  6. Android中设置中文粗体的方法
  7. Android如何进行数字签名与优化
  8. 浅谈Java中Collections.sort对List排序的两种方法
  9. Python list sort方法的具体使用

随机推荐

  1. Spinnaker持续交付实战
  2. pdb clone mos文档
  3. 在vim中设置tab缩进为4个字符
  4. python入门教程13-04 (语法入门之记录相关
  5. 用查找替换命令删除文件中行首的空白字符
  6. golang语言学习之数据类型
  7. 软链接与硬链接的区别
  8. 自学C语言的第一天
  9. 文件的元数据信息查看及修改文件时间戳信
  10. 远程克隆PDB