簡體   English   中英

在Android中的單獨線程上使用彎針

[英]Using a looper on a separate thread in Android

背景:

我正在嘗試通過handler.postDelayed逐漸移動標記,直到它從一個停靠點到達下一個停靠點,來顯示總線的運動。

我希望它在一定時間后重復到下一個停止,所以我嘗試在單獨的線程上使用循環程序,因為這對於主UI線程來說工作量太大。

問題:

因為我正在更新標記的位置,所以我需要每秒鍾設置一個新位置,但是在運行代碼時,我遇到錯誤,指出它不在主UI線程上(請參閱本文的底部) 。

錯誤指向存儲busMarker的變量,我認為只能由創建它的線程來修改。

我已經嘗試過runOnUiThread()但是我仍然會遇到其他錯誤,例如空值,這不應該是因為我為它們分配了值,而只是在主線程中。

我假設有一種比必須不斷返回到主線程更干凈的方法,那么我該如何實現呢?

創建線程

private class ThreadClass extends Thread {

    @Override
    public void run() {

        Looper.prepare();

        moveBusMarker();

        if (passedStops.size() != stops.size()) {

            Looper.loop();
        }
        else {

            Looper.myLooper().quit();
        }
    }
}

運行線程

    if (passedStops.size() != 0 && passedStops.size() != stops.size()) {
        thread.start();
    }

執行運動

// set up a timer
final long limit = TimeUnit.SECONDS.toMillis(seconds) - 1000;
final long startTime = System.currentTimeMillis();

final Stop NextStop = nextStop;

final Handler handler1 = new Handler();

Runnable runnable = new Runnable() {

    @Override
    public void run() {

        Log.d("", "The bus is currently at " + busPosition.toString());

        // get the current bus' position
        double lat = busPosition.latitude;
        double lon = busPosition.longitude;

        // add the difference to the bus position to move it closer
        lat = lat + latDifference;
        lon = lon + lonDifference;
        busPosition = new LatLng(lat, lon);

        Log.d("", "The bus has moved to " + busPosition.toString());

        // set the new position to the marker representing the bus movement
        busMarker.setPosition(busPosition);


        // it hasn't reached the next stop, continue to animate
        if ((System.currentTimeMillis() - startTime) < limit) {
            handler1.postDelayed(this, 1000);
        }

        // else the time is up i.e. the bus has reached the next stop, so set the new target
        else {
            Log.d("", "The bus has passed " + NextStop.getName());

            passedStops.add(NextStop);
            Log.d("", passedStops.toString());

            createPolyline();
        }
    }

};

handler1.post(runnable); 

記錄錯誤

Process: com.example.sanj.fyp, PID: 18904
java.lang.IllegalStateException: Not on the main thread
        at com.google.l.a.cd.b(Unknown Source)
        at com.google.maps.api.android.lib6.c.ca.a(Unknown Source)
        at com.google.maps.api.android.lib6.c.aj.a(Unknown Source)
        at com.google.android.gms.maps.model.internal.t.onTransact(SourceFile:73)
        at android.os.Binder.transact(Binder.java:361)
        at com.google.android.gms.maps.model.internal.l$a$a.setPosition(Unknown Source)
        at com.google.android.gms.maps.model.Marker.setPosition(Unknown Source)
        at com.example.sanj.fyp.main.fragment.LiveServiceFragment$2$1.run(LiveServiceFragment.java:423)
        at android.os.Handler.handleCallback(Handler.java:733)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:136)
        at com.example.sanj.fyp.main.fragment.LiveServiceFragment$ThreadClass.run(LiveServiceFragment.java:115)

沒有辦法確定您的handler1變量是從哪個線程創建的。 確保它在UI線程上。 或快速修復:

handler1 = new Handler(context.getApplicationContext().getMainLooper());

您的方法moveBusMarker()在后台線程中運行,這就是您收到此錯誤的原因。 嘗試AsyncTask類。 使用doInBackground方法運行循環程序,然后在postExecute方法中更新UI。

 Handler handler = new Handler(Looper.getMainLooper());

應該解決您的問題。

暫無
暫無

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

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