繁体   English   中英

在AsyncTask中关闭进度对话框时,Android应用会强制关闭

[英]Android app force close when dismissing progress dialog in asynctask

我在主要活动中使用子类来执行asynctask。 我计划以后将其移动到一个单独的文件中,我只是更喜欢以这种方式进行操作以确认其正常工作。 我正在尝试使用进度对话框执行HTTPRequest ,因为等待时间可能很长。 我在doInBackground()什么也不做,因为我读到您不能从那里访问UI层。 最终发生的事情是我在onPreExecute()上显示进度对话框,并在onPostExecute()其关闭。 我在上面分别调用每个任务,这可能是我问题的99%,但我需要能够将我的活动传递给任务,以使其正常运行。

我已经将很多步骤分解为小块。 我收到了一个空指针异常,这使我相信我的问题来自于不使用execute(),但是我似乎无法弄清楚它是如何工作的。

new CodeRetrievalItem().onPreExecute(MyActivity.this);

new CodeRetrievalItem().onPostExecute(MyActivity.this);

class CodeRetrievalItem extends AsyncTask<Void, Void, Void>{

ProgressDialog dialog;
protected void onPreExecute(Activity actpass){
        dialog = new  ProgressDialog(actpass);
    dialog.setMessage("Loading");
    dialog.setIndeterminate(false); 
    dialog.setCancelable(false);
    dialog.show();

}

@Override
protected Void doInBackground(Void... arg0) {
    // TODO Auto-generated method stub
    return null;
}

protected void onPostExecute(Activity actpass){

            // Execute HTTP Request
    try{
        dialog.dismiss();
    }
    catch(Exception e){
        Toast.makeText(actpass, "IOE response " + e.toString(), Toast.LENGTH_LONG).show();
    }

}

}

您使用AsyncTask完全错误。 您的代码中有几个主要错误。

AsyncTask受保护的方法

不要自己叫他们。 AsyncTask文档中 ,您可以找到:

不要手动调用onPreExecute(),onPostExecute(Result),doInBackground(Params ...),onProgressUpdate(Progress ...)。

您必须通过调用execute(Params...)方法来启动AsyncTask 这将导致:

  1. onPreExecute()在后台执行开始之前被调用,并在主线程上被调用
  2. doInBackground(Params...)在后台调用
  3. 后台执行完成后,在主线程上调用onPostExecute(Result)

除非您调用execute(Params...) ,否则将不会发生任何事情。

通用参数

此外,您的通用参数存在问题。 AsyncTask具有三个通用参数AsyncTask<Params, Progress, Result> (在您的情况下AsyncTask<Void, Void, Void> ,您必须在方法的参数中匹配这些参数。

因此创建:

  1. onPreExecute()而不是onPreExecute(Activity actpass)
  2. onPostExecute(Void)代替onPostExecute(Activity actpass)

您定义的那些方法不以任何方式绑定到异步执行,它们只是类中的一些额外方法。

如果您需要访问AsyncTask内部的活动,请以其他方式(例如,在构造函数中)传递它。 请注意,将Activity传递给AsyncTask可能会导致可能的内存泄漏(在此处利用WeakReference<T>很好),并且如果处理不当,则访问onPostExecute(Result)对话框可能会导致崩溃。

像这样改变你的代码

new CodeRetrievalItem(MyActivity.this).execute();



class CodeRetrievalItem extends AsyncTask<Void, Void, Void>{
Activity context;
public CodeRetrievalItem(Activity actpass)
{
context=actpass;
}
ProgressDialog dialog;
protected void onPreExecute(Activity actpass){
        dialog = new  ProgressDialog(context);
    dialog.setMessage("Loading");
    dialog.setIndeterminate(false); 
    dialog.setCancelable(false);
    dialog.show();

}

@Override
protected Void doInBackground(Void... arg0) {
    // TODO Auto-generated method stub
    return null;
}

protected void onPostExecute(Activity actpass){

            // Execute HTTP Request
    try{
        dialog.dismiss();
    }
    catch(Exception e){
        Toast.makeText(context, "IOE response " + e.toString(), Toast.LENGTH_LONG).show();
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM