簡體   English   中英

Android-Sphero-CalledFromWrongThreadException

[英]Android - Sphero - CalledFromWrongThreadException

我正在創建一個使用Sphero機器人球的游戲。 當游戲開始/繼續時,它會檢查配對或連接的球。 如果藍牙處於關閉狀態,或者沒有配對的球,它將隱藏連接窗口。 如果有一個配對但未連接的球,它將轉到此功能。

// 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  

從不是Looper主線程(或“ UI線程”)的線程中調用removeConnectionView方法。 只能從主彎針線程修改視圖。

為了解決這個問題,有時在Looper主線程上實例化一個Handler(例如,創建視圖或Activity時),然后使用Hander#post(Runnable)方法調用您的方法, 或者使用View#post(Runnable)方法放在您的FrameLayout上。

第一種示例:

將其放在Activity的onCreate方法中,該方法始終在Looper主線程中運行。

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相關的操作。 嘗試使用主循環程序創建處理程序,然后將可運行內容發布到該處理程序。

例如

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM