Java Android实现runOnUiThread

Java Android实现runOnUiThread,java,android,android-activity,graphics,Java,Android,Android Activity,Graphics,我知道有很多类似的问题,但我找不到我问题的答案 我的比赛有问题。当SurfaceView的游戏循环运行时,我无法更改我想要(在)可见的元素的可视性 这是因为只有创建视图层次结构的原始线程才能接触其视图,但我不知道如何修复它 07-28 19:07:20.913: E/AndroidRuntime(15091): FATAL EXCEPTION: Thread-26727 07-28 19:07:20.913: E/AndroidRuntime(15091): android.view.ViewR

我知道有很多类似的问题,但我找不到我问题的答案

我的比赛有问题。当SurfaceView的游戏循环运行时,我无法更改我想要(在)可见的元素的可视性

这是因为只有创建视图层次结构的原始线程才能接触其视图,但我不知道如何修复它

07-28 19:07:20.913: E/AndroidRuntime(15091): FATAL EXCEPTION: Thread-26727
07-28 19:07:20.913: E/AndroidRuntime(15091):
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that
created a view hierarchy can touch its views.
07-28 19:07:20.913: E/AndroidRuntime(15091):    at 
android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4650)
07-28 19:07:20.913: E/AndroidRuntime(15091):    at 
android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:877)
07-28 19:07:20.913: E/AndroidRuntime(15091):    at 
android.view.ViewGroup.invalidateChild(ViewGroup.java:4066)
07-28 19:07:20.913: E/AndroidRuntime(15091):    at 
android.view.View.invalidate(View.java:10275)
07-28 19:07:20.913: E/AndroidRuntime(15091):    at 
android.view.View.setFlags(View.java:8385)
07-28 19:07:20.913: E/AndroidRuntime(15091):    at 
android.view.View.setVisibility(View.java:5531)
07-28 19:07:20.913: E/AndroidRuntime(15091):    at   
android.widget.ImageView.setVisibility(ImageView.java:1155)
07-28 19:07:20.913: E/AndroidRuntime(15091):    at     com.coderogden.pongtennis.activities.SingleGameActivity.setInVisLife3C(SingleGameActivity.j    ava:84)
07-28 19:07:20.913: E/AndroidRuntime(15091):    at 
com.coderogden.pongtennis.views.SingleGameView.outOfBounds(SingleGameView.java:319)
07-28 19:07:20.913: E/AndroidRuntime(15091):    at 
com.coderogden.pongtennis.views.SingleGameView.update(SingleGameView.java:197)
07-28 19:07:20.913: E/AndroidRuntime(15091):    at  
com.coderogden.pongtennis.other.MainThread.run(MainThread.java:57)
以下是代码的重要部分:

Activity类包含大量类似的方法,如下面的方法

public static void setInVisLife3C() {           
        life3C.setVisibility(View.INVISIBLE);
    }
这些方法是从我的SurfaceView类调用的,例如从这里:

public void outOfBounds() {

    // Player's side
    if (ball.getY() + ball.getRadius() > box.getBoxBot()) {
        playerLives--;
        playing = false;
        switch (playerLives) {
        case 4:
            SingleGameActivity.setInVisLife5P();
            break;
        case 3:
            SingleGameActivity.setInVisLife4P();
            break;
        case 2:
            SingleGameActivity.setInVisLife3P();
            break;
        case 1:
            SingleGameActivity.setInVisLife2P();
            break;
        case 0:
            SingleGameActivity.setInVisLife1P();
            playerLoses();
            break;
        }
    }
}
此方法是从另一个名为update()的方法调用的,该方法也位于SurfaceView类中

然后从主线程(游戏循环)调用update()方法:


如果您需要更多代码来帮助我,请告诉我!:)

嗯,你回答了你自己的问题。您必须使用runOnUiThread和Runnable在非UI线程中对视图进行更改。例如:

public static void setInVisLife3C() {           
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            life3C.setVisibility(View.INVISIBLE);
        }
    });
}

您不能从UI线程调用
runOnUiThread
。您需要从单独的线程调用它。试试这个

要编辑@Gintas_uu,请回答:

  public static void setInVisLife3C() {
        new Thread(new Runnable() {
            public void run() {
                runOnUiThread(new Runnable() {
                    public void run() {
                        life3C.setVisibility(View.INVISIBLE);
                    }
                });
            }
        }).start;

谢谢但问题是:“无法从类型活动中对非静态方法runOnUiThread(Runnable)进行静态引用”。并且该方法必须是静态的,才能从另一个类访问。对吗(我从我的SurfaceView类访问它)?@CoderOgden如果理解正确,您的SurfaceView类应该有一个上下文引用,您可以强制转换到某个活动。或者你可以把一个句柄传递到一个自定义的Survivew中,你把它包装回活动中。抱歉,但是我想你在第一句话中失去了我,我是Android编程的新手…@ CoderOgden,也叫这样的活动方法是不好的练习,你应该考虑使用活动参考来称呼他们。好的,谢谢!这样做对吗?[(卢克·泰勒的回答)这与我对金塔斯的评论不一样,我很抱歉。
  public static void setInVisLife3C() {
        new Thread(new Runnable() {
            public void run() {
                runOnUiThread(new Runnable() {
                    public void run() {
                        life3C.setVisibility(View.INVISIBLE);
                    }
                });
            }
        }).start;