受到这个的启发终于结局了如何在AsyncTask运行中终止其操作。
单纯的onCancelled(true)是不行的
下面把代码贴出来~实现了登陆功能。
AsyncTask简介,它使创建需要与用户界面交互的长时间运行的任务变得更简单。相对来说AsyncTask更轻量级一些,适用于简单的异步处理,不需要借助线程和Handler即可实现。
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<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