Android AsyncTask onPostExecute方法

Android AsyncTask onPostExecute方法,android,android-asynctask,Android,Android Asynctask,编辑:如果我根本不使用进度,只显示对话框,那么一切都可以正常工作。但若我添加了进度,那个么对话框就不会关闭(不会触发onPostExecute()方法) 未执行onPostExecute方法。我哪里出错了?(模拟器和设备上的结果相同) 我也不确定是否应该对这些方法使用覆盖符号 这是目前的粗略解决方案。它每次都有效,但不是合适的,也不是好的。 我在做什么: *我使用tabgroupactivity启动子活动 *然后我导航到子活动中的另一个活动,因此它是父活动的当前子活动 *有一个webview,

编辑:如果我根本不使用进度,只显示对话框,那么一切都可以正常工作。但若我添加了进度,那个么对话框就不会关闭(不会触发onPostExecute()方法)


未执行onPostExecute方法。我哪里出错了?(模拟器和设备上的结果相同) 我也不确定是否应该对这些方法使用覆盖符号

这是目前的粗略解决方案。它每次都有效,但不是合适的,也不是好的。 我在做什么: *我使用tabgroupactivity启动子活动 *然后我导航到子活动中的另一个活动,因此它是父活动的当前子活动 *有一个webview,我在其中显示有关一条评论的信息。。无论什么 *webView显示的内容中有一个链接 *当我点击它时,我开始下载PDF文件

下载文件时:

    while ((current = bis.read()) != -1) {
        read = read + current;
        baf.append((byte) current);
        Dialog.setProgress(read);

        if(Dialog.isShowing() && read+2*current>file_size){
            Dialog.dismiss();
            Dialog.cancel();
        }
    }
我的Dialog对象被禁用,所以如果我尝试在While循环之后调用Dialog,我就是不明白。所以我所做的是,每次我从网站获得新的缓冲区时,我都会检查对话框是否仍然可见,如果当前字节加上到目前为止读取的字节数大于文件的完整大小,那么我会在while循环中关闭对话框。 我试着使用fileSize==read(字节数),但它不起作用,可能在下载文件时它们之间并不完全相同

private class DownloadPDFFile extends AsyncTask<String, Integer, Void> {
    private ProgressDialog Dialog = new ProgressDialog(getParent());

    protected void onPreExecute() {
        Dialog.setMessage("Downloading PDF file..");
        Dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        Dialog.setCancelable(false);
        // Dialog.setMax(1000);
        Dialog.setProgress(0);
        Dialog.show();
    }

