为什么ui在while循环结束之前不加载?

时间:2015-09-21 06:46:30

标签: android performance android-activity

即使while循环在一个线程中,UI也不会加载到任何条件的while break。我希望UI能够在无限循环运行时加载。 如何处理这种情况?

public class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    /* runOnUiThread th=new runOnUiThread(new TextChange());*/
    new Thread() {
        public void run() {
            try {
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                // change UI elements here
                                TextView tv = (TextView) findViewById(R.id.tv);
                                while (true) {
                                    int y = 10;
                                }
                            }
                        });
                    }
                });
                Thread.sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }
    return super.onOptionsItemSelected(item);
}
}

3 个答案:

答案 0 :(得分:1)

首先, runOnUiThread 没有任何效果,因为 onCreate 方法中的所有代码都是按设计在UI线程上运行的,这意味着你不能将它放在一个单独的 runOnUiThread 块中。其次,你必须使用 AsyncTask 来创建一个新的后台线程,因为它更适合做小背景内容并且还与主UI线程交互。第三,你创造了一个无限循环,这意味着它不会出现。检查出。

答案 1 :(得分:0)

试试这段代码:

new Thread() {
    public void run() {

        try {                                  
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            // change UI elements here
                            TextView tv = (TextView) findViewById(R.id.tv);
                            new Thread(){
                                public void run() {
                                    while (true) {
                                        int y = 10;
                                    }
                                }
                            }.start();
                        }
                    });               
            Thread.sleep(30);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}.start();

答案 2 :(得分:0)

您的代码存在一些问题(正如其他人提到的那样),但这里的主要问题是对UI线程的误解。

如启动流程时“Rendering Performance 101”中所述,Android会为其创建“主”线程。该线程将处理所有输入回调事件,并为您处理渲染操作。渲染系统本身将尝试每16ms左右重新绘制一次屏幕。如果你的主线程(也称为你的“UI线程”)在这些16ms的优势之一发生时有效,那么你将得到我们称之为“丢帧”(见“Why 60fps?”)。

因此,大多数Android开发人员尽其所能在UIThread / MainThread上工作,以便与渲染系统无争用(因此,不会丢帧!)

您的代码正在执行“runOnUIThread”回调,该回调将推送一组工作在UI线程上执行。除非该例程中的工作在<16ms内执行,否则它可能会强制您的应用程序错过一个帧;或者更糟糕的是,在循环结束之前不渲染屏幕。

你真正想做的是使用类似AsyncTaskLoader的东西来移动你的无限循环关闭UI线程。