如何在调用回调之前暂停Android生命周期阶段?

时间:2016-04-17 19:18:01

标签: android multithreading google-maps

我正在尝试在我的Android应用中使用Google Maps API。我需要调用getMapAsync()以异步方式检索地图对象,我需要在我的片段调用onResume()之前获取GoogleMap对象实例,因为否则GoogleMap对象仍将为null并且它将引发异常。

因此,我希望保持片段的Activity在onResume()处暂停,直到调用onMapReadyCallback为止,这样我就可以保证创建了GoogleMap对象,并且可以在Activity生命周期中继续。但是,如果我在Activity的线程(主线程)中使用任何锁定或屏障同步器,线程将阻塞并且不会接收任何回调,因此将永远等待。

我尝试使用一个对象来实现onMapReadyCallback并将其放在另一个线程中,但根据文档,我必须在主线程中进行回调。

那么如何让主线程等到回调到来并阻止它运行其生命周期方法呢?

3 个答案:

答案 0 :(得分:1)

您有两种方法可以解决您的问题。一个糟糕,一个更好。

糟糕的方式

例如,如果这有助于测试目的,这可行。 当地图对象为空时,调用Handler#postDelayed方法中的onResume()方法。这是一个例子。

@Override
public void onResume(){
    super.onResume();
    doMapStuff();
}

public void doMapStuff()
{
    if (mMap == null) {
        new Handler().postDelayed(new Runnable() {
            public void run() {
                doMapStuff();
            }
        }, 250);
        return;
    }

    // do your stuff on the map here.
}

public void onMapReady(GoogleMap map) {
    mMap = map;
    doMapStuff();
}

当在UI线程上创建处理程序时,延迟的runnable也将在UI线程上执行,因此您将能够制作地图内容。 但这是一个糟糕的方式来做到这一点。它可以用于测试,但避免使用这种方式!

好方法

  • 如果在调用onResume()时您的地图对象为空,则表示将进一步调用onMapReady回调。
  • 如果在调用onResume()时设置了地图对象,则表示已调用onMapReady回调,因此不会再次调用它。

基本上,你需要复制"您在onResume()onMapReady()方法之间的通话。

@Override
public void onResume(){
    super.onResume();
    doMapStuff();
}

public void doMapStuff()
{
    if (mMap == null)
        return;

    // do your stuff on the map here.
}

public void onMapReady(GoogleMap map) {
    mMap = map;
    doMapStuff();
}

答案 1 :(得分:0)

如您所见,您不能暂停或延迟活动生命周期而不会导致问题。

如果在活动生命周期方法时您所需的所有数据都不可用,则可以延迟UI的可见性并推迟需要在活动中完成的其他工作。在所有数据和连接都可用之前显示某种微调器或进度条,然后更新视图以响应所有可用的内容。

答案 2 :(得分:0)

进行检查以确保onMapReady已完成。这对你有用吗?

MapFragment mMapFragment;

@Override
public View onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);    
    mMapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}

public void onMapReady(GoogleMap map){
    mMap = map;
}

然后在onResume上做一个检查:

@Override
public void onResume(){
    super.onResume();
    if(mMap == null){
       mMapFragment.getMapAsync(this);
    }
    //rest of code
}