异步任务;调用方法 onPreExecute() 后未调用 doInbackground()
Posted
技术标签:
【中文标题】异步任务;调用方法 onPreExecute() 后未调用 doInbackground()【英文标题】:AsyncTask ; doInbackground() not called after calling method onPreExecute() 【发布时间】:2015-01-09 12:29:20 【问题描述】:我确实在我的项目中添加了异步库并且已经检查过了,我不知道为什么代码流没有进入异步任务
代码
public void domysql()
Log.v("doMysql", "accessed");
new AsyncTask<Void, Void, String>()
@Override
protected void onPreExecute()
super.onPreExecute();
Log.e("AsyncTask", "onPreExecute");
@Override
protected String doInBackground(Void... params)
Log.v("AsyncTask", "doInBackground");
String msg = "";
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://172.16.100.172:52273/mysql");
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("myday", Integer.toString(day_picker.getYear()) +
addZero(day_picker.getMonth() + 1) +
addZero(day_picker.getDayOfMonth())));
nameValuePairs.add(new BasicNameValuePair("mystar", changeStar(day_picker.getMonth() + 1, day_picker.getDayOfMonth())));
nameValuePairs.add(new BasicNameValuePair("mybt", changeBloodType(blood_picker.getValue())));
nameValuePairs.add(new BasicNameValuePair("mynum", "" + myPhone.getText()));
nameValuePairs.add(new BasicNameValuePair("yournum", "" + partnerPhone.getText()));
nameValuePairs.add(new BasicNameValuePair("myregID", regid));
try
Log.v("setEntity", "before");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
Log.v("setEntity", "after");
catch (UnsupportedEncodingException e1)
Log.v("UnsupportedEncodingException", "");
e1.printStackTrace();
//172.16.101.28
try
Log.v("post", "before");
HttpResponse httpresponse = httpclient.execute(httppost);
Log.v("post", "after");
Log.v("HttpResponse ",httpresponse.getEntity().toString());
catch (ClientProtocolException e)
Log.v("ClientProtocolException", "ClientProtocolException");
e.printStackTrace();
catch (IOException e)
Log.v("IOException", "IOException");
e.printStackTrace();
return msg;
@Override
protected void onPostExecute(String msg)
Log.v("AsyncTask", "onPostExecute");
.execute(null, null, null);
我在代码'Log.v("AsyncTask", "doInBackground");'中有一个日志语句
但它没有显示在记录器中'Log.v("AsyncTask", "doInBackground");'
【问题讨论】:
尝试 .execute() 而不是 .execute(null, null, null); 结果是一样的...为什么你认为这是一个解决方案?在本地,它与 '.execute(null,null,null)' 配合得很好 可能另一个异步任务仍在执行 @brightstar 在我的日志 cat 中,'AsyncTask : doInBackground' 被标记... @LKM 好吧,如果你的 logcat 中有“doInBackground”,那么你的 asynctask 执行得很好 【参考方案1】:你应该用executor来执行你的任务
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
因为在较低版本的 android 中,所有 AsyncTask 都在单个后台线程中执行。因此,新任务可能正在等待,直到其他任务工作为止。
在 Android 的较低版本中(实际上是在 HONEYCOMB 之前),您无法在 executor 上执行 AsyncTask。
将您的代码更改为
public void executeAsyncTask()
AsyncTask<Void, Void, String> task = new AsyncTask<Void, Void, String>()
@Override
protected void onPreExecute()
super.onPreExecute();
Log.e("AsyncTask", "onPreExecute");
@Override
protected String doInBackground(Void... params)
Log.v("AsyncTask", "doInBackground");
String msg = null;
// some calculation logic of msg variable
return msg;
@Override
protected void onPostExecute(String msg)
Log.v("AsyncTask", "onPostExecute");
;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB/*HONEYCOMB = 11*/)
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
else
task.execute();
【讨论】:
【参考方案2】:这样做不适合你吗?
task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
我已经这样做了,但问题仍然存在,问题是我使用 AsyncTask
运行长期后台任务,因此ThreadPoolExecutor
的工作线程已经被占用。
在我的情况下,AsyncTask.THREAD_POOL_EXECUTOR
(使用调试器获取您的执行程序属性)具有 ff 属性:
maximumPoolSize = 3
largetsPoolSize = 2
corePoolSize =2
因此,禁用其中一个长时间运行的 asyncTask 会使我的 doInBackground 代码运行,但这不是正确的解决方案。
正确的解决方案是我将长时间运行的任务转移到自定义线程中,而不是使用 AsyncTask
。
【讨论】:
或者你可以定义你自己的自定义执行器——这并不难,只需看看它是如何在 AsyncTask 中完成的,并在池中使用更多线程【参考方案3】:我也遇到过这种情况。
-
我打了个电话
AsyncTask.cancel(boolean mayInterruptIfRunning)
通过了
然后我假设(我错了)这个任务的doInBackground()
现在被中断了
通过添加日志语句,我意识到第一个 asyncTask
仍在运行......因此阻止了另一个 asyncTask
执行。 doInBackground()
方法正在运行一个无限循环,所以我只需要更改条件以考虑所有可能的“中断”情况......
【讨论】:
【参考方案4】:引用Async Task的Android文档
在首次引入时,AsyncTask 是在单个 后台线程。从 DONUT 开始,这变成了一个池 允许多个任务并行运行的线程。从...开始 HONEYCOMB,任务在单线程上执行,避免常见 并行执行导致的应用程序错误。
如果你真的想要并行执行,你可以调用 executeOnExecutor(java.util.concurrent.Executor, Object[]) 与 THREAD_POOL_EXECUTOR。
使用这个 sn-p 来触发 AsyncTask:
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB)
asyncTaskInstance.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params);
else
pdfPageChanger.execute(params);
【讨论】:
以上是关于异步任务;调用方法 onPreExecute() 后未调用 doInbackground()的主要内容,如果未能解决你的问题,请参考以下文章
从片段调用 Android AsyncTask 没有调用其成员 - doInbackground、onpreexecute、onpostexecute
在 onPreExecute() 内部调用时 TextView.setText() 的 NullPointerException