上传文件时网络请求不起作用

时间:2013-03-18 01:42:35

标签: android android-asynctask android-networking


我正面临着一个我不知道如何解决的问题 GetDataTask工作正常。但是当我上传文件时,会发送请求,但只有在文件上传完成后才会响应! GetDataTask和UploadTask使用AsyncTask异步运行 知道为什么它不起作用以及为什么文件上传时响应不会回来 还有另一种方法可以实现这一点吗? 问题是,它应该并行运行但不幸的是它们同步运行 我在下面发布了我的实际来源 提前谢谢。

GetData任务

private class GetDataTask extends AsyncTask<String, Void, String>{

    @Override
    protected void onPreExecute() {

    }

    @Override
    protected String doInBackground(String... params) {
        return NetConnection.getRecordData(mUserId, mUserPassword);
    }

    @Override
    protected void onPostExecute(String result) {
        parseJson(result);
    }
}

上传任务

    private class HttpMultipartPost extends AsyncTask<String, Integer, String>
    {
        TextProgressBar pb;
        long totalSize;
        String filePath;

        @Override
        protected void onPreExecute()
        {
            pb = (TextProgressBar) findViewById(R.id.idPBUploadProgress);
            pb.setMax(100);
        }

        @Override
        protected String doInBackground(String... arg)
        {
            HttpClient httpClient = new DefaultHttpClient();
            HttpContext httpContext = new BasicHttpContext();
            HttpPost httpPost = new HttpPost( Utils.UPLOAD_URL );

            try
            {
                CustomMultiPartEntity multipartContent = new CustomMultiPartEntity(new ProgressListener()
                {
                    @Override
                    public void transferred(long num)
                    {
                        publishProgress((int) ((num / (float) totalSize) * 100));
                        //Log.v(TAG, "Progress =" + num);
                    }
                });

                // We use FileBody to transfer an file
                filePath = arg[0];
                multipartContent.addPart("upfile", new FileBody(new File( filePath )));
                totalSize = multipartContent.getContentLength();
                Log.e(TAG, "Upload file size = " + totalSize/1048576 + "MB") ;

                // Send it
                httpPost.setEntity(multipartContent);
                HttpResponse response = httpClient.execute(httpPost, httpContext);
                String serverResponse = EntityUtils.toString(response.getEntity());

                return serverResponse;
            }

            catch (Exception e)
            {
                System.out.println(e);
            }
            return null;
        }

        @Override
        protected void onProgressUpdate(Integer... progress)
        {
            pb.setProgress((int) (progress[0]));
            pb.setText(progress[0] + "%");
        }

        @Override
        protected void onPostExecute(String result)
        {
            Log.e(TAG, "Response =" + result);
            parseResult( result, filePath );
        }
    }

3 个答案:

答案 0 :(得分:3)

以下是official java doc ...

的说明
  

执行顺序

     

首次引入时,AsyncTasks在单个上串行执行   背景线程。从DONUT开始,这已更改为a   允许多个任务并行运行的线程池。   从HONEYCOMB开始,任务在单个线程上执行   避免因并行执行而导致的常见应用程序错误。

     

如果您真的想要并行执行,可以调用   executeOnExecutor(java.util.concurrent.Executor, Object[])   THREAD_POOL_EXECUTOR

所以如果你一起调用两个AsyncTask ......它们不会并行执行(例外是甜甜圈,ECLAIR和姜饼)......你可以使用executeOnExecutor并行执行它们......

答案 1 :(得分:0)

尝试这样,

package com.file.upload;

import java.io.FilterOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;

import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntity;

public class CustomMultiPartEntity extends MultipartEntity{

    private final ProgressListener listener;

    public CustomMultiPartEntity (final ProgressListener listener)
    {
        super();
        this.listener = listener;
    }

    public CustomMultiPartEntity (final HttpMultipartMode mode, final ProgressListener listener)
    {
        super(mode);
        this.listener = listener;
    }

    public CustomMultiPartEntity (HttpMultipartMode mode, final String boundary, final Charset charset, final ProgressListener listener)
    {
        super(mode, boundary, charset);
        this.listener = listener;
    }

    @Override
    public void writeTo(final OutputStream outstream) throws IOException
    {
        super.writeTo(new CountingOutputStream(outstream, this.listener));
    }

    public static interface ProgressListener
    {
        void transferred(long num);
    }

    public static class CountingOutputStream extends FilterOutputStream
    {

        private final ProgressListener listener;
        private long transferred;

