Android版百度地图MapView维护

浏览:
字体:
发布时间:2013-12-09 23:23:22
来源:

最近项目工程使用百度地图,功能确实强大,但就像论坛里很多人提的那样,在MapView的刷新问题上,百度地图还有一定bug,比如在一个dialog中放一个MapView,却发现dialog中的MapView展现效果很差,很多地图上的标志没有刷新出来。比如下图

/

我们可以看到整个地图完全乱套了,现在我贴在这个dialog的代码,然后一起分析下问题

 

package baidumapsdk.demo;import android.app.Dialog;import android.content.Context;import android.view.View;import android.view.Window;import android.widget.Button;import com.baidu.mapapi.map.MapView;import com.baidu.platform.comapi.basestruct.GeoPoint;public class MapDialog extends Dialog{	/**	 *  MapView 是地图主控件	 */	private MapView mMapView = null;	private Button mBtnBack = null;	public MapDialog(Context context) {		super(context);		requestWindowFeature(Window.FEATURE_NO_TITLE);		setContentView(R.layout.mapdialog);		mMapView = (MapView)findViewById(R.id.bmapView);		mMapView.setBuiltInZoomControls(true);		mMapView.getController().setCenter(new GeoPoint((int)(39.945 * 1E6), (int)(116.404 * 1E6)));		mBtnBack = (Button)findViewById(R.id.btn_back);		mBtnBack.setOnClickListener(new View.OnClickListener() {						@Override			public void onClick(View v) {				// TODO Auto-generated method stub				dismiss();			}		});	}	@Override	public void dismiss() {		super.dismiss();	}			}

我们看到在Dialog中我们就直接从xml中引用了地图,不过在百度地图Hello World 介绍中,百度地图似乎还调动了MapView的onResume和onPause等方法,虽然它们都是在Activity中调用的,而我们这是Dialog,但没有条件我们可以创造条件调用,直接在构造函数里调用onResume,dismiss()里调用onPause

 

 

package baidumapsdk.demo;import android.app.Dialog;import android.content.Context;import android.view.View;import android.view.Window;import android.widget.Button;import com.baidu.mapapi.map.MapView;import com.baidu.platform.comapi.basestruct.GeoPoint;public class MapDialog extends Dialog{	/**	 *  MapView 是地图主控件	 */	private MapView mMapView = null;	private Button mBtnBack = null;	public MapDialog(Context context) {		super(context);		requestWindowFeature(Window.FEATURE_NO_TITLE);		setContentView(R.layout.mapdialog);		mMapView = (MapView)findViewById(R.id.bmapView);		mMapView.setBuiltInZoomControls(true);		mMapView.onResume();		mMapView.getController().setCenter(new GeoPoint((int)(39.945 * 1E6), (int)(116.404 * 1E6)));		mBtnBack = (Button)findViewById(R.id.btn_back);		mBtnBack.setOnClickListener(new View.OnClickListener() {						@Override			public void onClick(View v) {				// TODO Auto-generated method stub				dismiss();			}		});	}	@Override	public void dismiss() {		mMapView.onPause();		super.dismiss();	}			}

这个时候似乎我们的使用有效果了,这样使用方式Dialog中MapView刷新没有问题了。

 

但是新问题来了。我们Dialog一般都是在Activity中调用的,如果调用的Activity中也有MapView

 

package baidumapsdk.demo;import android.app.Activity;import android.content.Intent;import android.graphics.Bitmap;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;import com.baidu.mapapi.BMapManager;import com.baidu.mapapi.map.MKMapViewListener;import com.baidu.mapapi.map.MKOfflineMap;import com.baidu.mapapi.map.MKOfflineMapListener;import com.baidu.mapapi.map.MapController;import com.baidu.mapapi.map.MapPoi;import com.baidu.mapapi.map.MapView;import com.baidu.platform.comapi.basestruct.GeoPoint;/** * 演示MapView的基本用法 */public class BaseMapDemo extends Activity implements MKOfflineMapListener{	final static String TAG = MainActivity;	/**	 *  MapView 是地图主控件	 */	private MapView mMapView = null;	/**	 *  用MapController完成地图控制 	 */	private MapController mMapController = null;		private Button mBtnDialog = null;	private Button mBtnActivity = null;		private MKOfflineMap mOffline = null;		    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        /**         * 使用地图sdk前需先初始化BMapManager.         * BMapManager是全局的,可为多个MapView共用,它需要地图模块创建前创建,         * 并在地图地图模块销毁后销毁,只要还有地图模块在使用,BMapManager就不应该销毁         */        DemoApplication app = (DemoApplication)this.getApplication();        if (app.mBMapManager == null) {            app.mBMapManager = new BMapManager(this);            /**             * 如果BMapManager没有初始化则初始化BMapManager             */            app.mBMapManager.init(DemoApplication.strKey,new DemoApplication.MyGeneralListener());        }        /**          * 由于MapView在setContentView()中初始化,所以它需要在BMapManager初始化之后          */        setContentView(R.layout.activity_main);        mMapView = (MapView)findViewById(R.id.bmapView);        mMapView.setBuiltInZoomControls(true);        /**         * 获取地图控制器         */        mMapController = mMapView.getController();        /**         *  设置地图是否响应点击事件  .         */        mMapController.enableClick(true);        /**         * 设置地图缩放级别         */        mMapController.setZoom(12);               /**         * 将地图移动至指定点         * 使用百度经纬度坐标,可以通过http://api.map.baidu.com/lbsapi/getpoint/index.html查询地理坐标         * 如果需要在百度地图上显示使用其他坐标系统的位置,请发邮件至mapapi@baidu.com申请坐标转换接口         */        GeoPoint p ;        double cLat = 39.945 ;        double cLon = 116.404 ;        Intent  intent = getIntent();        if ( intent.hasExtra(x) && intent.hasExtra(y) ){        	//当用intent参数时,设置中心点为指定点        	Bundle b = intent.getExtras();        	p = new GeoPoint(b.getInt(y), b.getInt(x));        }else{        	//设置中心点为天安门        	 p = new GeoPoint((int)(cLat * 1E6), (int)(cLon * 1E6));        }                mMapController.setCenter(p);        		mOffline = new MKOfflineMap();            /**         * 初始化离线地图模块,MapControler可从MapView.getController()获取         */        mOffline.init(mMapController, this);   //     mOffline.scan();		mBtnActivity = (Button)findViewById(R.id.btn_activity);		mBtnDialog = (Button)findViewById(R.id.btn_dialog);		mBtnActivity.setOnClickListener(new OnClickListener() {						@Override			public void onClick(View v) {				// TODO Auto-generated method stub				Intent intent = new Intent(BaseMapDemo.this, GeometryDemo.class);				startActivity(intent);			}		});		mBtnDialog.setOnClickListener(new OnClickListener() {						@Override			public void onClick(View v) {				// TODO Auto-generated method stub				MapDialog dialog = new MapDialog(BaseMapDemo.this);				dialog.show();			}		});    }        @Override    protected void onPause() {    	/**    	 *  MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause()    	 */        mMapView.onPause();        super.onPause();    }        @Override    protected void onResume() {    	/**    	 *  MapView的生命周期与Activity同步,当activity恢复时需调用MapView.onResume()    	 */        mMapView.onResume();        super.onResume();    }        @Override    protected void onDestroy() {    	/**    	 *  MapView的生命周期与Activity同步,当activity销毁时需调用MapView.destroy()    	 */        mMapView.destroy();        super.onDestroy();    }        @Override    protected void onSaveInstanceState(Bundle outState) {    	super.onSaveInstanceState(outState);    	mMapView.onSaveInstanceState(outState);    	    }        @Override    protected void onRestoreInstanceState(Bundle savedInstanceState) {    	super.onRestoreInstanceState(savedInstanceState);    	mMapView.onRestoreInstanceState(savedInstanceState);    }	@Override	public void onGetOfflineMapState(int arg0, int arg1) {		// TODO Auto-generated method stub			}    }

这个Activity的中使用MapView的方式就是百度官方代码使用MapView的方式,当我们dimiss了dialog,发现Activity上的MapView的刷新也出问题了,甚至我测试有的时候Activity上的MapView连动都不能动,整个屏幕像死机了一样。

 

/

而且刷新混乱的方式跟之前Dialog混乱的方式很像,之前我们解决Dialog刷新混乱的问题的时候,是在Dialog调用了MapView的onResume方法,现在我们也来在dismiss了Dialog后再次调用Activity中MapView的onResume,有onResume方法就得有相应的onPause方法对应,显然,是在show Dialog的时候让Activity中的MapView onPause,

现在我们把Dialog和Activity中代码修改如下:

 

package baidumapsdk.demo;import android.app.Dialog;import android.content.Context;import android.view.View;import android.view.Window;import android.widget.Button;import baidumapsdk.demo.BaseMapDemo.MapDialogCallback;import com.baidu.mapapi.map.MapView;import com.baidu.platform.comapi.basestruct.GeoPoint;public class MapDialog extends Dialog{	/**	 *  MapView 是地图主控件	 */	private MapView mMapView = null;	private Button mBtnBack = null;	private MapDialogCallback mCallback;	public MapDialog(Context context) {		super(context);		requestWindowFeature(Window.FEATURE_NO_TITLE);		setContentView(R.layout.mapdialog);		mMapView = (MapView)findViewById(R.id.bmapView);		mMapView.setBuiltInZoomControls(true);		mMapView.onResume();		mMapView.getController().setCenter(new GeoPoint((int)(39.945 * 1E6), (int)(116.404 * 1E6)));		mBtnBack = (Button)findViewById(R.id.btn_back);		mBtnBack.setOnClickListener(new View.OnClickListener() {						@Override			public void onClick(View v) {				// TODO Auto-generated method stub				dismiss();			}		});	}	@Override	public void dismiss() {		mMapView.onPause();		mCallback.mapback();		super.dismiss();	}		public void registerCallback(MapDialogCallback callback) {		mCallback = callback;	}		}

package baidumapsdk.demo;import android.app.Activity;import android.content.Intent;import android.graphics.Bitmap;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;import com.baidu.mapapi.BMapManager;import com.baidu.mapapi.map.MKMapViewListener;import com.baidu.mapapi.map.MKOfflineMap;import com.baidu.mapapi.map.MKOfflineMapListener;import com.baidu.mapapi.map.MapController;import com.baidu.mapapi.map.MapPoi;import com.baidu.mapapi.map.MapView;import com.baidu.platform.comapi.basestruct.GeoPoint;/** * 演示MapView的基本用法 */public class BaseMapDemo extends Activity implements MKOfflineMapListener{	final static String TAG = MainActivity;	/**	 *  MapView 是地图主控件	 */	private MapView mMapView = null;	/**	 *  用MapController完成地图控制 	 */	private MapController mMapController = null;		private Button mBtnDialog = null;	private Button mBtnActivity = null;		private MKOfflineMap mOffline = null;		public interface MapDialogCallback{		void mapback();	}	    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        /**         * 使用地图sdk前需先初始化BMapManager.         * BMapManager是全局的,可为多个MapView共用,它需要地图模块创建前创建,         * 并在地图地图模块销毁后销毁,只要还有地图模块在使用,BMapManager就不应该销毁         */        DemoApplication app = (DemoApplication)this.getApplication();        if (app.mBMapManager == null) {            app.mBMapManager = new BMapManager(this);            /**             * 如果BMapManager没有初始化则初始化BMapManager             */            app.mBMapManager.init(DemoApplication.strKey,new DemoApplication.MyGeneralListener());        }        /**          * 由于MapView在setContentView()中初始化,所以它需要在BMapManager初始化之后          */        setContentView(R.layout.activity_main);        mMapView = (MapView)findViewById(R.id.bmapView);        mMapView.setBuiltInZoomControls(true);        /**         * 获取地图控制器         */        mMapController = mMapView.getController();        /**         *  设置地图是否响应点击事件  .         */        mMapController.enableClick(true);        /**         * 设置地图缩放级别         */        mMapController.setZoom(12);               /**         * 将地图移动至指定点         * 使用百度经纬度坐标,可以通过http://api.map.baidu.com/lbsapi/getpoint/index.html查询地理坐标         * 如果需要在百度地图上显示使用其他坐标系统的位置,请发邮件至mapapi@baidu.com申请坐标转换接口         */        GeoPoint p ;        double cLat = 39.945 ;        double cLon = 116.404 ;        Intent  intent = getIntent();        if ( intent.hasExtra(x) && intent.hasExtra(y) ){        	//当用intent参数时,设置中心点为指定点        	Bundle b = intent.getExtras();        	p = new GeoPoint(b.getInt(y), b.getInt(x));        }else{        	//设置中心点为天安门        	 p = new GeoPoint((int)(cLat * 1E6), (int)(cLon * 1E6));        }                mMapController.setCenter(p);        		mOffline = new MKOfflineMap();            /**         * 初始化离线地图模块,MapControler可从MapView.getController()获取         */        mOffline.init(mMapController, this);   //     mOffline.scan();		mBtnActivity = (Button)findViewById(R.id.btn_activity);		mBtnDialog = (Button)findViewById(R.id.btn_dialog);		mBtnActivity.setOnClickListener(new OnClickListener() {						@Override			public void onClick(View v) {				// TODO Auto-generated method stub				Intent intent = new Intent(BaseMapDemo.this, GeometryDemo.class);				startActivity(intent);			}		});		mBtnDialog.setOnClickListener(new OnClickListener() {						@Override			public void onClick(View v) {				// TODO Auto-generated method stub				mMapView.onPause();				MapDialog dialog = new MapDialog(BaseMapDemo.this);				dialog.registerCallback(new MapDialogCallback() {										@Override					public void mapback() {						// TODO Auto-generated method stub						mMapView.onResume();					}				});				dialog.show();			}		});    }        @Override    protected void onPause() {    	/**    	 *  MapView的生命周期与Activity同步,当activity挂起时需调用MapView.onPause()    	 */        mMapView.onPause();        super.onPause();    }        @Override    protected void onResume() {    	/**    	 *  MapView的生命周期与Activity同步,当activity恢复时需调用MapView.onResume()    	 */        mMapView.onResume();        super.onResume();    }        @Override    protected void onDestroy() {    	/**    	 *  MapView的生命周期与Activity同步,当activity销毁时需调用MapView.destroy()    	 */        mMapView.destroy();        super.onDestroy();    }        @Override    protected void onSaveInstanceState(Bundle outState) {    	super.onSaveInstanceState(outState);    	mMapView.onSaveInstanceState(outState);    	    }        @Override    protected void onRestoreInstanceState(Bundle savedInstanceState) {    	super.onRestoreInstanceState(savedInstanceState);    	mMapView.onRestoreInstanceState(savedInstanceState);    }	@Override	public void onGetOfflineMapState(int arg0, int arg1) {		// TODO Auto-generated method stub			}    }
按照这个方法修改代码后发现地图无论是在Dialog和Activity中都能正常使用,刷新问题不复存在。

 

 

由于我们看不到onResume和onPause中的源码,因此对于这个刷新问题,我们只能做猜测,我个人觉得MapView中有些刷新和显示上的控制是在onResume中操作,而在onPause中去暂停操作,个人觉得绘制地图应该是很耗资源的事情,所以确实需要这样的一些操作。但可能有些操作可能是静态全局性的,所以不管一个工程中有多少个MapView,都有些共用的操作,因此才会导致不同地图的刷新问题似乎会相互影响。

经过几天研究,我个人觉得目前的解决方案是每个MapView要有单独维护的onResume和onPause调用,不管这个MapView是在Dialog还是Activity中显示,在你需要使用MapView就调用其onResume方法,在你暂时不需要使用的时候就调用其onPause方法。

 

>更多相关文章
24小时热门资讯
24小时回复排行
资讯 | QQ | 安全 | 编程 | 数据库 | 系统 | 网络 | 考试 | 站长 | 关于东联 | 安全雇佣 | 搞笑视频大全 | 微信学院 | 视频课程 |
关于我们 | 联系我们 | 广告服务 | 免责申明 | 作品发布 | 网站地图 | 官方微博 | 技术培训
Copyright © 2007 - 2023 Vm888.Com. All Rights Reserved
粤公网安备 44060402001498号 粤ICP备19097316号 请遵循相关法律法规
');})();