【发布时间】:2014-05-04 11:21:04
【问题描述】:
我开发了一个应用程序,它在主要活动 (MapActivity) 上显示 MapView,并且此地图视图包含叠加层,点击时会打开一个弹出窗口,其中包含 ViewPager 和片段。我已经通过在带有 viewpager 的弹出窗口上使用 FragmentActivity 调用另一个活动成功地实现了这一点,但它暂停了我不想要的 MapActivity。但是,这个解决方案不会导致IntentReceiver leaks。
我的另一个解决方案是将MapActivity 更改为FragmentActivity,并且使用viewpager 调用弹出窗口效果很好。但是,当关闭活动时会触发IntentReceiver leaks。谷歌搜索,发现解决方案包括在 onDestroy 方法上取消注册意图接收器,但我没有注册任何。
泄漏是NetworkConnectivityListener$ConnectivityBroadcastReceiver 和maps.FSTileCache。顺便说一句,我正在使用 mapquest 库。而且我也在使用兼容性库。
代码如下:
使用 MapActivity
public class MyMapActivity extends MapActivity {
public MapView mapView;
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.my_map_activity);
mapView = (MapView) findViewById(R.id.my_map);
showAllAvailableOverlays();
}
private void showAllAvailableOverlays() {
Bitmap trafficBitmap = null;
List<TrafficProfileDummyModel> dummyTrafficProfiles = new TrafficProfileMockDataSource().getTrafficProfiles();
for(TrafficProfileDummyModel dtp : dummyTrafficProfiles) {
View trafficProfileView = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.traffic_profile_custom_overlay_item, null);
ImageView trafficProfileImageView = (ImageView) trafficProfileView.findViewById(R.id.traffic_profile_image_overlay);
TextView trafficProfileCurrentText = (TextView) trafficProfileView.findViewById(R.id.traffic_profile_custom_overlay_item_currentspeed);
TextView trafficProfileAverageText = (TextView) trafficProfileView.findViewById(R.id.traffic_profile_custom_overlay_item_averagespeed);
int curr = (int)Math.round(MyMapActivity.this.currentTripDataModel.getCurrentAverageSpeed()), ave = Integer.parseInt(dtp.getTrafficProfileHistorical());
trafficProfileCurrentText.setText(String.format("%02d",curr));
trafficProfileAverageText.setText(String.format("%02d",ave));
Drawable trafficProfileMarkerOverlay = null;
trafficBitmap=null;
final GeoPoint geopoint = dtp.getGeopoint();
if((int)Math.round(MyMapActivity.this.currentTripDataModel.getCurrentAverageSpeed()) >= 0 && (int)Math.round(MyMapActivity.this.currentTripDataModel.getCurrentAverageSpeed()) < 35 ) {
// set marker color to red
trafficProfileImageView.setImageDrawable(getResources().getDrawable(R.drawable.traffic_profile_red));
//trafficProfileImageView.setBackground(getResources().getDrawable(R.drawable.traffic_profile_red));
trafficBitmap = bitmapScalerAndResizer.createDrawableFromView(MyMapActivity.this, trafficProfileView);
trafficProfileMarkerOverlay = new BitmapDrawable(getResources(),trafficBitmap);
} else if ((int)Math.round(MyMapActivity.this.currentTripDataModel.getCurrentAverageSpeed()) >= 35 && (int)Math.round(MyMapActivity.this.currentTripDataModel.getCurrentAverageSpeed()) < 49) {
// set marker color to yellow
trafficProfileImageView.setImageDrawable(getResources().getDrawable(R.drawable.traffic_profile_yel));
trafficBitmap = bitmapScalerAndResizer.createDrawableFromView(MyMapActivity.this, trafficProfileView);
trafficProfileMarkerOverlay = new BitmapDrawable(getResources(),trafficBitmap);
} else if ((int)Math.round(MyMapActivity.this.currentTripDataModel.getCurrentAverageSpeed()) >= 50) {
// set marker color to green
trafficProfileImageView.setImageDrawable(getResources().getDrawable(R.drawable.traffic_profile_green));
trafficBitmap = bitmapScalerAndResizer.createDrawableFromView(MyMapActivity.this, trafficProfileView);
trafficProfileMarkerOverlay = new BitmapDrawable(getResources(),trafficBitmap);
}
final DefaultItemizedOverlay overlay = new DefaultItemizedOverlay(trafficProfileMarkerOverlay);
final OverlayItem overlayItem = new OverlayItem(geopoint, "", "");
overlay.addItem(overlayItem);
overlay.setTapListener(new ItemizedOverlay.OverlayTapListener() {
@Override
public void onTap(GeoPoint pt, MapView mapView) {
// this pauses the current activity but doesn't produce intent receiver leaks on activity finish()
Intent trafficProfileIntent = new Intent(MyMapActivity.this, TrafficProfilePopUpActivity.class);
startActivity(trafficProfileIntent);
}
});
mapView.getOverlays().add(overlay);
}
trafficBitmap.recycle();
mapView.invalidate();
}
}
TrafficProfilePopUpActivity(带有 viewpager 和片段的弹出窗口)
public class TrafficProfilePopUpActivity extends FragmentActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
params.gravity = Gravity.NO_GRAVITY;
params.x = 0; params.y = -200;
getWindow().setAttributes(params);
setContentView(R.layout.traffic_profile_viewpager_prompt_layout);
TrafficProfilePagerAdapter pageAdapter = new TrafficProfilePagerAdapter(getSupportFragmentManager(), getFragments());
ViewPager pager = (ViewPager)findViewById(R.id.myViewPager);
pager.setAdapter(pageAdapter);
CirclePageIndicator circlePageIndicator = (CirclePageIndicator) findViewById(R.id.viewPagerIndicator);
circlePageIndicator.setViewPager(pager,0);
}
private List<Fragment> getFragments(){
List<Fragment> fList = new ArrayList<Fragment>();
fList.add(new TrafficProfile_9am_Fragment());
fList.add(new TrafficProfile_12pm_Fragment());
fList.add(new TrafficProfile_3pm_Fragment());
fList.add(new TrafficProfile_6pm_Fragment());
fList.add(new TrafficProfile_9pm_Fragment());
return fList;
}
}
使用 FragmentActivity
public class MyMapActivity extends FragmentActivity {
public MapView mapView;
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.my_map_activity);
mapView = (MapView) findViewById(R.id.my_map);
showAllAvailableOverlays();
}
private void showAllAvailableOverlays() {
Bitmap trafficBitmap = null;
List<TrafficProfileDummyModel> dummyTrafficProfiles = new TrafficProfileMockDataSource().getTrafficProfiles();
for(TrafficProfileDummyModel dtp : dummyTrafficProfiles) {
View trafficProfileView = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.traffic_profile_custom_overlay_item, null);
ImageView trafficProfileImageView = (ImageView) trafficProfileView.findViewById(R.id.traffic_profile_image_overlay);
TextView trafficProfileCurrentText = (TextView) trafficProfileView.findViewById(R.id.traffic_profile_custom_overlay_item_currentspeed);
TextView trafficProfileAverageText = (TextView) trafficProfileView.findViewById(R.id.traffic_profile_custom_overlay_item_averagespeed);
int curr = (int)Math.round(MyMapActivity.this.currentTripDataModel.getCurrentAverageSpeed()), ave = Integer.parseInt(dtp.getTrafficProfileHistorical());
trafficProfileCurrentText.setText(String.format("%02d",curr));
trafficProfileAverageText.setText(String.format("%02d",ave));
Drawable trafficProfileMarkerOverlay = null;
trafficBitmap=null;
final GeoPoint geopoint = dtp.getGeopoint();
if((int)Math.round(MyMapActivity.this.currentTripDataModel.getCurrentAverageSpeed()) >= 0 && (int)Math.round(MyMapActivity.this.currentTripDataModel.getCurrentAverageSpeed()) < 35 ) {
// set marker color to red
trafficProfileImageView.setImageDrawable(getResources().getDrawable(R.drawable.traffic_profile_red));
//trafficProfileImageView.setBackground(getResources().getDrawable(R.drawable.traffic_profile_red));
trafficBitmap = bitmapScalerAndResizer.createDrawableFromView(MyMapActivity.this, trafficProfileView);
trafficProfileMarkerOverlay = new BitmapDrawable(getResources(),trafficBitmap);
} else if ((int)Math.round(MyMapActivity.this.currentTripDataModel.getCurrentAverageSpeed()) >= 35 && (int)Math.round(MyMapActivity.this.currentTripDataModel.getCurrentAverageSpeed()) < 49) {
// set marker color to yellow
trafficProfileImageView.setImageDrawable(getResources().getDrawable(R.drawable.traffic_profile_yel));
trafficBitmap = bitmapScalerAndResizer.createDrawableFromView(MyMapActivity.this, trafficProfileView);
trafficProfileMarkerOverlay = new BitmapDrawable(getResources(),trafficBitmap);
} else if ((int)Math.round(MyMapActivity.this.currentTripDataModel.getCurrentAverageSpeed()) >= 50) {
// set marker color to green
trafficProfileImageView.setImageDrawable(getResources().getDrawable(R.drawable.traffic_profile_green));
trafficBitmap = bitmapScalerAndResizer.createDrawableFromView(MyMapActivity.this, trafficProfileView);
trafficProfileMarkerOverlay = new BitmapDrawable(getResources(),trafficBitmap);
}
final DefaultItemizedOverlay overlay = new DefaultItemizedOverlay(trafficProfileMarkerOverlay);
final OverlayItem overlayItem = new OverlayItem(geopoint, "", "");
overlay.addItem(overlayItem);
overlay.setTapListener(new ItemizedOverlay.OverlayTapListener() {
@Override
public void onTap(GeoPoint pt, MapView mapView) {
// this does not pauses the current activity but when activity closes/finish, produces the intentreceiver leaks
final TrafficProfileDialogFragment trafficProfileDialog = new TrafficProfileDialogFragment();
trafficProfileDialog.show(getSupportFragmentManager(),"");
}
});
mapView.getOverlays().add(overlay);
}
trafficBitmap.recycle();
mapView.invalidate();
}
}
TrafficProfileDialogFragment(类似于弹出式对话框,其中包含 viewpager 和片段)
public class TrafficProfileDialogFragment extends android.support.v4.app.DialogFragment {
@SuppressWarnings("deprecation")
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
final View trafficProfileDialogFragment = this.onCreateView(getActivity().getLayoutInflater(), null, savedInstanceState);
final Dialog dialog = new Dialog(getActivity(), R.style.DialogCustomTheme);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();
lp.dimAmount=0.90f; // Dim level. 0.0 - no dim, 1.0 - completely opaque
lp.y = 75;
lp.height = 300;
lp.width = 300;
dialog.getWindow().setAttributes(lp);
dialog.getWindow().setGravity(Gravity.CENTER_HORIZONTAL|Gravity.TOP);
dialog.getWindow().setBackgroundDrawable(new BitmapDrawable());
dialog.setContentView(trafficProfileDialogFragment);
dialog.setCanceledOnTouchOutside(true);
return dialog;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View trafficProfileDialogFragment = inflater.inflate(R.layout.traffic_profile_viewpager_prompt_layout, container, false);
TrafficProfilePagerAdapter pageAdapter = new TrafficProfilePagerAdapter(getChildFragmentManager(), getFragments());
ViewPager pager = (ViewPager) trafficProfileDialogFragment.findViewById(R.id.myViewPager);
pager.setAdapter(pageAdapter);
CirclePageIndicator circlePageIndicator = (CirclePageIndicator) trafficProfileDialogFragment.findViewById(R.id.viewPagerIndicator);
circlePageIndicator.setViewPager(pager,0);
return trafficProfileDialogFragment;
}
private List<Fragment> getFragments(){
List<Fragment> fList = new ArrayList<Fragment>();
fList.add(new TrafficProfile_9am_Fragment());
fList.add(new TrafficProfile_12pm_Fragment());
fList.add(new TrafficProfile_3pm_Fragment());
fList.add(new TrafficProfile_6pm_Fragment());
fList.add(new TrafficProfile_9pm_Fragment());
return fList;
}
}
我该如何解决这个问题?
【问题讨论】:
标签: android android-fragments memory-leaks android-viewpager android-mapview