        public CountingOutputStream(final OutputStream out, final ProgressListener listener)
        {
            super(out);
            this.listener = listener;
            this.transferred = 0;
        }

        public void write(byte[] b, int off, int len) throws IOException
        {
            out.write(b, off, len);
            this.transferred += len;
            this.listener.transferred(this.transferred);
        }

        public void write(int b) throws IOException
        {
            out.write(b);
            this.transferred++;
            this.listener.transferred(this.transferred);
        }
    }
}

这是HttpMultipartPost .java上传文件

import java.io.File;
    import java.io.IOException;
    import org.apache.http.HttpResponse;
    import org.apache.http.HttpStatus;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.mime.MultipartEntity;
    import org.apache.http.entity.mime.content.ContentBody;
    import org.apache.http.entity.mime.content.FileBody;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.params.BasicHttpParams;
    import org.apache.http.params.HttpConnectionParams;
    import org.apache.http.params.HttpParams;
    import org.apache.http.util.EntityUtils;
    import com.file.upload.MyMultipartEntity.ProgressListener;
    import android.app.ProgressDialog;
    import android.content.Context;
    import android.os.AsyncTask;
    import android.util.Log;

        public class HttpMultipartPost extends AsyncTask<Void, Integer, Void> {

            private Context context;
            private String filepath;

            private HttpClient client;

            private ProgressDialog pd;
            private long totalSize;

            private static final String url = "Your URL";

            public HttpMultipartPost (Context context, String filepath) {
                super();
                this.context = context;
                this.filepath= filepath;
            }

            @Override
            protected void onPreExecute() {
                //Set timeout parameters
                int timeout = 10000;
                HttpParams httpParameters = new BasicHttpParams();
                HttpConnectionParams.setConnectionTimeout(httpParameters, timeout);
                HttpConnectionParams.setSoTimeout(httpParameters, timeout);

                //We'll use the DefaultHttpClient
                client = new DefaultHttpClient(httpParameters);

                pd = new ProgressDialog(context);
                pd.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                pd.setMessage("Uploading File...");
                pd.setCancelable(false);
                pd.show();
            }

            @Override
            protected Void doInBackground(Void... params) {
                try {
                    File file = new File(filepath);

                    //Create the POST object
                    HttpPost post = new HttpPost(url);

                    //Create the multipart entity object and add a progress listener
                    //this is a our extended class so we can know the bytes that have been transfered
                    MultipartEntity entity = new CustomMultiPartEntity (new ProgressListener()
                    {
                        @Override
                        public void transferred(long num)
                        {
                            //Call the onProgressUpdate method with the percent completed
                            publishProgress((int) ((num / (float) totalSize) * 100));
                            Log.d("DEBUG", num + " - " + totalSize);
                        }
                    });
                    //Add the file to the content's body
                    ContentBody cbFile = new FileBody( file, "image/jpeg" );// change according
                    entity.addPart("source", cbFile);

                    //After adding everything we get the content's lenght
                    totalSize = entity.getContentLength();

                    //We add the entity to the post request
                    post.setEntity(entity);

                    //Execute post request
                    HttpResponse response = client.execute( post );
                    int statusCode = response.getStatusLine().getStatusCode();

                    if(statusCode == HttpStatus.SC_OK){
                        //If everything goes ok, we can get the response
                        String fullRes = EntityUtils.toString(response.getEntity());
                        Log.d("DEBUG", fullRes);

                    } else {
                        Log.d("DEBUG", "HTTP Fail, Response Code: " + statusCode);
                    }

                } catch (ClientProtocolException e) {
                    // Any error related to the Http Protocol (e.g. malformed url)
                    e.printStackTrace();
                } catch (IOException e) {
                    // Any IO error (e.g. File not found)
                    e.printStackTrace();
                }


                return null;
            }

            @Override
            protected void onProgressUpdate(Integer... progress) {
                //Set the pertange done in the progress dialog
                pd.setProgress((int) (progress[0]));
            }

            @Override
            protected void onPostExecute(Void result) {
                //Dismiss progress dialog
                pd.dismiss();
            }

        }


Hope this will helpful to you. 

答案 2 :(得分:0)

当我用一个简单的线程替换 GetData Task 时,工作正常。

        new Thread( new Runnable() {

            @Override
            public void run() {
                String res = NetConnection. getRecordData(mUserId, mUserPassword);
                Log.e(TAG, res);
                parseJson(res);

            }
        }).start();

AsyncTask有些可疑,我不知道为什么。