2013-03-18 85 views
0


我遇到了一個我不知道如何解決的問題。
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); 
     } 
    } 
+0

什麼Android版本以及你如何打電話給他們? – codeMagic 2013-03-18 02:08:07

+0

@Lazy Ninja在下面看到我的答案。使用此代碼,您可以在%(上傳到服務器)中顯示水平進度條。謝謝 – 2013-03-18 02:08:29

+0

@codeMagic我正在測試Android 4.0.3設備。 – 2013-03-18 02:11:21

回答

3

好以下是筆記從official java doc ...

執行

當首次推出的順序,分別AsyncTasks在單個 後臺線程串行執行。從DONUT開始,這被改爲 線程池,允許多個任務並行操作。 從HONEYCOMB開始,任務在單個線程上執行到 ,避免由並行執行導致的常見應用程序錯誤。

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

所以如果你調用2周的AsyncTask一起..他們不會並行執行(異常甜甜圈,ECLAIR和薑餅)...你可以使用executeOnExecutor並行執行他們...

+0

感謝您的幫助! – 2013-03-18 09:09:37

+1

很高興我能幫到你.. – 2013-03-18 09:10:09

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. 
+0

謝謝你的努力!我想我正在使用和你一樣的邏輯。上傳對我來說很好。我的問題是當我上傳文件時,我無法發出其他網絡請求。它應該並行運行,但不幸的是它們正在同步運行。 – 2013-03-18 02:09:53

0

事情工作正常,當我用一個簡單的線程替換GetData任務

 new Thread(new Runnable() { 

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

      } 
     }).start(); 

有一些與AsyncTask魚腥味,我不知道爲什麼。