繁体   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