我正在使用asynctask进行蓝牙套接字通信。它在galaxy s ii(android 2.3.3)上工作正常,但有时不适用于galaxy s iii(android 4.0.4)。
class MyTask extends AsyncTask<Void, long[], Void> {
long[] d = new long[40];
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.e("BTtest", "MyTask preexecute");
}
@Override
protected Void doInBackground(Void... v) {
int count = 0;
Log.e("BTtest", "Mytask background start " );
*******creting socket and streams*******
*********logic*******
publishProgress(d);
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
**logic**
}
@Override
protected void onProgressUpdate(long[]... data) {
super.onProgressUpdate(data);
*******logic***
}
}
来自onCreate按钮功能:
mt = new MyTask();
mt.execute( );
有时在galaxy s iii上调用onPreExecute方法并且doInBackground方法未启动。 但其他时候称为背景方法。它看起来像是随机的。
有什么想法吗?
wildhemp建议只在一个线程中执行asynctasks。我在一个活动中编写了测试应用程序这3个asynctasks:
public class MainActivity extends Activity {
MyTask mt1, mt2, mt3;
TextView tvInfo;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tvInfo = (TextView) findViewById(R.id.tvInfo);
}
public void onclick(View v) {
mt1 = new MyTask();
mt1.execute("file_path_1", "file_path_2", "file_path_3", "file_path_4");
mt2 = new MyTask();
mt2.execute("file_path_1", "file_path_2", "file_path_3", "file_path_4");
mt3 = new MyTask();
mt3.execute("file_path_1", "file_path_2", "file_path_3", "file_path_4");
}
class MyTask extends AsyncTask<String, Integer, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
tvInfo.append("Begin \n");
}
@Override
protected Void doInBackground(String... urls) {
try {
int cnt = 0;
for (String url : urls) {
downloadFile(url);
publishProgress(++cnt);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
tvInfo.append("Downloaded " + values[0] + " files \n");
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
tvInfo.append("End\n");
}
private void downloadFile(String url) throws InterruptedException {
int i=0;
while (i<100000000){
i+=1;
}
}
}
}
它在sgs2,sgs3和模拟器上工作正常。应用程序在sgs3上加载75%(4个核心上的3个线程)的cpu。 sgs2加载100%(2个核心上的3个线程)。 这意味着每个asynctask在separeted线程中执行的是什么。
问题解决了。谢谢。 我已经更改了项目目标构建版本。 现在执行代码:
mt = new MyTask();
if (Build.VERSION.SDK_INT >= 11){
mt.executeOnExecutor( AsyncTask.THREAD_POOL_EXECUTOR); //work on sgs3 android 4.0.4
}
else {
mt.execute(); // work on sgs2 android 2.3
}
答案 0 :(得分:0)
可能会发生因为4.0.4上的doInBackground默认使用1个线程来运行所有异步任务,所以如果另一个doInBackground仍在工作,它将阻止执行,我认为在这种情况下将调用onPreExecute,因为它在主线程上运行。在2.3.3中,asynctask使用更多线程(AFAIK是每个任务的新线程)。
更新: 以下是android documentation所说的内容:
首次引入时,AsyncTasks在单个后台线程上串行执行。从DONUT开始,这被改为一个线程池,允许多个任务并行运行。从HONEYCOMB开始,任务在单个线程上执行,以避免由并行执行引起的常见应用程序错误。
如果您真的想要并行执行,可以使用THREAD_POOL_EXECUTOR调用executeOnExecutor(java.util.concurrent.Executor,Object [])。