受到这个的启发终于结局了如何在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...", true, true, new
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 {
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
}
这个取消其实不是完美的,当执行到 HttpResponse response =
httpClient.execute(httpGet,localContext);时,是不能取消的,而恰恰是这后面的等待过程需求取消操作
此时只能等待响应超时。