如何操作从Android的另一个线程主线程UI元素? [英] How can I manipulate main thread UI elements from another thread in Android?

查看:171
本文介绍了如何操作从Android的另一个线程主线程UI元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序结合了一堆主应用程序线程上运行的常规视图对自己的线程运行的SurfaceView。在大多数情况下,这工作正常。然而,当我尝试对SurfaceView的线程触发的改变在主应用程序线程的UI元素的一个东西,我得android.View.ViewRoot $ CalledFromWrongThreadException。

有没有解决这个正确的方式?我应该使用AsyncTask的? Runonuithread()?抑或是混合在自己的线程与主线程只是一个天生的坏事情在其他UI元素的SurfaceView?

如果我的问题没有意义,这里是伪code,可能会更清晰。

  //活动的主应用程序线程中运行
公共类MainActivity延伸活动{
    RelativeLayout的布局;
    TextView中弹出;
    MySurfaceView mysurfaceview;    保护无效的onCreate(捆绑savedInstanceState){
        ...
        的setContentView(布局);
        layout.addView(mysurfaceview); //显示表面观
        popup.setText(你赢了); //创建,但尚未显示
    }
    公共无效showPopup(){
        layout.addView(弹出式);
    }
}//表面观运行在自己的独立线程
公共类MySurfaceView扩展SurfaceView实现SurfaceHolder.Callback,OnTouchListener {
    私人ViewThread mThread;    公共布尔onTouch(视图V,MotionEvent事件){
        ...
        如果(someCondition ==真){
            mainactivity.showPopup();
            //这工作,因为onTouch()是由主应用程序线程调用
        }
    }
    公共无效抽奖(帆布油画){
        ...
        如果(someCondition ==真){
            mainactivity.showPopup();
            //这与崩溃$的ViewRoot CalledFromWrongThreadException
            //因为绘制由mThread称为
            //这是可以解决的?
        }
    }
}


解决方案

  

我应该使用AsyncTask的? Runonuithread()?


无论这些应该罚款。我通常使用的AsyncTask 对于需要做一个后台进程更新 UI 最多的事。但无论哪种应该工作。

AsyncTask的文档

<一个href=\"http://stackoverflow.com/questions/17410734/toast-is-crashing-application-even-inside-thread/17410834#17410834\">runOnUiThread例如和<一个href=\"http://developer.android.com/reference/android/app/Activity.html#runOnUiThread%28java.lang.Runnable%29\"相对=nofollow>文档

My app combines a SurfaceView running on its own thread with a bunch of regular Views running on the main application thread. For the most part, this works fine. However, when I try to have something on the SurfaceView's thread trigger a change to one of the UI elements in the main application thread, I get android.View.ViewRoot$CalledFromWrongThreadException.

Is there a right way around this? Should I use an asynctask? Runonuithread()? Or is mixing a SurfaceView on its own thread with other UI elements on the main thread just an inherently bad thing to do?

If my question doesn't make sense, here's pseudocode that may be clearer.

// Activity runs on main application thread
public class MainActivity extends Activity {
    RelativeLayout layout;
    TextView popup;
    MySurfaceView mysurfaceview;

    protected void onCreate(Bundle savedInstanceState) {
        ...
        setContentView(layout);
        layout.addView(mysurfaceview);  // Surface View is displayed
        popup.setText("You won");       // created but not displayed yet
    }
    public void showPopup() {
        layout.addView(popup);
    }
}

// Surface View runs on its own separate thread
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback, OnTouchListener {
    private ViewThread mThread;

    public boolean onTouch(View v, MotionEvent event) { 
        ...
        if (someCondition == true) {
            mainactivity.showPopup();
            // This works because onTouch() is called by main app thread
        }
    }
    public void Draw(Canvas canvas) { 
        ...
        if (someCondition == true) {
            mainactivity.showPopup();
            // This crashes with ViewRoot$CalledFromWrongThreadException
            // because Draw is called by mThread
            // Is this fixable?
        }
    }
}

解决方案

Should I use an asynctask? Runonuithread()?

Either of these should be fine. I typically use AsyncTask for most things that need to update the UI after doing a background process. But either should work.

AsyncTask Docs

runOnUiThread example and Docs

这篇关于如何操作从Android的另一个线程主线程UI元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