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

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

单纯的onCancelled(true)是不行的

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

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

转自stackoverflow

001 packagecom.isummation.exampleapp;
002
003 importjava.io.BufferedReader;
004 importjava.io.InputStreamReader;
005 importjava.net.URLEncoder;
006 importjava.net.UnknownHostException;
007
008 importorg.apache.http.HttpResponse;
009 importorg.apache.http.client.HttpClient;
010 importorg.apache.http.client.methods.HttpGet;
011 importorg.apache.http.impl.client.DefaultHttpClient;
012 importorg.apache.http.params.CoreProtocolPNames;
013 importorg.apache.http.protocol.BasicHttpContext;
014 importorg.apache.http.protocol.HttpContext;
015 importorg.json.JSONObject;
016
017 importandroid.app.Activity;
018 importandroid.app.Dialog;
019 importandroid.app.ProgressDialog;
020 importandroid.content.DialogInterface;
021 importandroid.content.DialogInterface.OnCancelListener;
022 importandroid.os.AsyncTask;
023 importandroid.os.Bundle;
024 importandroid.view.View;
025 importandroid.view.View.OnClickListener;
026 importandroid.widget.Button;
027 importandroid.widget.EditText;
028 importandroid.widget.Toast;
029
030 publicclassUserLoginextendsActivity {
031
032 privateEditText etUsername;
033 privateEditText etPassword;
034 privateProgressDialog progressDialog;
035 privatestaticfinalintPROGRESSDIALOG_ID =0;
036 privatestaticfinalintSERVER_ERROR =1;
037 privatestaticfinalintNETWORK_ERROR =2;
038 privatestaticfinalintCANCELLED =3;
039 privatestaticfinalintSUCCESS =4;
040 privateString ServerResponse;
041 privateLoginTask loginTask;
042
043 @Override
044 publicvoidonCreate(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(newOnClickListener() {
053 publicvoidonClick(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 protectedDialog onCreateDialog(intid) {
069 switch(id) {
070 casePROGRESSDIALOG_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,newOnCancelListener(){
078
079 publicvoidonCancel(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 returnprogressDialog;
091 }
092
093 @Override
094 protectedvoidonPrepareDialog(intid, Dialog dialog) {
095 switch(id) {
096 casePROGRESSDIALOG_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 =newLoginTask();//every time create new object, as AsynTask will only be executed one time.
102 loginTask.execute();
103 }
104 }
105
106 classLoginTaskextendsAsyncTask<Void, Integer, Void> {
107 @Override
108 protectedVoid doInBackground(Void... unused) {
109 try{
110 ServerResponse =null;//don't forget to make it null, as task can be called again
111 HttpClient httpClient =newDefaultHttpClient();
112 HttpContext localContext =newBasicHttpContext();
113 HttpGet httpGet =newHttpGet(
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 =newBufferedReader(
141 newInputStreamReader(
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 protectedvoidonProgressUpdate(Integer... errorCode) {
159 switch(errorCode[0]) {
160 caseCANCELLED:
161 removeDialog(PROGRESSDIALOG_ID);
162 Toast.makeText(getApplicationContext(),"Cancelled by user",
163 Toast.LENGTH_LONG).show();
164 break;
165 caseNETWORK_ERROR:
166 removeDialog(PROGRESSDIALOG_ID);
167 Toast.makeText(getApplicationContext(),"Network connection error",
168 Toast.LENGTH_LONG).show();
169 break;
170 caseSERVER_ERROR:
171 removeDialog(PROGRESSDIALOG_ID);
172 Toast.makeText(getApplicationContext(),"Server error",
173 Toast.LENGTH_LONG).show();
174 break;
175 caseSUCCESS:
176 removeDialog(PROGRESSDIALOG_ID);
177 try{
178 if(ServerResponse !=null) {
179 JSONObject JResponse =newJSONObject(ServerResponse);
180 String sMessage = JResponse.getString("MESSAGE");
181 intsuccess = 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 protectedvoidonPostExecute(Void unused) {
208
209 }
210 }
211
212 @Override
213 protectedvoidonDestroy(){
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

按默认排序|显示最新评论|回页面顶部共有1个评论发表评论»

  • PengTesun
    PengTesun回答于 2012-02-13 11:38 (2个月前)
    这个取消其实不是完美的,当执行到 HttpResponse response = httpClient.execute(httpGet, localContext);时,是不能取消的,而恰恰是这后面的等待过程需求取消操作
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值