Network request doesn't work when uploading a file

久未见 提交于 2019-12-13 04:28:47

问题



I am facing a problem which I don't know how to solve.
GetDataTask works fine. But when I am uploading a file, the request is sent but the response comes only after the file upload is finished! GetDataTask and UploadTask run asynchronously using AsyncTask.
Any idea why it doesn't work and why the response doesn't come back when the file is uploading.
Is there another way to realize this?
The problem is, it is supposed to run in a parallel but unfortunately they are running synchronously.
I have posted my actual source below.
Thanks in advance.

GetData Task:

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);
    }
}

Upload Task:

    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 );
        }
    }

回答1:


Ok following are the notes from the official java doc...

Order of execution

When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.

If you truly want parallel execution, you can invoke executeOnExecutor(java.util.concurrent.Executor, Object[]) with THREAD_POOL_EXECUTOR.

SO if you invoke two AsyncTask together.. they would not be executed in parallel (exception is donut, ECLAIR and gingerbread)... You can use executeOnExecutor to execute them in parallel...




回答2:


try like this,

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);
        }
    }
}

This is HttpMultipartPost .java to upload file

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. 



回答3:


Things work fine when I replace GetData Task by a simple thread.

        new Thread( new Runnable() {

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

            }
        }).start();

There is something fishy with AsyncTask and I dont know why.



来源:https://stackoverflow.com/questions/15468563/network-request-doesnt-work-when-uploading-a-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!