完美的解决如何让AsyncTask终止操作

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

单纯的onCancelled(true)是不行的

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

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

转自stackoverflow

001 package com.isummation.exampleapp;
002   
003 import java.io.BufferedReader;
004 import java.io.InputStreamReader;
005 import java.net.URLEncoder;
006 import java.net.UnknownHostException;
007   
008 import org.apache.http.HttpResponse;
009 import org.apache.http.client.HttpClient;
010 import org.apache.http.client.methods.HttpGet;
011 import org.apache.http.impl.client.DefaultHttpClient;
012 import org.apache.http.params.CoreProtocolPNames;
013 import org.apache.http.protocol.BasicHttpContext;
014 import org.apache.http.protocol.HttpContext;
015 import org.json.JSONObject;
016   
017 import android.app.Activity;
018 import android.app.Dialog;
019 import android.app.ProgressDialog;
020 import android.content.DialogInterface;
021 import android.content.DialogInterface.OnCancelListener;
022 import android.os.AsyncTask;
023 import android.os.Bundle;
024 import android.view.View;
025 import android.view.View.OnClickListener;
026 import android.widget.Button;
027 import android.widget.EditText;
028 import android.widget.Toast;
029   
030 public class UserLogin extends Activity {
031   
032     private EditText etUsername;
033     private EditText etPassword;
034     private ProgressDialog progressDialog;
035     private static final int PROGRESSDIALOG_ID = 0;
036     private static final int SERVER_ERROR = 1;
037     private static final int NETWORK_ERROR = 2;
038     private static final int CANCELLED = 3;
039     private static final int SUCCESS = 4;
040     private String ServerResponse;
041     private LoginTask loginTask;
042   
043     @Override
044     public void onCreate(Bundle savedInstanceState) {
045         super.onCreate(savedInstanceState);
046         setContentView(R.layout.login);
047   
048         etUsername = (EditText) findViewById(R.id.txt_username);
049         etPassword = (EditText) findViewById(R.id.txt_password);
050   
051         Button login_button = (Button) this.findViewById(R.id.login_button);
052         login_button.setOnClickListener(new OnClickListener() {
053             public void onClick(View viewParam) {
054                 if (etUsername.getText().toString().length() == 0
055                         || etPassword.getText().toString().length() == 0) {
056                     Toast.makeText(getApplicationContext(),
057                             "Please enter username and password",
058                             Toast.LENGTH_SHORT).show();
059                 else {
060   
061                     //Show dialog by passing id
062                     showDialog(PROGRESSDIALOG_ID);
063                 }
064             }
065         });
066     }
067   
068     protected Dialog onCreateDialog(int id) {
069         switch(id) {
070         case PROGRESSDIALOG_ID:
071             removeDialog(PROGRESSDIALOG_ID);
072   
073             //Please note that forth parameter is true for cancelable Dialog
074             //Also register cancel event listener
075             //if the litener is registered then forth parameter has no effect
076             progressDialog = ProgressDialog.show(UserLogin.this,"Authenticating",
077                     "Please wait..."truetruenew OnCancelListener(){
078   
079                         public void onCancel(DialogInterface dialog) {
080                             //Check the status, status can be RUNNING, FINISHED and PENDING
081                             //It can be only cancelled if it is not in FINISHED state
082                             if (loginTask != null && loginTask.getStatus() != AsyncTask.Status.FINISHED)
083                                 loginTask.cancel(true);
084                         }
085                     });
086             break;
087         default:
088             progressDialog = null;
089         }
090         return progressDialog;
091     }
092   
093     @Override
094     protected void onPrepareDialog(int id, Dialog dialog) {
095         switch (id) {
096         case PROGRESSDIALOG_ID:
097             //check if any previous task is running, if so then cancel it
098             //it can be cancelled if it is not in FINISHED state
099             if (loginTask != null && loginTask.getStatus() != AsyncTask.Status.FINISHED)
100                 loginTask.cancel(true);
101             loginTask = new LoginTask(); //every time create new object, as AsynTask will only be executed one time.
102             loginTask.execute();
103         }
104     }
105   
106     class LoginTask extends AsyncTask<Void, Integer, Void> {
107         @Override
108         protected Void doInBackground(Void... unused) {
109             try {
110                 ServerResponse = null//don't forget to make it null, as task can be called again
111                 HttpClient httpClient = new DefaultHttpClient();
112                 HttpContext localContext = new BasicHttpContext();
113                 HttpGet httpGet = new HttpGet(
114                         getString(R.string.WebServiceURL)
115                                 "/cfc/iphonewebservice.cfc?returnformat=json&method=validateUserLogin&username="
116                                 + URLEncoder.encode(etUsername.getText()
117                                         .toString(), "UTF-8")
118                                 "&password="
119                                 + URLEncoder.encode(etPassword.getText()
120                                         .toString(), "UTF-8"));
121                 httpClient.getParams().setParameter(
122                         CoreProtocolPNames.USER_AGENT,"Some user agent string");
123   
124                 //call it just before you make server call
125                 //calling after this statement and canceling task will no meaning if you do some update database kind of operation
126                 //so be wise to choose correct place to put this condition
127                 //you can also put this condition in for loop, if you are doing iterative task
128   
129                 //now this very important
130                 //if you do not put this condition and not maintaining execution, then there is no meaning of calling .cancel() method
131                 //you should only check this condition in doInBackground() method, otherwise there is no logical meaning
132                 if (isCancelled())
133                 {
134                     publishProgress(CANCELLED); //Notify your activity that you had canceled the task
135                     return (null); // don't forget to terminate this method
136                 }
137                 HttpResponse response = httpClient.execute(httpGet,
138                         localContext);
139   
140                 BufferedReader reader = new BufferedReader(
141                         new InputStreamReader(
142                                 response.getEntity().getContent(), "UTF-8"));
143                 ServerResponse = reader.readLine();
144                 publishProgress(SUCCESS); //if everything is Okay then publish this message, you may also use onPostExecute() method
145             catch (UnknownHostException e) {
146                 removeDialog(PROGRESSDIALOG_ID);
147                 e.printStackTrace();
148                 publishProgress(NETWORK_ERROR);
149             catch (Exception e) {
150                 removeDialog(PROGRESSDIALOG_ID);
151                 e.printStackTrace();
152                 publishProgress(SERVER_ERROR);
153             }
154             return (null);
155         }
156   
157         @Override
158         protected void onProgressUpdate(Integer... errorCode) {
159             switch (errorCode[0]) {
160             case CANCELLED:
161                 removeDialog(PROGRESSDIALOG_ID);
162                 Toast.makeText(getApplicationContext(), "Cancelled by user",
163                         Toast.LENGTH_LONG).show();
164                 break;
165             case NETWORK_ERROR:
166                 removeDialog(PROGRESSDIALOG_ID);
167                 Toast.makeText(getApplicationContext(), "Network connection error",
168                         Toast.LENGTH_LONG).show();
169                 break;
170             case SERVER_ERROR:
171                 removeDialog(PROGRESSDIALOG_ID);
172                 Toast.makeText(getApplicationContext(), "Server error",
173                         Toast.LENGTH_LONG).show();
174                 break;
175             case SUCCESS:
176                 removeDialog(PROGRESSDIALOG_ID);
177                 try {
178                     if (ServerResponse != null) {
179                         JSONObject JResponse = new JSONObject(ServerResponse);
180                         String sMessage = JResponse.getString("MESSAGE");
181                         int success = JResponse.getInt("SUCCESS");
182                         if (success == 1) {
183                             //proceed further
184   
185                             //you may start new activity from here
186                             //after that you may want to finish this activity
187                             UserLogin.this.finish();
188   
189                             //Remember when you finish an activity, it doesn't mean that you also finish thread or AsynTask started within that activity
190                             //So you must implement onDestroy() method and terminate those threads.
191                         else {
192                             //just showing invalid username password from server response
193                             Toast.makeText(getApplicationContext(), sMessage,
194                                     Toast.LENGTH_SHORT).show();
195                         }
196                     }
197                 catch (Exception e){
198                     Toast.makeText(getApplicationContext(), "Server error",
199                             Toast.LENGTH_LONG).show();
200                     e.printStackTrace();
201                 }
202                 break;
203             }
204         }
205   
206         @Override
207         protected void onPostExecute(Void unused) {
208   
209         }
210     }
211   
212     @Override
213     protected void onDestroy(){
214         //you may call the cancel() method but if it is not handled in doInBackground() method
215         if (loginTask != null && loginTask.getStatus() != AsyncTask.Status.FINISHED)
216             loginTask.cancel(true);
217         super.onDestroy();
218     }
219 }

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值