重构方案-移除ShareProxyActivity.md 13 KB

分享模块重构方案 - 移除 ShareProxyActivity

一、现状分析

1.1 当前架构

当前分享模块使用 ShareProxyActivity 作为透明代理 Activity 来统一处理所有平台的分享回调:

业务层调用 shareService.share(activity, content, callback)
    ↓
自动启动 ShareProxyActivity(透明)
    ↓
ShareProxyActivity.onCreate() 调用 shareService.shareManual()
    ↓
执行实际分享(友盟SDK)
    ↓
用户在第三方应用完成分享
    ↓
第三方应用回调 → ShareProxyActivity.onActivityResult()
    ↓
ShareProxyActivity 调用 shareService.onActivityResult()
    ↓
处理回调并传递给业务层
    ↓
ShareProxyActivity 自动关闭

1.2 当前实现的关键点

  1. ShareProxyActivity

    • 透明的代理 Activity,用户看不到
    • 统一处理所有平台的 onActivityResult 回调
    • 业务层无需在 Activity 中处理回调
  2. share() 方法

    • 自动启动 ShareProxyActivity
    • 内部使用 shareManual() 避免递归调用
  3. shareManual() 方法

    • ShareProxyActivity 内部调用
    • 直接执行分享逻辑,不启动代理 Activity
  4. onActivityResult() 方法

    • ShareProxyActivity 调用
    • 转发给友盟 SDK 处理

1.3 当前架构的优势

业务层透明:业务层不需要处理 onActivityResult
统一处理:所有平台的回调都统一在 ShareProxyActivity 中处理
完全封装:实现细节完全封装在模块内部

1.4 当前架构的问题

依赖 Activity:必须启动一个透明的 Activity
生命周期复杂:需要管理 Activity 的生命周期和超时
增加 Activity 栈:每次分享都会启动新的 Activity
灵活性不足:无法让业务层自行处理回调


二、重构目标

2.1 需求

  1. 移除 ShareProxyActivity:不通过代理 Activity 统一处理
  2. 只暴露方法:所有功能都通过方法暴露
  3. 统一入口:提供一个统一的分享方法给外部调用
  4. 业务层自行处理回调:业务层需要在 Activity 中处理 onActivityResult

2.2 重构后的架构

业务层调用 shareService.share(activity, content, callback)
    ↓
直接执行分享(友盟SDK)
    ↓
用户在第三方应用完成分享
    ↓
第三方应用回调 → 业务层 Activity.onActivityResult()
    ↓
业务层调用 shareService.onActivityResult()
    ↓
处理回调并传递给业务层

三、重构方案

3.1 API 设计

3.1.1 统一分享方法

所有分享都通过一个统一的 share() 方法:

interface ShareService {
    /**
     * 统一分享方法(推荐使用)
     * 
     * 如果 ShareContent.platform 已指定,则直接分享到该平台
     * 如果 ShareContent.platform 为 null,则显示分享弹窗让用户选择平台
     * 
     * 注意:业务层需要在 Activity.onActivityResult() 中调用 shareService.onActivityResult()
     * 
     * @param activity Activity上下文
     * @param content 分享内容
     * @param callback 分享结果回调
     */
    fun share(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit)
    
    /**
     * 处理分享回调(必须在 Activity.onActivityResult() 中调用)
     * 
     * 业务层必须在 Activity.onActivityResult() 中调用此方法,以接收分享结果
     * 
     * @param activity Activity上下文
     * @param requestCode 请求码
     * @param resultCode 结果码
     * @param data Intent数据
     */
    fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, data: Intent?)
}

3.1.2 各平台分享方法(可选,向后兼容)

保留各平台的具体分享方法,但都改为直接调用,不通过代理 Activity:

interface ShareService {
    // 统一分享方法(推荐)
    fun share(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit)
    
    // 各平台分享方法(可选,向后兼容)
    fun shareToWeChat(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit)
    fun shareToWeChatMoments(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit)
    fun shareToQQ(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit)
    fun shareToQZone(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit)
    fun shareToWeibo(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit)
    fun shareToDouyin(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit)
    fun shareToXiaohongshu(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit)
    fun shareToKuaishou(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit)
    fun shareToSystem(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit)
    
    // 显示分享弹窗
    fun showShareDialog(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit)
    
    // 必须调用:处理分享回调
    fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, data: Intent?)
}

3.2 实现改动

3.2.1 ShareService 接口改动

interface ShareService {
    // 移除 shareManual() 方法(不再需要)
    // 移除:fun shareManual(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit)
    
    // share() 方法改为直接执行,不启动 ShareProxyActivity
    fun share(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit) {
        // 如果指定了平台,直接分享到该平台
        if (content.platform != null) {
            shareToPlatform(activity, content, content.platform, callback)
        } else {
            // 否则显示分享弹窗
            showShareDialog(activity, content, callback)
        }
    }
}

3.2.2 ShareServiceImpl 实现改动

class ShareServiceImpl : ShareService {
    
    // 存储回调(用于 onActivityResult 时查找)
    private val callbacks = mutableMapOf<Int, (ShareResponse) -> Unit>()
    private var requestCodeCounter = 1000
    
    override fun share(activity: Activity, content: ShareContent, callback: (ShareResponse) -> Unit) {
        // 不再启动 ShareProxyActivity,直接执行分享
        if (content.platform != null) {
            shareToPlatform(activity, content, content.platform, callback)
        } else {
            showShareDialog(activity, content, callback)
        }
    }
    
