AsyncTask是一个很大的cpu饥饿功能

时间:2013-08-06 10:54:23

标签: android

我有一个小代码,我在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);

2 个答案:

答案 0 :(得分:0)

好吧,我能想到的几个原因:

  • 使用AsyncTasks会增加CPU使用率,因为您正在生成不同的线程,这些线程本身需要初始化及其JVM CPU时间(请记住Java线程由JVM管理)。
  • 您可以在更短的时间内完成相同的工作(所有任务)(通过线程化您实际上同时执行所有任务),因此显然CPU使用率必须更高(能量不会被创造也不会被破坏,只能被转化)。

答案 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是谷歌提供的一个易于使用的实用程序,它可以让您的生活更简单,但是,使用提供的功能会带来设置开销的性能成本