2012-05-25 23 views
0

我遇到以下問題。我正在使用DropBox SDK將文件上傳到Dropbox,它工作正常。當文件上傳時(在一個AsyncTask中),一個ProgressDialog會顯示一個取消按鈕,在這裏仍然可以。什麼是不正常工作,當按下取消按鈕時引發NetworkOnMainThreadException。我是Android編程新手,但我懷疑它與構造函數中的ProgressDialog有關。因爲它不在「doInBackground」部分。由於ProgressDialog,試圖繞過AsyncTask上的NetworkOnMainThreadException

試圖解決它與實施OnDismissListener和做流產onDismiss但仍然沒有運氣。當我調用「mRequest.abort()」時出現錯誤。 在此先感謝您的任何答案!

因此,這裏是我的代碼

public class DropBoxUpload extends AsyncTask<Void, Long, Boolean> implements OnDismissListener { 

    private DropboxAPI<?> mApi; 
    private String mPath; 
    private File mFile; 

    private long mFileLen; 
    private UploadRequest mRequest; 
    private Context mContext; 
    private final ProgressDialog mDialog; 

    private String mErrorMsg; 


    public DropBoxUpload(Context context, DropboxAPI<?> api, String dropboxPath, File file) { 

     // We set the context this way so we don't accidentally leak activities 
     mContext = context.getApplicationContext(); 

     mFileLen = file.length(); 
     mApi = api; 
     mPath = dropboxPath; 
     mFile = file; 

     mDialog = new ProgressDialog(context); 
     mDialog.setMax(100); 
     mDialog.setMessage("Uploading " + file.getName()); 
     mDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 
     mDialog.setProgress(0); 
     mDialog.setButton("Cancel", new OnClickListener() { 
      public void onClick(DialogInterface dialog, int which) { 
       // This will cancel the putFile operation 
       mDialog.dismiss(); 

      } 
     }); 
     mDialog.setCancelable(true); 
     mDialog.setOnDismissListener(this); 

     mDialog.show();   
    } 

    @Override 
    protected Boolean doInBackground(Void... params) { 

     try { 
      // By creating a request, we get a handle to the putFile operation, 
      // so we can cancel it later if we want to 
      FileInputStream fis = new FileInputStream(mFile); 
      String path = mPath + mFile.getName(); 
      mRequest = mApi.putFileOverwriteRequest(path, fis, mFile.length(), 
        new ProgressListener() { 
       @Override 
       public long progressInterval() { 
        // Update the progress bar every half-second or so 
        return 500; 
       } 

       @Override 
       public void onProgress(long bytes, long total) { 
        publishProgress(bytes); 
       } 
      }); 

      if (mRequest != null) { 
       mRequest.upload(); 
       return true; 
      } 

     } catch (DropboxUnlinkedException e) { 
      // This session wasn't authenticated properly or user unlinked 
      mErrorMsg = "This app wasn't authenticated properly."; 
     } catch (DropboxFileSizeException e) { 
      // File size too big to upload via the API 
      mErrorMsg = "This file is too big to upload"; 
     } catch (DropboxPartialFileException e) { 
      // We canceled the operation 
      mErrorMsg = "Upload canceled"; 
     } catch (DropboxServerException e) { 
      // Server-side exception. These are examples of what could happen, 
      // but we don't do anything special with them here. 
      if (e.error == DropboxServerException._401_UNAUTHORIZED) { 
       // Unauthorized, so we should unlink them. You may want to 
       // automatically log the user out in this case. 
      } else if (e.error == DropboxServerException._403_FORBIDDEN) { 
       // Not allowed to access this 
      } else if (e.error == DropboxServerException._404_NOT_FOUND) { 
       // path not found (or if it was the thumbnail, can't be 
       // thumbnailed) 
      } else if (e.error == DropboxServerException._507_INSUFFICIENT_STORAGE) { 
       // user is over quota 
      } else { 
       // Something else 
      } 
      // This gets the Dropbox error, translated into the user's language 
      mErrorMsg = e.body.userError; 
      if (mErrorMsg == null) { 
       mErrorMsg = e.body.error; 
      } 
     } catch (DropboxIOException e) { 
      // Happens all the time, probably want to retry automatically. 
      mErrorMsg = "Network error. Try again."; 
     } catch (DropboxParseException e) { 
      // Probably due to Dropbox server restarting, should retry 
      mErrorMsg = "Dropbox error. Try again."; 
     } catch (DropboxException e) { 
      // Unknown error 
      mErrorMsg = "Unknown error. Try again."; 
     } catch (FileNotFoundException e) { 
     } 

     return false; 
    } 

    @Override 
    protected void onProgressUpdate(Long... progress) { 
     int percent = (int)(100.0*(double)progress[0]/mFileLen + 0.5); 
     mDialog.setProgress(percent); 
    } 

    @Override 
    protected void onPostExecute(Boolean result) { 
     mDialog.dismiss();   
    } 

    @Override 
    public void onDismiss(DialogInterface arg0) { 
     // TODO Auto-generated method stub 
     mRequest.abort(); 
    } 
} 

回答

2

您不能從主UI線程訪問mRequest對象,因爲這是負責網絡操作。這就是爲什麼當你撥打mRequest.abort()時你得到NetworkOnMainThreadException

你應該修改你的代碼,這樣你就解僱對話框使用AsyncTask.cancel,並在您doInBackground檢查isCancelled定期和調用mRequest.abort()當任務被取消。

+0

thx您的快速回復!那麼如何檢查isCancelled「定期」?我會如何做這樣的事情? –

+0

通常它是在一個循環中完成的。在你的情況下,你可以在'ProgressListener'的'onProgress'方法中定期調用它。 – Rajesh

+0

Rajesh非常感謝!我只是把它放在doInBackground方法中,它就像一個魅力一樣。再次感謝!我會投你的答案,但我沒有聲望;-) –

0

你應該調用取消方法停止你的上傳過程。

ast.cancel(true); 

其中AST是您的AsyncTask對象

+0

感謝您的回答! –

相關問題