    protected Void doInBackground(String... urls) {
        File file=null;
        int file_size = 0;
        try {
            URL url = new URL(urls[0]);
            URLConnection urlConnection = url.openConnection();
            urlConnection.connect();
            file_size = urlConnection.getContentLength();
            Dialog.setMax(file_size);
        } catch (IOException e) {

        }

        try {
            URL url1 = new URL(urls[0]); // you can // link

            file = new File("skm_intern_pdf.pdf");

            URLConnection ucon = url1.openConnection();

            InputStream is = ucon.getInputStream();

            BufferedInputStream bis = new BufferedInputStream(is);

            ByteArrayBuffer baf = new ByteArrayBuffer(5000);
            int read = 0;
            int current = 0;
            while ((current = bis.read()) != -1) {
                read = read + current;
                baf.append((byte) current);
                Dialog.setProgress(read);

                if(Dialog.isShowing() && read+2*current>file_size){
                    Dialog.dismiss();
                    Dialog.cancel();
                }
            }

            FileOutputStream fos = openFileOutput("skm_pdf.pdf",
                    Context.MODE_WORLD_WRITEABLE);
            fos.write(baf.toByteArray());
            fos.flush();
            fos.close();

        } catch (IOException e) {

        }

        return null;
        }
私有类下载Pffile扩展异步任务{
private ProgressDialog=新建ProgressDialog(getParent());
受保护的void onPreExecute(){
setMessage(“下载PDF文件…”);
设置ProgressStyle(ProgressDialog.STYLE_水平);
对话框。可设置可取消(false);
//Dialog.setMax(1000);
对话框。设置进度(0);
Dialog.show();
}
受保护的Void doInBackground(字符串…URL){
File=null;
int file_size=0;
试一试{
URL=新URL(URL[0]);
URLConnection URLConnection=url.openConnection();
urlConnection.connect();
文件_size=urlConnection.getContentLength();
setMax(文件大小);
}捕获(IOE异常){
}
试一试{
URL url1=新URL(URL[0]);//您可以//链接
文件=新文件(“skm_intern_pdf.pdf”);
URLConnection ucon=url1.openConnection();
InputStream=ucon.getInputStream();
BufferedInputStream bis=新的BufferedInputStream(is);
ByteArrayBuffer baf=新ByteArrayBuffer(5000);
int read=0;
int电流=0;
而((当前=bis.read())!=-1){
读取=读取+当前;
baf.append((字节)当前值);
对话框。设置进度(读取);
if(Dialog.isShowing()&&read+2*当前>文件大小){
Dialog.dismise();
Dialog.cancel();
}
}
FileOutputStream fos=openFileOutput(“skm_pdf.pdf”,
上下文。模式(世界可写);
fos.write(baf.toByteArray());
fos.flush();
fos.close();
}捕获(IOE异常){
}
返回null;
}

IMHO,您只需要删除super调用。

异步任务的父任务是否在异步任务完成之前取消/暂停/销毁


如果是,AsyncTask可能会收到一个
cancel()
,这将导致
onPostExecute()
永远不会运行。要验证这一点,请尝试重写
onCancelled()
-方法并检查它是否运行。

有趣的是,您可以发布3次相同的答案,因为人们在发布之前不进行搜索。。。 除了UI线程外,您不允许从任何位置访问UI线程…这意味着您的Dialog.Dislose和Dialog.cancel无法执行,因为它不是线程安全的

要解决您的问题,您有几种方法。第一种方法:不要使用
AsyncTask
,因为您每次都会运行5个任务(最多)…我将您发送到
AsyncTask
的Android文档,以及附加的进程和线程指南,以获取更多信息

第二种方式:
onPostExecute()
中移动所有与UI线程相关的方法。这是线程安全的,并且
doInBackground()
的结果会自动传输给它

第三种方式:在下列情况下使用

Activity.runOnUiThread(Runnable)
View.post(Runnable)
View.postDelayed(Runnable, long)
Runnable将在UI线程内执行。同样,线程安全

如果您确实不需要对应用程序进行彻底优化,我建议使用第二种解决方案。如果需要,请使用手动添加到手动创建的
ThreadPoolExecutor
(请再次参阅
ThreadPoolExecutor
的文档)中的任务

在搜索文档时,我发现:

要使此类正常工作,必须遵循以下几个线程规则:

如果不在UI线程上,请不要使用
AsyncTask
,而是使用Task,使用
ThreadPoolExecutor
来包装它们

这就是为什么不应使用
Asynctask

在答案中查找我的名字。

我发现此线程正在搜索相同的问题。经过多次尝试和错误,我发现了两个问题:

  • 有时我会取消doInBackground中的任务,而不是让方法正常完成,导致onCancelled()而不是onPostExecute()触发。谢谢你的提示,Kasper

  • 显然,我对onPostExecute使用了错误的方法签名。如果没有返回类型,则需要:

    受保护的void onPostExecute(void v)


  • 不是很直观,也没有在API中显示,但一旦我这样做了,这就成功了。

    你基于什么理由得出结论说onPostExecute从未被调用?请发布一些logcat.sys.out+一直在做的对话框。dismise();如果
    The task instance must be created on the UI thread.
    execute(Params...) must be invoked on the UI thread.
    Do not call onPreExecute(), onPostExecute(Result), 
    doInBackground(Params...), onProgressUpdate(Progress...) 
    manually.
    The task can be executed only once (an exception will be thrown  
    if a second execution is attempted.)