0


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

获取数据任务

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

3 回答 3

3

好的,以下是官方 java 文档中的注释...

执行顺序

首次引入时,AsyncTask 在单个后台线程上串行执行。从DONUT开始,这被更改为允许多个任务并行运行的线程池。从HONEYCOMB开始,任务在单个线程上执行,以避免并行执行导致的常见应用程序错误。

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

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

于 2013-03-18T09:06:10.610 回答
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. 
于 2013-03-18T02:04:14.500 回答
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 有点可疑,我不知道为什么。

于 2013-03-18T03:45:38.633 回答