8

我的 Activity inonCreate()执行需要一些时间的长时间计算。

同样onCreate(),我调用setContentView()设置活动的外观。

关键是,由于执行上述计算需要一段时间,因此只有在很长一段时间后才会加载 Activity 的屏幕。

请,关于如何避免这种情况的任何建议?

我试图调用setContentView()onCreate()开始计算onResume(),但活动屏幕仅在最后加载。

4

4 回答 4

21

除了使用例如AsyncTask之外别无他法。原因是实际的渲染不是异步进行的;换句话说, setContentView 只会设置一些数据,但不会在那个时间点显示任何内容。

然而,AsyncTask 并不一定意味着“长”计算。但是,如果您的应用程序依赖于结果,并且没有其他并行计算发生,那么它可能仍然是您实现所需目标的最简单方法。如果没有,您甚至可能不得不使用线程。

更新由于每个人都在用更多不同质量的AsyncTask答案轰炸原始海报,我想再强调一次 AsyncTask 用于操作(引用参考:最多几秒钟),而 OP 有没有说明他的计算真正需要多长时间此外,AsyncTask 是一次性对象,只能运行一次。

需要考虑的另一个非常重要的点如下。Android 为 AsyncTask 分配一个后台任务优先级。这意味着,除了较低的调度优先级外,AsyncTask 中的计算将比在前台执行的时间长十倍,因为 Android 运行所有具有后台优先级的任务,人为限制了 10% 的 CPU 周期。但是,可以通过“稍微”提高其优先级来将 AsyncTasks 从该组中移除。对于 AsyncTask,它会像这样完成:

public R doInBackground(I... is) {
    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND +
                              Process.THREAD_PRIORITY_MORE_FAVORABLE);
    ...
}
于 2013-02-10T14:53:03.293 回答
3

你必须实现 AsyncTask

  public class AsyncTaskActivity extends Activity implements OnClickListener {
    Button btn;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        btn = (Button) findViewById(R.id.button1);.
                    //because we implement OnClickListener we only have to pass "this" (much easier)
        btn.setOnClickListener(this);
    }

    public void onClick(View view){
        //detect the view that was "clicked"
        switch(view.getId())
        {
          case R.id.button1:
              new LongOperation().execute("");
          break;

        }

    }

    private class LongOperation extends AsyncTask<String, Void, String> {

          @Override
          protected String doInBackground(String... params) {
                for(int i=0;i<5;i++) {
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }

                return "Executed";
          }      

          @Override
          protected void onPostExecute(String result) {
                TextView txt = (TextView) findViewById(R.id.output);
                txt.setText("Executed"); // txt.setText(result);
                //might want to change "executed" for the returned string passed into onPostExecute() but that is upto you
          }

          @Override
          protected void onPreExecute() {
          }

          @Override
          protected void onProgressUpdate(Void... values) {
          }
    }
于 2013-02-10T15:14:04.810 回答
2

如果所有计算都需要很长时间才能执行,那么您的 UI 将被“锁定”并且不会更新。

您需要在AsyncTask中完成所有长期工作

AsyncTask 允许正确和轻松地使用 UI 线程。此类允许在 UI 线程上执行后台操作并发布结果,而无需操作线程和/或处理程序。

于 2013-02-10T14:53:05.857 回答
1

在开始初始化视图之前在 onCreate 方法中调用 setContentView(layoutID),创建AsyncTask并在仅在 onCreate 方法中调用 setContentView 之后启动AsyncTask线程。如下所示

  onCreate(....){
    --
    --
    setContentView(layoutID);
    ---
    --
    new asynchTask(); // load your ui in AsyncTask by creating an inner class in your activity by extending AsyncTask class

    }

这是一个如何实现 AsyncTask的教程

于 2013-02-10T14:54:01.473 回答