You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android/Java:让继承AppCompatActivity的Activity继承自定义类

解决方案:用组合替代继承实现职责分离

Java不支持多继承,所以你的HereMap(继承AppCompatActivity)无法再继承HereMapClass。正确的做法是组合模式:将HereMapClass作为HereMap的成员变量,让HereMapClass专注于地图下载、地图包管理等业务逻辑,HereMap只负责UI可视化。

步骤1:重构HereMapClass,剥离UI依赖并定义回调

首先清理HereMapClass中的UI相关成员,只保留核心逻辑,并通过回调接口将状态通知给UI层:

public class HereMapClass {
    private final static String TAG = HereMapClass.class.getSimpleName();
    private MapLoader mapLoader;
    private ArrayList<MapPackage> currentInstalledMaps;
    private Context context;
    private MapLoaderCallback callback;

    // 定义回调接口,用于通知UI层状态变化
    public interface MapLoaderCallback {
        void onDownloadProgress(int progress);
        void onError(String errorMsg);
        void onMapPackagesLoaded(ArrayList<MapPackage> installedPackages);
    }

    public HereMapClass(Context context, MapLoaderCallback callback) {
        this.context = context;
        this.callback = callback;
        initMapLoader();
    }

    private void initMapLoader() {
        mapLoader = MapLoader.getInstance();
        // 初始化地图加载器的其他逻辑...
    }

    // 公开方法:获取已安装地图包
    public void fetchInstalledMapPackages() {
        mapLoader.getMapPackages(mapLoaderHandler);
    }

    // MapLoader监听器,内部处理逻辑,通过回调通知UI
    private MapLoader.Listener mapLoaderHandler = new MapLoader.Listener() {
        @Override
        public void onProgress(int progress) {
            Log.i(TAG, "Progress " + progress + "%");
            if (callback != null) {
                callback.onDownloadProgress(progress);
            }
        }

        @Override
        public void onInstallationSize(long diskSize, long networkSize) {
            Log.i(TAG, "Map data require " + diskSize);
        }

        @Override
        public void onGetMapPackagesComplete(MapPackage rootMapPackage, MapLoader.ResultCode resultCode) {
            if (resultCode == MapLoader.ResultCode.OPERATION_SUCCESSFUL) {
                Log.i(TAG, "Map packages received successful: " + rootMapPackage.getTitle());
                currentInstalledMaps = new ArrayList<>(1);
                populateInstalledMaps(rootMapPackage);

                if (callback != null) {
                    callback.onMapPackagesLoaded(currentInstalledMaps);
                }
            } else {
                String errorMsg = "Can't retrieve map packages: " + resultCode.name();
                Log.e(TAG, errorMsg);
                if (callback != null) {
                    callback.onError(errorMsg);
                }
            }
        }

        private void populateInstalledMaps(MapPackage pac) {
            if (pac.getInstallationState() == MapPackage.InstallationState.INSTALLED) {
                Log.i(TAG, "Installed package found: " + pac.getTitle() + " id " + pac.getId());
                currentInstalledMaps.add(pac);
            } else if (pac.getChildren() != null && pac.getChildren().size() > 0) {
                for (MapPackage p : pac.getChildren()) {
                    populateInstalledMaps(p);
                }
            }
        }
    };

    // 其他地图下载相关的公开方法,比如启动下载、取消下载等
    public void startMapDownload(MapPackage packageToDownload) {
        // 实现地图下载逻辑...
    }
}

步骤2:修改HereMap Activity,组合HereMapClass并处理UI

让HereMap实现HereMapClass.MapLoaderCallback接口,实例化HereMapClass,专注于地图可视化:

import androidx.appcompat.app.AppCompatActivity;

public class HereMap extends AppCompatActivity implements HereMapClass.MapLoaderCallback {
    private final static String TAG = HereMap.class.getSimpleName();
    // UI相关成员,只保留可视化需要的
    private MapView mapView;
    private AndroidXMapFragment mapFragment;
    private Map map;
    private ProgressBar downloadProgressBar;
    // 组合HereMapClass,处理业务逻辑
    private HereMapClass hereMapClass;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_here_map);
        
        // 初始化UI控件
        downloadProgressBar = findViewById(R.id.download_progress);
        initMapView();
        
        // 实例化HereMapClass,传入Context和回调
        hereMapClass = new HereMapClass(this, this);
        // 调用业务方法,获取已安装地图包
        hereMapClass.fetchInstalledMapPackages();
    }

    // 初始化地图可视化相关逻辑
    private void initMapView() {
        mapView = findViewById(R.id.map_view);
        mapView.onCreate(savedInstanceState);
        mapView.getMapAsync(map -> {
            this.map = map;
            // 地图初始化完成后的可视化操作,比如添加标记、设置地图样式等
        });
    }

    // 实现回调接口,处理UI更新
    @Override
    public void onDownloadProgress(int progress) {
        runOnUiThread(() -> downloadProgressBar.setProgress(progress));
    }

    @Override
    public void onError(String errorMsg) {
        runOnUiThread(() -> Toast.makeText(HereMap.this, errorMsg, Toast.LENGTH_SHORT).show());
    }

    @Override
    public void onMapPackagesLoaded(ArrayList<MapPackage> installedPackages) {
        runOnUiThread(() -> {
            // 处理已安装地图包的UI展示,比如显示列表
            StringBuilder sb = new StringBuilder();
            for (MapPackage pac : installedPackages) {
                sb.append(pac.getTitle()).append("\n");
            }
            // 比如显示在TextView中
            // TextView installedMapsTv = findViewById(R.id.installed_maps_tv);
            // installedMapsTv.setText(sb.toString());
        });
    }

    // 其他UI相关方法,比如处理地图点击、添加标记等
    private void addMapMarker(GeoCoordinate coordinate) {
        // 实现标记添加逻辑...
    }

    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
    }

    @Override
    protected void onPause() {
        mapView.onPause();
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        mapView.onDestroy();
        super.onDestroy();
    }
}

关键说明

  • 职责分离:HereMapClass只处理地图下载、地图包管理等无UI的业务逻辑,可在多个组件(比如Service、其他Activity)中复用;HereMap专注于地图的可视化展示和用户交互。
  • 回调机制:通过回调接口让HereMapClass将状态变化通知给UI层,避免直接依赖UI控件,保证类的独立性。
  • 生命周期管理:Activity中的地图控件(MapView)需要正确处理生命周期方法,避免内存泄漏或功能异常。

内容的提问来源于stack exchange,提问作者ΩlostA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 20:05:36