1

我对 Android 还很陌生,还没有得到 Android 线程的想法。

在这里,我有BtConnection通过蓝牙与 Lego NXT 通信的课程。我想webView根据来自 NXT 的消息更改我的。我想在webView收到任何消息后立即更改。像这样

class BtConnection implements Runnable {

    @Override
    public void run() {
        NXTConnector conn = new NXTConnector();
        dos = new DataOutputStream(conn.getOutputStream());
        dis = new DataInputStream(conn.getInputStream());

        while(true){
            int nextPageIndex = dis.readInt();
            webView.loadUrl(indexToUrl(nextPageIndex));
        }
    }
}

接着...

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        webView = (WebView) findViewById(R.id.webView);

    webView.loadUrl("file:///android_asset/html/index.html");

    new Thread(new BtConnection()).start(); 
}

但这是错误的,因为new Thread(new BtConnection())无法触摸 UI。我应该怎么办?

4

2 回答 2

1

Android只有一个用于ui操作的ui调度线程和安全机制(如果不在ui线程中执行操作则抛出异常)。因此,如果要更新 ui,则必须在调度程序线程中进行。您可以使用这个处理程序,也可以使用 easy Activity.runOnUiThread。所以,在你的代码中,只是

class BtConnection implements Runnable {

    @Override
    public void run() {
        NXTConnector conn = new NXTConnector();
        dos = new DataOutputStream(conn.getOutputStream());
        dis = new DataInputStream(conn.getInputStream());

        while(true){
            runOnUiThread(new Runnable(){
              run(){
                 int nextPageIndex = dis.readInt();
                webView.loadUrl(indexToUrl(nextPageIndex));
              });
        }
    }
 }

而且,如果您需要在屏幕上快速更新,那么您可以使用SurfaceView. SurfaceView没有绑定到ui线程。所以,你可以在这个对象中做任何你想做的事情。但是,它是一个简单的绘图对象。因此,您只能在此对象上绘制一些几何形状。

于 2014-11-28T14:48:52.537 回答
0

这里的解决方案是在 UI 线程和其他线程之间使用Handler :

https://developer.android.com/training/multiple-threads/communicate-ui.html

您要做的是在 UI 线程上定义一个处理程序,该处理程序将处理来自其他线程的传入消息。

于 2014-11-28T14:34:32.633 回答