简体   繁体   English

Android Activity需要很长时间才能显示内容

[英]Android Activity takes too long to show content

My Activity in onCreate() performs long computations that take some time. 我在onCreate() Activity执行需要一些时间的长计算。

In the same onCreate() I call setContentView() to set the appearance of the activity. 在同一个onCreate()我调用setContentView()来设置活动的外观。

The point is that, since it takes a while to performs the above mentioned computations the screen of the Activity loads only after long time. 关键在于,由于执行上述计算需要一段时间,因此活动的屏幕仅在很长时间后加载。

Please, any suggestion on how to avoid this? 请问有关如何避免这种情况的任何建议?

I have tried to call setContentView() in onCreate() and start the computations in onResume() , but again the Activity screen is loaded only at the end. 我试图在onCreate()调用setContentView()并在onResume()启动计算,但同​​样只在最后加载Activity屏幕。

There is no other way than to use eg an AsyncTask . 除了使用例如AsyncTask之外别无他法。 The reason is that the actual rendering does not take place asynchronously; 原因是实际渲染不是异步发生的; in other words, setContentView will only set some data but nothing will be displayed at that point in time. 换句话说,setContentView只会设置一些数据,但在那个时间点什么都不会显示。

AsyncTask, however, is not necessarily meant for "long" computations. 然而,AsyncTask不一定意味着“长”计算。 But if your app relies on the result, and no other computations take place in parallel, it may still be the simplest way for you to achieve what you want. 但是,如果您的应用程序依赖于结果,并且没有其他计算并行发生,那么它可能仍然是您实现所需内容的最简单方法。 If not, you may have to use a Thread even. 如果没有,您可能必须使用线程甚至。

Update Since everybody keeps bombarding the original poster with more use AsyncTask answers of various quality, I'd like to stress one more time that AsyncTask is intended for short operations (to quote the reference: a few seconds at the most ) while the OP has given no indication on how long his computations really take. 更新由于每个人都在更多地使用各种质量的AsyncTask答案来轰炸原始海报,我想再次强调AsyncTask用于操作(引用参考: 最多几秒 )而OP有没有说明他的计算真正需要多长时间。 Also, an AsyncTask is a one-shot-only object which can only run once. 此外,AsyncTask是一个只能运行一次的一次性对象。

One more very important point to consider is the following. 另一个需要考虑的重点是以下几点。 Android assigns AsyncTask a background task priority. Android为AsyncTask分配后台任务优先级。 This means that, besides the lower scheduling priority, the computations in AsyncTask will take ten times as long as if they were performed in the foreground , because Android runs all tasks which have background priority with an artificial limit of 10% CPU cycles. 这意味着,除了较低的调度优先级之外,AsyncTask中计算将花费十倍于在前台执行的计算 ,因为Android运行具有后台优先级且具有10%CPU周期的人为限制的所有任务。 However, AsyncTasks can be lifted out of this group by raising its priority "just a little bit". 但是,AsyncTasks可以通过提高“优先级”来提升其优先级。 For an AsyncTask, it would be done like so: 对于AsyncTask,它将像这样完成:

public R doInBackground(I... is) {
    Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND +
                              Process.THREAD_PRIORITY_MORE_FAVORABLE);
    ...
}

If all computations take long time to execute, your UI is 'locked' and not updated. 如果所有计算都需要很长时间才能执行,那么您的UI将被“锁定”并且不会更新。

You need to do all long work in an AsyncTask 您需要在AsyncTask中完成所有长时间的工作

AsyncTask enables proper and easy use of the UI thread. AsyncTask可以正确,方便地使用UI线程。 This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers. 此类允许执行后台操作并在UI线程上发布结果,而无需操作线程和/或处理程序。

call setContentView(layoutID) in onCreate method before you start initializing views, create a AsyncTask and start AsyncTask thread after you called setContentView in onCreate method only. 在开始初始化视图之前调用onCreate方法中的setContentView(layoutID),在onCreate方法中调用setContentView之后创建AsyncTask并启动AsyncTask线程。 Something like given below 下面给出的东西

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

    }

here is a tutorial of how to implement AsyncTask 这是一个如何实现AsyncTask的教程

You have to implement AsyncTask 你必须实现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) {
          }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM