• 解决如何让AsyncTask终止操作


    受到这个的启发终于结局了如何在AsyncTask运行中终止其操作。

    单纯的onCancelled(true)是不行的

    下面把代码贴出来~实现了登陆功能。

    AsyncTask简介,它使创建需要与用户界面交互的长时间运行的任务变得更简单。相对来说AsyncTask更轻量级一些,适用于简单的异步处理,不需要借助线程和Handler即可实现。

    转自stackoverflow

    package com.isummation.exampleapp;
     
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.net.URLEncoder;
    import java.net.UnknownHostException;
     
    import org.apache.http.HttpResponse;
    import org.apache.http.client.HttpClient;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.params.CoreProtocolPNames;
    import org.apache.http.protocol.BasicHttpContext;
    import org.apache.http.protocol.HttpContext;
    import org.json.JSONObject;
     
    import android.app.Activity;
    import android.app.Dialog;
    import android.app.ProgressDialog;
    import android.content.DialogInterface;
    import android.content.DialogInterface.OnCancelListener;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.view.View;
    import android.view.View.OnClickListener;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.Toast;
     
    public class UserLogin extends Activity {
     
        private EditText etUsername;
        private EditText etPassword;
        private ProgressDialog progressDialog;
        private static final int PROGRESSDIALOG_ID = 0;
        private static final int SERVER_ERROR = 1;
        private static final int NETWORK_ERROR = 2;
        private static final int CANCELLED = 3;
        private static final int SUCCESS = 4;
        private String ServerResponse;
        private LoginTask loginTask;
     
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.login);
     
            etUsername = (EditText) findViewById(R.id.txt_username);
            etPassword = (EditText) findViewById(R.id.txt_password);
     
            Button login_button = (Button) this.findViewById(R.id.login_button);
            login_button.setOnClickListener(new OnClickListener() {
                public void onClick(View viewParam) {
                    if (etUsername.getText().toString().length() == 0
                            || etPassword.getText().toString().length() == 0) {
                        Toast.makeText(getApplicationContext(),
                                "Please enter username and password",
                                Toast.LENGTH_SHORT).show();
                    } else {
     
                        //Show dialog by passing id
                        showDialog(PROGRESSDIALOG_ID);
                    }
                }
            });
        }
     
        protected Dialog onCreateDialog(int id) {
            switch(id) {
            case PROGRESSDIALOG_ID:
                removeDialog(PROGRESSDIALOG_ID);
     
                //Please note that forth parameter is true for cancelable Dialog
                //Also register cancel event listener
                //if the litener is registered then forth parameter has no effect
                progressDialog = ProgressDialog.show(UserLogin.this, "Authenticating",
                        "Please wait...", true, true, new OnCancelListener(){
     
                            public void onCancel(DialogInterface dialog) {
                                //Check the status, status can be RUNNING, FINISHED and PENDING
                                //It can be only cancelled if it is not in FINISHED state
                                if (loginTask != null && loginTask.getStatus() != AsyncTask.Status.FINISHED)
                                    loginTask.cancel(true);
                            }
                        });
                break;
            default:
                progressDialog = null;
            }
            return progressDialog;
        }
     
        @Override
        protected void onPrepareDialog(int id, Dialog dialog) {
            switch (id) {
            case PROGRESSDIALOG_ID:
                //check if any previous task is running, if so then cancel it
                //it can be cancelled if it is not in FINISHED state
                if (loginTask != null && loginTask.getStatus() != AsyncTask.Status.FINISHED)
                    loginTask.cancel(true);
                loginTask = new LoginTask(); //every time create new object, as AsynTask will only be executed one time.
                loginTask.execute();
            }
        }
     
        class LoginTask extends AsyncTask<Void, Integer, Void> {
            @Override
            protected Void doInBackground(Void... unused) {
                try {
                    ServerResponse = null; //don't forget to make it null, as task can be called again
                    HttpClient httpClient = new DefaultHttpClient();
                    HttpContext localContext = new BasicHttpContext();
                    HttpGet httpGet = new HttpGet(
                            getString(R.string.WebServiceURL)
                                    + "/cfc/iphonewebservice.cfc?returnformat=json&method=validateUserLogin&username="
                                    + URLEncoder.encode(etUsername.getText()
                                            .toString(), "UTF-8")
                                    + "&password="
                                    + URLEncoder.encode(etPassword.getText()
                                            .toString(), "UTF-8"));
                    httpClient.getParams().setParameter(
                            CoreProtocolPNames.USER_AGENT,"Some user agent string");
     
                    //call it just before you make server call
                    //calling after this statement and canceling task will no meaning if you do some update database kind of operation
                    //so be wise to choose correct place to put this condition
                    //you can also put this condition in for loop, if you are doing iterative task
     
                    //now this very important
                    //if you do not put this condition and not maintaining execution, then there is no meaning of calling .cancel() method
                    //you should only check this condition in doInBackground() method, otherwise there is no logical meaning
                    if (isCancelled())
                    {
                        publishProgress(CANCELLED); //Notify your activity that you had canceled the task
                        return (null); // don't forget to terminate this method
                    }
                    HttpResponse response = httpClient.execute(httpGet,
                            localContext);
     
                    BufferedReader reader = new BufferedReader(
                            new InputStreamReader(
                                    response.getEntity().getContent(), "UTF-8"));
                    ServerResponse = reader.readLine();
                    publishProgress(SUCCESS); //if everything is Okay then publish this message, you may also use onPostExecute() method
                } catch (UnknownHostException e) {
                    removeDialog(PROGRESSDIALOG_ID);
                    e.printStackTrace();
                    publishProgress(NETWORK_ERROR);
                } catch (Exception e) {
                    removeDialog(PROGRESSDIALOG_ID);
                    e.printStackTrace();
                    publishProgress(SERVER_ERROR);
                }
                return (null);
            }
     
            @Override
            protected void onProgressUpdate(Integer... errorCode) {
                switch (errorCode[0]) {
                case CANCELLED:
                    removeDialog(PROGRESSDIALOG_ID);
                    Toast.makeText(getApplicationContext(), "Cancelled by user",
                            Toast.LENGTH_LONG).show();
                    break;
                case NETWORK_ERROR:
                    removeDialog(PROGRESSDIALOG_ID);
                    Toast.makeText(getApplicationContext(), "Network connection error",
                            Toast.LENGTH_LONG).show();
                    break;
                case SERVER_ERROR:
                    removeDialog(PROGRESSDIALOG_ID);
                    Toast.makeText(getApplicationContext(), "Server error",
                            Toast.LENGTH_LONG).show();
                    break;
                case SUCCESS:
                    removeDialog(PROGRESSDIALOG_ID);
                    try {
                        if (ServerResponse != null) {
                            JSONObject JResponse = new JSONObject(ServerResponse);
                            String sMessage = JResponse.getString("MESSAGE");
                            int success = JResponse.getInt("SUCCESS");
                            if (success == 1) {
                                //proceed further
     
                                //you may start new activity from here
                                //after that you may want to finish this activity
                                UserLogin.this.finish();
     
                                //Remember when you finish an activity, it doesn't mean that you also finish thread or AsynTask started within that activity
                                //So you must implement onDestroy() method and terminate those threads.
                            } else {
                                //just showing invalid username password from server response
                                Toast.makeText(getApplicationContext(), sMessage,
                                        Toast.LENGTH_SHORT).show();
                            }
                        }
                    } catch (Exception e){
                        Toast.makeText(getApplicationContext(), "Server error",
                                Toast.LENGTH_LONG).show();
                        e.printStackTrace();
                    }
                    break;
                }
            }
     
            @Override
            protected void onPostExecute(Void unused) {
     
            }
        }
     
        @Override
        protected void onDestroy(){
            //you may call the cancel() method but if it is not handled in doInBackground() method
            if (loginTask != null && loginTask.getStatus() != AsyncTask.Status.FINISHED)
                loginTask.cancel(true);
            super.onDestroy();
        }
    }

    原文出处:http://www.ericyue.info/archive/stop-asynctask#more-1117

  • 相关阅读:
    Azure 媒体服务的 RTMP 支持和实时编码器
    在_Linux_中如何使用_gdb_调试_C_程序
    你刚吃的兰州牛肉面,背后就藏着大数据
    《C++覆辙录》——1.9:使用糟糕的语言
    老司机带你用MaxCompute和表格存储玩转车联网数据
    快速部署rabbitMQ教程
    《第一本Docker书(修订版)》——1.3 能用Docker做什么
    《第一本Docker书(修订版)》——第1章_简介_1.1Docker简介
    【DockerCon2017最新技术解读】Docker最新特性介绍
    【DockerCon2017最新技术解读】如何在阿里云一键部署高可用的Kubernetes集群
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3221647.html
Copyright © 2020-2023  润新知