使用超时杀死Android AsyncTask

时间:2015-06-17 22:47:35

标签: java android android-asynctask timeout jsoup

所以我的问题是我有一个AsyncTask从服务器上的页面中删除html所以我使用Jsoup作为库。 所以问题是我想设置一个超时来取消任务,如果我没有从页面收到任何数据并显示吐司上有“通信错误”

无论如何都要杀死或停止其中的asynctask并在onPostExecute上返回一个结果

{
private class getPageTitle extends AsyncTask<Void, Void, String> {
        String title;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            connectServerProgressDialog = new ProgressDialog(LoginScreen.this);
            connectServerProgressDialog.setTitle("CheckingServer");
            connectServerProgressDialog.setMessage("Loading...");
            connectServerProgressDialog.setIndeterminate(true);

            connectServerProgressDialog.show();
        }

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


            try {

                // Connect to the web site
                                Document document = Jsoup.connect(CONNECT_URL).get();

                            title = document.title();

                           } catch (IOException e) {

                e.printStackTrace();
            }

            return null ;
        }

        @Override
        protected void onPostExecute(String result) {

            if(result!=null){

            switch (title) {
                case "0":
                    Toast.makeText(LoginScreen.this,"offline",Toast.LENGTH_SHORT).show();
                    connectServerProgressDialog.dismiss();
                    break;
                case "1":
                    connectServerProgressDialog.dismiss();
                     Toast.makeText(LoginScreen.this,"Connected",Toast.LENGTH_SHORT).show();
                    break;

            }}else{
                Toast.makeText(LoginScreen.this,"Communication error",Toast.LENGTH_SHORT).show();
            }

            }
        }}

1 个答案:

答案 0 :(得分:0)

我有一个用于AsyncTask子类的约定。

  • 定义客户端要使用的内部接口。这会将客户端类解耦,以便可以重用AsyncTask。界面以blahblahListener
  • 的形式命名
  • 界面有两种形式blahblahCompleted()blahblahException()
  • 接受作为该接口实现的回调对象(侦听器)。这可以在AsyncTask构造函数中传递,也可以使用setListener()方法设置。
  • WeakReference字段中保留该侦听器引用,以便如果侦听器在任务完成之前消失,则仍可以对侦听器进行垃圾回收。
  • 定义一个字段以容纳Exception。如果后台方法中发生异常,则此字段会记住该异常,以便将其报告给客户端。
  • onPostExecute()方法中,检查Exception字段是否为null。如果是,请使用结果调用blahblahCompleted()。如果不是,请使用例外情况调用blahblahException()。另请检查WeakReference是否仍然有效。

要终止任务,您可以在连接上设置超时。然后,当您的连接超时时,您将收到一个异常,会被记住并报告。

因此,使用该约定,您的代码将如下所示:

public class WebPageTitleRemoteTask extends AsyncTask<URL, Void, String> {

    private WeakReference<WebPageTitleRetrievalListener> mListener;

    private Exception mException;

    public WebPageTitleRemoteTask(WebPageTitleRetrievalListener listener) {
        super();
        mListener = new WeakReference<WebPageTitleRetrievalListener>(listener);
    }

    @Override
    protected String doInBackground(URL... params) {

        String title = null;

        try {
            // Connect to the web site
            Document document = Jsoup.connect(params[0]).get();
            title = document.title();

        } catch (IOException e) {
            mException = e;
        }

        return title;
    }

    @Override
    protected void onPostExecute(String result) {

        WebPageTitleRetrievalListener listener = mListener.get();
        if (listener != null) {
            if (mException == null) {
                listener.webPageTitleRetrieved(result);
            } else {
                listener.webPageTitleRetrievalException(mException);
            }
        }
    }

    public static interface WebPageTitleRetrievalListener {

        public void webPageTitleRetrieved(String title);

        public void webPageTitleRetrievalException(Exception e);
    }

}

您的客户端代码看起来像这样,您的Activity实现了内部接口:

    .
    .
    .
    connectServerProgressDialog = new ProgressDialog(LoginScreen.this);
    connectServerProgressDialog.setTitle("CheckingServer");
    connectServerProgressDialog.setMessage("Loading...");
    connectServerProgressDialog.setIndeterminate(true);

    connectServerProgressDialog.show();

    new WebPageTitleRemoteTask(this).execute(url);
    .
    .
    .

@Override
public void webPageTitleRetrieved(String title) {

    if (isFinishing()) return;
    connectServerProgressDialog.dismiss();
    Toast.makeText(this, "title = " + title, Toast.LENGTH_SHORT).show();
}

@Override
public void webPageTitleRetrievalException(Exception e) {

    if (isFinishing()) return;
    connectServerProgressDialog.dismiss();
    Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
}

注意:因为侦听器保存在WeakReference中,所以不能为侦听器使用匿名内部类,因为引用几乎会立即消失并且有资格进行垃圾回收。

我一致地使用这个约定,AsyncTask子类中的额外样板代码使得在客户端类中使用它更加清晰。