如何使实例变量更新回调发生在主线程



这是创建GoogleApiClient时调用的代码。所有这些都检索用户的最后位置。

  //omitted code
@Override
public void onConnected(Bundle bundle) {
    Location location = LocationServices.FusedLocationApi.getLastLocation(mApiClient);
    if (location != null) {
        mLongitude = String.valueOf(location.getLongitude());
        mLatitude = String.valueOf(location.getLatitude());
        Log.d(TAG, mLongitude + "___" + mLatitude); //this one doesn't return null
    } else {
        Log.d(TAG, "Location is null");
        LocationServices.FusedLocationApi.requestLocationUpdates(mApiClient, mLocationRequest, this);
    }
}

这是google api客户端:

private void buildGoogleApiClient() {
    mApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
}
这段代码来自我的onCreate()方法:
buildGoogleApiClient();
Log.d(TAG, mLongitude + "___" + mLatitude); //this one returns null

所以当代码运行时,我构建一个google api客户端和onConnected方法被调用。在该方法内部,我将更新实例变量mLongitude和mllatitude变量。但是在日志中,它们返回null。我想知道为什么会发生这种情况,所以我把另一个日志在我的onConnected()方法的if语句内,你可以在第一块代码中看到,这个成功地带回了经度和纬度。我不知道为什么它不更新实例变量。我相信这是因为回调没有在主线程上运行,所以日志发生在更新之前。所以我试着在主线程中像这样运行代码:

runOnUiThread(new Runnable() {
            @Override
            public void run() {
                buildGoogleApiClient();
            }
        });
Log.d(TAG, mLongitude + "___" + mLatitude);
不幸的是,

也不起作用。我搜索了与这个主题相关的东西,并试图在我的代码中实现它们,但似乎没有一个工作,因为我甚至不知道这个问题的真正原因。

有人知道如何解决这个问题吗?

谢谢

buildGoogleApiClient是异步调用。数据将在稍后返回-变量将在调用完成之前打印。

您需要找到一种等待数据返回的方法。有很多方法可以实现。

编辑:

只是为了验证,你可以在非ui线程上运行循环并等待数据更改…如:

new Runnable() {
        @Override
        public void run() {
            while (mLongitude == null) {
                wait(100);
            }
            Log.d(TAG, mLongitude + "___" + mLatitude);
        }
    });

你可能想要改进它,但是有很多方法可以等待,只是不在UI线程上。但问题是,一旦这些数据可用,你想如何处理它们。如果您需要更新数据库而不是UI,那么您需要不同的实现。从根本上讲,它的实现方式与listener一般的实现方式类似。

最新更新