Android - Sphero - CalledFromWrongThreadException

问题描述:

我正在创建一个使用Sphero机器人球的游戏。当游戏启动/恢复时,它会检查配对或连接的球。如果蓝牙关闭,或者没有配对球,它将隐藏连接窗口。如果有球配对,但没有连接,则转到该功能。Android - Sphero - CalledFromWrongThreadException

// If the user clicked a Sphero and it failed to connect, this event will be fired 
@Override 
public void onRobotConnectionFailed(Robot robot) { 
    Log.d("activity", "onRobotConnectionFailed"); 
    removeConnectionView(); 
} 

它以下面的方法崩溃。

private void removeConnectionView() { 
    mFrameLayout.removeView(mSpheroConnectionView); 
    mSpheroConnectionView = null; 
} 

此功能对彼此可能的结果起作用。 这是错误。

Thread [<14> Thread-2606] (Suspended (exception ViewRootImpl$CalledFromWrongThreadException)) 
<VM does not provide monitor information> 
ViewRootImpl.checkThread() line: 5031 
ViewRootImpl.invalidateChildInParent(int[], Rect) line: 998 
FrameLayout(ViewGroup).invalidateChild(View, Rect) line: 4358 
ImageView(View).invalidate(boolean) line: 10565 
ImageView(View).invalidate() line: 10520  
ImageView.invalidateDrawable(Drawable) line: 202  
XDrawable(Drawable).invalidateSelf() line: 382 
XDrawable(Drawable).setVisible(boolean, boolean) line: 578 
ImageView.onDetachedFromWindow() line: 1196 
ImageView(View).dispatchDetachedFromWindow() line: 12136  
FrameLayout(ViewGroup).dispatchDetachedFromWindow() line: 2824 
RelativeLayout(ViewGroup).dispatchDetachedFromWindow() line: 2824 
SpheroConnectionView$SpheroItemView(ViewGroup).dispatchDetachedFromWindow() line: 2824 
SpheroConnectionView$SpheroListView(ViewGroup).dispatchDetachedFromWindow() line: 2824 
SpheroConnectionView(ViewGroup).dispatchDetachedFromWindow() line: 2824 
FrameLayout(ViewGroup).removeViewInternal(int, View) line: 3943 
FrameLayout(ViewGroup).removeViewInternal(View) line: 3918 
FrameLayout(ViewGroup).removeView(View) line: 3850 
discgroove.removeConnectionView() line: 233 
discgroove.access$4(discgroove) line: 232 
discgroove$2.onRobotConnectionFailed(Robot) line: 191 
SpheroConnectionView$4.onRobotConnectionFailed(Robot) line: 157 
RobotProvider.update(Observable, Object) line: 570 
Robot(Observable).notifyObservers(Object) line: 138 
Robot.setConnected(boolean) line: 300 
DeviceConnection$4.run() line: 378 

removeConnectionView方法是从不是主Looper线程(或“UI线程”)的线程调用的。查看可以只有从主循环线程被修改。

为了解决这个问题,在主弯针线上的某个实例化一个处理程序(创建视图或活动时,例如),并使用Hander#post(Runnable)方法打电话给你的方法,上使用View#post(Runnable)方法您的FrameLayout里。第一种

实施例:

在活动,它总是在主弯针线运行的onCreate方法将这个。

mHandler = new Handler(); 

然后,当你想运行的方法:

handler.post(new Runnable() { 
     @Override 
     public void run() { 

      mFrameLayout.removeView(mSpheroConnectionView); 
      mSpheroConnectionView = null; 
     } 
    }); 

第二类的例子:

mFrameLayout.post(new Runnable() { 
     @Override 
     public void run() { 
      mFrameLayout.removeView(mSpheroConnectionView); 
      mSpheroConnectionView = null; 
     } 
    }) 

只能从主线程做UI相关的事情。尝试使用主循环器创建一个处理程序并将该可运行程序发布到该处理程序。

Ex。

private Handler mHandler = new Handler(Looper.getMainLooper()); 
. 
. 
. 
mHandler.post(new Runnable() { 
     public void run() { 
      removeConnectionView(); 
     } 
    });