Java 由于ProgressDialog,正在尝试规避AsyncTask上的NetworkOnMainThreadException

Java 由于ProgressDialog,正在尝试规避AsyncTask上的NetworkOnMainThreadException,java,android,android-asynctask,progressdialog,Java,Android,Android Asynctask,Progressdialog,我有以下问题。我正在使用DropBox SDK将一个文件上传到DropBox,效果很好。上载文件时(在AsyncTask内部),将显示一个带有取消按钮的ProgressDialog,此处仍然可以。不正常的是,当按下“取消”按钮时,会引发NetworkOnMainThreadException。我是Android编程新手,但我怀疑它与构造函数中的ProgressDialog有关。因为它不在“doInBackground”部分 试图通过实现OnDismissListener和执行onDismiss来

我有以下问题。我正在使用DropBox SDK将一个文件上传到DropBox,效果很好。上载文件时(在AsyncTask内部),将显示一个带有取消按钮的ProgressDialog,此处仍然可以。不正常的是,当按下“取消”按钮时,会引发NetworkOnMainThreadException。我是Android编程新手,但我怀疑它与构造函数中的ProgressDialog有关。因为它不在“doInBackground”部分

试图通过实现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();
    }
}
公共类DropBoxUpload扩展AsyncTask实现OnDismissListener{
私有DropboxAPI mApi;
私有字符串mPath;
私有文件文件;
私人长姆费伦;
私有上传请求mRequest;
私有上下文;
私人最终进度对话框;
私有字符串merrormg;
公共DropBoxUpload(上下文上下文、DropboxAPI、字符串dropboxPath、文件){
//我们以这种方式设置上下文,以免意外泄漏活动
mContext=context.getApplicationContext();
mfilen=file.length();
mApi=api;
mPath=dropboxPath;
mFile=文件;
mDialog=新建进度对话框(上下文);
mDialog.setMax(100);
mDialog.setMessage(“上载”+文件.getName());
mDialog.setProgressStyle(ProgressDialog.STYLE_水平);
mDialog.setProgress(0);
mDialog.setButton(“取消”,新建OnClickListener()){
public void onClick(DialogInterface dialog,int which){
//这将取消putFile操作
mDialog.discouse();
}
});
mDialog.setCancelable(真);
mDialog.setOnDismissListener(此);
mDialog.show();
}
@凌驾
受保护的布尔doInBackground(Void…params){
试一试{
//通过创建请求,我们获得putFile操作的句柄,
//如果我们想的话,我们可以以后取消
FileInputStream fis=新的FileInputStream(mFile);
字符串路径=mPath+mFile.getName();
mRequest=mApi.putFileOverwriteRequest(路径,fis,mFile.length(),
新ProgressListener(){
@凌驾
公共长时间间隔(){
//大约每半秒更新一次进度条
返回500;
}
@凌驾
public void onProgress(长字节,长总计){
出版进度(字节);
}
});
if(mRequest!=null){
mRequest.upload();
返回true;
}
}捕获(DropboxUnlinkedException){
//此会话未正确验证或用户未链接
mErrorMsg=“此应用未正确验证。”;
}捕获(DropboxFileSizeException e){
//文件太大,无法通过API上载
mErrorMsg=“此文件太大,无法上载”;
}捕获(DropboxPartialFileE异常){
//我们取消了手术
mErrorMsg=“上传已取消”;
}捕获(DropboxServerException e){
//服务器端异常。这些是可能发生的情况的示例,
//但我们在这里对他们没有什么特别的处理。
如果(e.error==DropboxServerException.\u 401\u未经授权){
//未经授权,所以我们应该取消它们的链接。您可能想要
//在这种情况下,自动注销用户。
}否则如果(e.error==DropboxServerException.\u 403\u禁止){
//不允许访问此文件
}else if(e.error==DropboxServerException.\u 404\u未找到){
//未找到路径(或者如果是缩略图,则无法
//拇指钉)
}否则如果(e.error==DropboxServerException.\u 507\u存储不足){
//用户超过配额
}否则{
//别的
}
//这将获取Dropbox错误,并将其翻译成用户的语言
mErrorMsg=e.body.userError;
if(mErrorMsg==null){
mErrorMsg=e.body.error;
}
}捕获(DropboxIOE异常){
//经常发生,可能要自动重试。
mErrorMsg=“网络错误。请重试。”;
}捕获(DropboxParse异常){
//可能是由于Dropbox服务器重新启动,应该重试
mErrorMsg=“Dropbox错误。请重试。”;
}捕获(DropBoxexException e){
//未知错误
mErrorMsg=“未知错误。请重试。”;
}catch(filenotfounde异常){
} 
返回false;
}
@凌驾
受保护的void onProgressUpdate(长…进度){
整数百分比=(整数)(100.0*(双倍)进度[0]/mFileLen+0.5);
mDialog.setProgress(百分比);
}
@凌驾
受保护的void onPostExecute(布尔结果){
mDialog.discouse();
}
@凌驾
public void onDismiss(对话框接口arg0){
//TODO自动生成的方法存根
mRequest.abort();
}
}

您应该调用cancel方法来停止上载过程

ast.cancel(true);

其中ast是asynctask对象

您不能从主UI线程访问
mRequest
对象,因为这是负责网络操作的对象。这就是为什么调用
mRequest.abort()
时会出现
networkMainThreadException

你应该修改你的计划