    private fun shareToPlatform(
        activity: Activity,
        content: ShareContent,
        platform: SharePlatform,
        callback: (ShareResponse) -> Unit
    ) {
        // 生成唯一的 requestCode
        val requestCode = requestCodeCounter++
        callbacks[requestCode] = callback
        
        // 调用友盟 SDK 进行分享
        val shareMedia = createShareMedia(activity, content)
        val shareAction = ShareAction(activity)
        shareAction.withMedia(shareMedia)
        shareAction.setPlatform(toShareMedia(platform))
        shareAction.setCallback(createShareListener(platform, requestCode, callback))
        shareAction.share()
    }
    
    override fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, data: Intent?) {
        // 转发给友盟 SDK 处理
        UMShareAPI.get(activity).onActivityResult(requestCode, resultCode, data)
    }
    
    private fun createShareListener(
        platform: SharePlatform,
        requestCode: Int,
        callback: (ShareResponse) -> Unit
    ): UMShareListener {
        return object : UMShareListener {
            override fun onResult(shareMedia: SHARE_MEDIA?) {
                // 找到对应的回调并调用
                callbacks[requestCode]?.invoke(
                    ShareResponse(success = true, data = platform)
                )
                callbacks.remove(requestCode)
            }
            
            override fun onError(shareMedia: SHARE_MEDIA?, throwable: Throwable?) {
                callbacks[requestCode]?.invoke(
                    ShareResponse(
                        success = false,
                        data = platform,
                        errorMessage = throwable?.message
                    )
                )
                callbacks.remove(requestCode)
            }
            
            override fun onCancel(shareMedia: SHARE_MEDIA?) {
                callbacks[requestCode]?.invoke(
                    ShareResponse(
                        success = false,
                        data = platform,
                        errorMessage = "用户取消分享"
                    )
                )
                callbacks.remove(requestCode)
            }
        }
    }
}

3.2.3 移除 ShareProxyActivity

  • 删除 ShareProxyActivity.kt 文件
  • AndroidManifest.xml 中移除 ShareProxyActivity 的声明
  • 移除 shareManual() 方法(不再需要)

3.3 业务层改动

3.3.1 使用示例(Fragment)

class UserFragment : Fragment() {
    
    private val shareService = ShareServiceFactory.getInstance()
    
    private fun shareContent() {
        val content = ShareContent.builder()
            .setTitle("分享标题")
            .setDescription("分享描述")
            .setUrl("https://example.com")
            .build()
        
        // 调用统一分享方法
        shareService.share(requireActivity(), content) { response ->
            if (response.success) {
                Toast.makeText(requireContext(), "分享成功", Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(requireContext(), "分享失败: ${response.errorMessage}", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

3.3.2 必须处理 onActivityResult

重要:业务层必须在 Activity 中处理 onActivityResult

class MainActivity : AppCompatActivity() {
    
    private val shareService = ShareServiceFactory.getInstance()
    
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        
        // 必须调用:处理分享回调
        shareService.onActivityResult(this, requestCode, resultCode, data)
    }
}

3.4 兼容性考虑

3.4.1 向后兼容

  • 保留所有现有的 API 方法(shareToWeChat(), shareToQQ() 等)
  • 只是改变实现方式(不再通过 ShareProxyActivity)
  • 业务层代码改动最小化

3.4.2 迁移指南

  1. 必须添加:在 Activity 中添加 onActivityResult() 处理
  2. 无需改动:调用 share() 方法的代码无需改动
  3. 可选:可以继续使用各平台的具体方法(shareToWeChat() 等)

四、重构步骤

步骤 1:修改 ShareService 接口

  • 移除 shareManual() 方法
  • 更新 share() 方法的文档说明

步骤 2:修改 ShareServiceImpl 实现

  • 修改 share() 方法,不再启动 ShareProxyActivity
  • 实现回调管理(使用 Map 存储回调)
  • 修改各平台分享方法,使用回调管理
  • 更新 onActivityResult() 方法,从回调 Map 中查找并调用回调

步骤 3:移除 ShareProxyActivity

  • 删除 ShareProxyActivity.kt 文件
  • AndroidManifest.xml 中移除相关声明
  • 清理相关引用

步骤 4:更新文档

  • 更新 集成说明.md
  • 添加 onActivityResult() 处理说明
  • 更新使用示例

步骤 5:测试

  • 测试各平台分享功能
  • 测试分享回调处理
  • 测试分享弹窗功能

五、优缺点分析

5.1 优点

灵活性更高:业务层可以自行处理回调
减少 Activity 栈:不再启动代理 Activity
代码更简洁:移除复杂的 Activity 生命周期管理
更符合 Android 规范:业务层直接处理回调

5.2 缺点

增加业务层负担:业务层必须在 Activity 中处理 onActivityResult
可能遗漏回调:如果业务层忘记处理 onActivityResult,分享回调将丢失
Fragment 使用不便:Fragment 需要依赖 Activity 的 onActivityResult


六、注意事项

  1. 必须处理 onActivityResult:业务层必须在 Activity 中调用 shareService.onActivityResult()
  2. Fragment 使用:Fragment 需要确保 Activity 正确处理 onActivityResult
  3. 回调管理:需要实现回调的存储和查找机制(使用 requestCode 作为 key)
  4. 内存泄漏:需要确保回调能够及时清理,避免内存泄漏

七、总结

重构后的分享模块:

  • ✅ 移除了 ShareProxyActivity,不再通过代理 Activity 处理回调
  • ✅ 所有功能都通过方法暴露,提供统一的 share() 方法
  • ✅ 业务层需要自行处理 onActivityResult
  • ✅ 保持向后兼容,现有 API 仍然可用

这个方案更符合 Android 的开发规范,也给了业务层更多的控制权。