2013-04-26 47 views
1

我正在創建一個使用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 

回答

5

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; 
     } 
    }) 
2

只能從主線程做UI相關的事情。嘗試使用主循環器創建一個處理程序並將該可運行程序發佈到該處理程序。

Ex。

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