我有一个小代码,我在doInBackground中读取100个项目的序列化文件,创建一个ArrayList并从doInBackground返回。在PostExecute中,我只是将数组列表复制到另一个与ListView适配器绑定的ArrayList对象。
有了这个,我用10s计时器获得了10-40%的CPU使用率。
我删除了异步任务并且在ui线程中连续执行doInackgrounf和postExecute工作,并且我总是< top命令输出中的5%cpu。
SO是AsyncTask cpu饿了吗?
以下更新是myAsyncTask中的代码
class MyAsyncTask extends AsyncTask<String, String, ArrayList<Info>> {
@Override
protected ArrayList<Info> doInBackground(String... params) {
ArrayList<Info> arr_list = new ArrayList<Info>() {
};
try {
File f = new File(mainApp.getFilesDir(), "");
String[] paths = f.list();
ArrayList<String> delfiles = new ArrayList<String>() {
};
long n = 0;
if (paths == null)
return arr_list;
for (int i = 0; i < paths.length; i++) {
try {
long fname = Long.valueOf(paths[i]);
if (fname > n)
n = fname;
delfiles.add(paths[i]);
} catch (Exception e) {
continue;
}
}
lastFileNum = n;
if (n > 0) {
File fp = new File(mainApp.getFilesDir(), String.valueOf(n));
FileInputStream fos = new FileInputStream(fp);
ObjectInputStream os;
os = new ObjectInputStream(fos);
int count = (Integer) os.readObject();
for (int i = 0; i < count; i++) {
Info ai = (Info) os.readObject();
arr_list.add(ai);
}
os.close();
fos.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return arr_list;
}
@Override
protected void onPostExecute(ArrayList<Info> arr_list) {
try{
if (this.isCancelled()) {
return;
}
if (arr_list != null && arr_list.size() > 0) {
if (this.isCancelled()) {
return;
}
mainApp.Info_data.clear();
for (int i = 0; i < arr_list.size(); i++) {
mainApp.Info_data.add(arr_list.get(i));
}
if (this.isCancelled()) {
return;
}
if (this.isCancelled()) {
return;
}
adapter.notifyDataSetChanged();
}
if (this.isCancelled()) {
return;
}
}
catch(Exception e){
}
}
}
使用matk.executeOnExecutor调用(AsyncTask.THREAD_POOL_EXECUTOR,str);
答案 0 :(得分:0)
好吧,我能想到的几个原因:
答案 1 :(得分:0)
您不应该在UI线程上进行任何形式的长处理。这对用户体验不利,对开发人员来说太糟糕了,你应该总是卸载任何类型的延长处理。
@ m0skit0所说的并不完全正确, “使用AsyncTasks会因为产生不同的线程而获得更多的CPU使用率”
从Android 3.0开始,Asynctasks运行使用.execute()运行UI线程,但是在一个“Asynctask线程”上顺序运行,所以如果你产生10个asynctasks,每个等待一秒,它将需要10秒钟才能完成执行所有,而不是你期望的。您必须明确告诉Android将它们生成为不同的线程,请参阅here了解如何执行此操作。
关于功耗,最佳功率效率,至少在ARM设备上是将CPU内核高速旋转,但是在非常短的时间内,然后将它们降低到低频以便它们可以睡眠。能够将执行压缩到很短的时间框架是您想要尝试并尽量减少功耗的。
- 编辑 -
使用matk.executeOnExecutor执行(AsyncTask.THREAD_POOL_EXECUTOR,str);将为asynctasks创建唯一的线程,以便它们可以并行运行。说实话,这是一个非常难以回答的问题,而不知道调度程序是用来管理内核行为的。我同意在调用android代码时设置asynctasks肯定会产生大量开销。一个更好的选择是直接使用具有更少开销的java线程,或者如果任务非常小,完全摆脱开销并在UI上执行
你必须要记住的是,Asynctask是Android提供的一种实用工具,可以让您作为程序员的生活更轻松。因此,随着CPU利用率的提高,他们选择了可用性和功能而不是效率。就个人而言,我很少使用Asynctasks并手动自我线程,因为这使我可以完全控制应用程序的行为和执行。
总结一下,恕我直言,
UI线程开销最小,但绝不能用于任何超过几微秒的时间,这是由android强制执行的,即如果你尝试在UI上运行网络就会崩溃 线程是最复杂的,您必须手动配置和控制线程生命周期,并且需要诸如Handles之类的东西来执行任何UI更改 Asyctask是谷歌提供的一个易于使用的实用程序,它可以让您的生活更简单,但是,使用提供的功能会带来设置开销的性能成本