我试图在一段时间后取消异步任务。我已经搜索过并发现了很多关于此问题的问题,所有问题都与我在下面所做的相同。
问题:在调用cancel之后,webservice似乎没有取消,因为它永远不会到达onPostExecute。 请任何帮助将不胜感激。
我的尝试:
经过一段时间后我打电话
类TimeOut,它将asyncTask作为其参数并执行以下操作:
if (task.getStatus() == AsyncTask.Status.RUNNING )
{task.cancel(true);}
if(task.isCancelled()==true)
{
Log.e(TAG,"TASK IS CANCELLED");
}
和我的异步类
@Override
protected void onCancelled() {
webServiceError=true; //when timeout change it to true.(default false)
Toast.makeText(context, R.string.webserviceDownloadUserDataError, Toast.LENGTH_LONG).show();
if (pd.isShowing()) {
pd.dismiss();
}
super.onCancelled();
}
@Override
protected String doInBackground(String... params) {
int paramsTracker = 0;
webServiceError = false;
while(webServiceError==false) {
HttpClient httpclient = new DefaultHttpClient();
String url = params[paramsTracker];
paramsTracker = paramsTracker + 1;
HttpPost httppost = new HttpPost(url);
int paramsCount = params.length;
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(paramsCount);
for (int i = 0; i < (paramsCount - 1) / 2; i++) {
Log.d(TAG, "parameters: " + params[paramsTracker] + " - " + params[paramsTracker + 1]);
nameValuePairs.add(new BasicNameValuePair(params[paramsTracker], params[paramsTracker + 1]));
paramsTracker = paramsTracker + 2;
}
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// execute http post request, call web service
response = httpclient.execute(httppost);
}
catch (Exception e) {
webServiceError = true;
Log.e(TAG, e.toString());
try {
AppLogging(TAG, "Error in calling web service " + e.toString(), LogFileName.ErrorLogFilename);
} catch (Exception a) {
}
}
if (webServiceError == false) {
int CNT = 0;
try {
String query = "SELECT COUNT(*) AS CNT FROM TASKS";
Cursor cursor = MainActivity.myDataBase.rawQuery(query, null);
if (cursor.moveToFirst()) {
do {
CNT = Integer.parseInt(cursor.getString(cursor.getColumnIndex("CNT")));
} while (cursor.moveToNext());
cursor.close();
}
} catch (Exception e) {
Log.e(TAG, e.toString());
try {
AppLogging(TAG, "Error in Database error getting task count " + e.toString(), LogFileName.ErrorLogFilename);
} catch (Exception a) {
}
}
if (CNT == 0) {
String webServiceResponse = "";
try {
Log.d(TAG, "Getting web service response");
// get web service response
HttpEntity entity = response.getEntity();
String content;
content = EntityUtils.toString(entity);
// Log.d(TAG, "content: "+ content);
// parse XML response
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(content));
Document doc = db.parse(is);
NodeList nodes = doc.getElementsByTagName("string");
Element line = (Element) nodes.item(0);
webServiceResponse = getCharacterDataFromElement(line);
String patternForON = "SET IDENTITY_INSERT \\[.*?\\] O?((N)|(FF))\\s*?;";
Pattern rForON = Pattern.compile(patternForON);
Matcher mForON = rForON.matcher(webServiceResponse);
String webServiceResponseWithOutIdentityInsert = mForON.replaceAll("");
String patternForInsert = "\\bINSERT (?!INTO)";
Pattern rForInsert = Pattern.compile(patternForInsert);
Matcher mForInsert = rForInsert.matcher(webServiceResponseWithOutIdentityInsert);
String webServiceResponseWITHOUTINSERTALONE = mForInsert.replaceAll("INSERT INTO ");
String webServiceResponsePURIFIED = webServiceResponseWITHOUTINSERTALONE.replaceAll(";;", ";");
Log.d(TAG, "content: " + webServiceResponsePURIFIED);
///////////END OF for removing queries that are not applicable in SQLITE
//FOR SPLITTING THE QUERIES AND PLACING EACH AT AN INDEX IN contentArray ARRAY
//String contentArray [] = webServiceResponse.split(";");
String contentArray[] = webServiceResponsePURIFIED.split(";");
Log.d(TAG, "contentArray length" + contentArray.length + ""); //GETS THE NUMBER OF QUERIES
pd.setMax(contentArray.length); //SETTING THE PROGRESS DIALOG (MAX PROGRESS)
for (int i = 0; i < contentArray.length; i++) {
// add the downloaded data to the local database
String query = contentArray[i];
try {
AppLogging(TAG, "Queries Downloaded splitted and purified\n query " + i + " :" + contentArray[i], LogFileName.LogFilename);
} catch (Exception l) {
}
Log.d(TAG, "query: " + query);
// if query contains "getdate()" replace with DATETIME('now'), to render the query executable in sqlite
query = query.replace("GETDATE()", "DATETIME('now')");
try {
MainActivity.myDataBase.execSQL(query); //EXECUTE QUERY
} catch (Exception e) {
Log.e(TAG, e.toString());
try {
AppLogging(TAG, "Error in performing query: " + query + "\nError: " + e, LogFileName.ErrorLogFilename);
} catch (Exception a) {
}
}
//Log.d("Initialize database, HTTPRequestGetUserData ", query);
publishProgress();
}
} catch (Exception e) {
webServiceError = true;
Log.e(TAG, e.toString());
try {
AppLogging(TAG, "Error: " + e.toString(), LogFileName.ErrorLogFilename);
} catch (Exception a) {
}
}
}
}
if (isCancelled()) return "0";
}
return "1";
}
答案 0 :(得分:3)
根据Android AsyncTask文档,在AsyncTask上调用cancel()
后,它将不会调用onPostExecute()
而是调用onCancelled()
。所以需要流动。
现在按照此处的文档,您的代码
@Override
protected String doInBackground(String... params) {
while(webServiceError=false) {
.....//calling webservice
if (isCancelled()) return "0";
}
return "1";
}
现在你的onCancelled()看起来像是String参数
@Override
protected void onCancelled(String object) { // Here object should be 0
webServiceError=true; //when timeout change it to true.(default false)
Toast.makeText(context, R.string.webserviceDownloadUserDataError, Toast.LENGTH_LONG).show();
if (pd.isShowing()) {
pd.dismiss();
}
super.onCancelled();
}
现在使用此方法参数object will be 0
。不要担心方法onPostExecute()
和onCancelled()
将在主UI线程上运行。
现在我建议您创建一个私有方法,您希望从onPostExecute()
和onCancelled()
使用String参数执行该方法。
答案 1 :(得分:0)
取消AsyncTask时,它永远不会触及OnPostExecute过程。 API Doc:
中提到了这一点http://developer.android.com/reference/android/os/AsyncTask.html
可以通过调用cancel(boolean)随时取消任务。调用此方法将导致后续调用isCancelled()返回true。调用此方法后,将在doInBackground(Object [])返回后调用onCancelled(Object)而不是onPostExecute(Object)。为确保尽快取消任务,应始终定期从doInBackground(Object [])检查isCancelled()的返回值(如果可能)(例如在循环内)。