# 友盟分享集成说明 ## 目录结构 ``` capability-share/src/ └── main/ ├── AndroidManifest.xml # Android 清单文件(权限声明) └── java/ └── com/narutohuo/xindazhou/share/ ├── api/ # API 接口层 │ └── ShareService.kt # 分享服务接口定义(统一 share() 方法 + 9个平台方法) ├── factory/ # 工厂类层 │ └── ShareServiceFactory.kt # 服务工厂(统一入口,单例获取) ├── impl/ # 实现层 │ └── ShareServiceImpl.kt # 分享服务具体实现(封装友盟SDK) ├── ui/ # UI层 │ ├── ShareDialogFragment.kt # 分享弹窗(封装在模块内部) │ └── ShareProxyActivity.kt # 透明代理 Activity(自动处理 onActivityResult) └── model/ # 数据模型层 ├── ShareResponse.kt # 分享相关的数据模型 │ ├── ShareContent # 分享内容模型 │ ├── ShareResponse # 分享响应模型 │ └── SharePlatform # 分享平台枚举 └── ShareConfig.kt # 分享服务配置模型 ├── ShareConfig # 主配置类 ├── WeChatConfig # 微信平台配置 ├── QQConfig # QQ平台配置 └── WeiboConfig # 微博平台配置 ``` ## 功能说明 ### 1. api/ 层 - 接口定义 - **职责**:定义分享服务的公共接口,业务层只依赖接口 - **内容**:`ShareService` 接口 - `share()` - 统一分享方法(推荐使用,业务层调用) - **自动处理 onActivityResult**,业务层不需要在 Activity 中处理回调 - 如果 `ShareContent.platform` 已指定,直接分享到该平台 - 如果 `ShareContent.platform` 为 null,显示分享弹窗让用户选择 - 内部使用透明代理 Activity 封装所有实现细节 - `shareManual()` - 手动分享方法(内部使用,避免递归调用) - 供 `ShareProxyActivity` 内部调用,业务层不应直接使用 - 如果指定了平台,直接分享到该平台;否则显示分享弹窗 - `showShareDialog()` - 显示分享弹窗(底部弹出) ### 2. factory/ 层 - 工厂类 - **职责**:提供统一的服务实例获取和初始化方式 - **内容**:`ShareServiceFactory` 单例工厂 - **作用**: - 隐藏实现细节,统一入口,便于替换实现 - 提供 `init()` 方法统一初始化,避免在 Application 中直接调用服务方法 - 提供 `getInstance()` 方法获取服务实例 ### 3. impl/ 层 - 具体实现 - **职责**:实现 `ShareService` 接口的具体逻辑 - **内容**:`ShareServiceImpl` 单例实现类 - **功能**: - 封装友盟分享 SDK 调用 - 封装友盟初始化逻辑(`initialize()`) - 封装分享回调处理(`onActivityResult()`)- 通过透明代理 Activity 自动处理 - 封装资源释放(`release()`) - 实现统一的 `share()` 方法,自动使用透明代理 Activity,业务层无需处理回调 - 实现 `shareManual()` 方法(内部使用,避免递归调用),供 `ShareProxyActivity` 调用 - 实现 `showShareDialog()` 方法,显示分享弹窗 - 处理分享回调(成功/失败/取消) - 错误处理和日志记录 - 支持网页、图片、文本等多种分享类型 ### 3.1 ui/ 层 - UI组件 - **职责**:封装分享相关的 UI 组件 - **内容**: - `ShareDialogFragment` - 分享弹窗(底部弹出) - 底部弹出(Material Design BottomSheet) - 显示所有可用分享平台(微信、朋友圈、QQ、QQ空间、微博、更多) - 用户选择平台后自动执行分享 - 弹窗逻辑完全封装在模块内部,主工程无需关心 - `ShareProxyActivity` - 透明代理 Activity(自动处理 onActivityResult) - 继承自 `FragmentActivity`,支持显示 `ShareDialogFragment` - 完全封装在模块内部,业务层不需要知道它的存在 - 自动处理分享回调,业务层不需要在 Activity 中处理 `onActivityResult` - 内部使用 `shareManual()` 方法避免递归调用 - 透明主题,用户看不到 - 分享完成后自动关闭 ### 4. model/ 层 - 数据模型 - **职责**:定义分享相关的数据模型 - **内容**: - `ShareContent` - 分享内容模型(标题、描述、URL、图片等) - **Builder 模式**:`ShareContent.builder()` 链式调用构建,支持灵活的参数组合 - **平台类型**:`platform: SharePlatform?` 字段 - 如果指定,直接分享到该平台(不显示弹窗) - 如果为 null,显示分享弹窗让用户选择 - `ShareResponse` - 分享响应模型(成功/失败、错误信息等) - `SharePlatform` - 分享平台枚举(9个平台) - `ShareConfig` - 分享服务配置模型(封装友盟和各平台配置) - `WeChatConfig` - 微信平台配置 - `QQConfig` - QQ平台配置 - `WeiboConfig` - 微博平台配置 ### 5. AndroidManifest.xml - 权限配置 - **职责**:声明模块所需的 Android 权限 - **内容**:网络权限声明 ## 架构设计 - **接口隔离**:业务层只依赖接口,不依赖实现 - **ARouter 依赖注入**:通过 ARouter 实现模块间解耦,base-core 定义接口,能力层实现接口 - **工厂模式**:统一入口,隐藏创建逻辑(内部使用 ARouter 获取服务) - **单例模式**:全局共享一个服务实例 - **分层架构**:base-core (接口) → capability-share (实现) → ARouter (注册) → Factory (获取) - **完全封装**:使用透明代理 Activity 自动处理 `onActivityResult`,业务层无需关心实现细节 ### ARouter 架构说明 - **base-core** 模块定义 `IShareService` 接口(位于 `com.narutohuo.xindazhou.core.share`) - **capability-share** 模块实现 `IShareService` 接口,并通过 `@Route(path = "/share/service")` 注册到 ARouter - **base-core** 模块中的 `WXEntryActivity` 通过 ARouter 注入 `IShareCallback` 实现(`@Route(path = "/share/callback")`) - **Factory** 内部使用 `ARouter.getInstance().navigation(IShareService::class.java)` 获取服务实例 - **业务层** 通过 Factory 获取服务,无需直接依赖实现模块 ## 核心功能说明 ### 1. 分享回调流程(完全封装,统一处理所有平台) **完整回调链路**: ``` 业务层调用 shareService.share(activity, content, callback) ↓ ShareServiceImpl.share() 自动启动 ShareProxyActivity ↓ ShareProxyActivity.onCreate() 调用 shareService.shareManual() ↓ ShareServiceImpl.shareManual() 调用友盟 SDK 进行分享(或显示分享弹窗) ↓ 用户在第三方应用(如微信、QQ、微博)完成分享操作 ↓ 第三方应用回调到各自的回调 Activity: - 微信 → WXEntryActivity(base-core 模块,通过 ARouter 注入 IShareCallback) ↓ WXEntryActivity.onWeChatCallback() 调用 shareCallback.onWeChatCallback() ↓ ShareCallbackImpl.onWeChatCallback() 处理回调 - QQ → AuthActivity(QQ SDK 自带,友盟自动处理) - 微博 → WBShareTransActivity(微博 SDK 自带,友盟自动处理) ↓ 友盟 SDK 通过 onActivityResult 回调到 ShareProxyActivity.onActivityResult() ↓ ShareProxyActivity.onActivityResult() 调用 shareService.onActivityResult() ↓ ShareServiceImpl.onActivityResult() 调用 UMShareAPI.get(activity).onActivityResult() ↓ 友盟 SDK 触发 ShareServiceImpl 中设置的 UMShareListener.onResult() / onError() / onCancel() ↓ UMShareListener 调用业务层传入的 callback 函数 ↓ ShareProxyActivity 收到回调结果,调用业务层的 callback,并自动关闭自身 ↓ 业务层的 callback { response -> ... } 被调用 ✅ ``` **关键点**: - ✅ **统一入口**:`share()` 方法自动启动 `ShareProxyActivity`,所有平台的分享都通过它处理 - ✅ **统一回调**:所有平台(微信、QQ、微博等)的回调都统一回到 `ShareProxyActivity.onActivityResult()` - ✅ **ARouter 解耦**:`WXEntryActivity` 在 `base-core` 模块,通过 ARouter 注入 `IShareCallback` 实现,实现模块间解耦 - ✅ **业务层透明**:业务层不需要在 Activity 中处理 `onActivityResult`,完全封装在模块内部 - ✅ **自动关闭**:`ShareProxyActivity` 收到回调后自动关闭,用户无感知 ## 已完成的工作 ✅ **SDK 依赖已添加** - `com.umeng.umsdk:common:9.6.8` - 友盟基础库 - `com.umeng.umsdk:share-core:7.3.2` - 友盟分享核心库 - `com.umeng.umsdk:share-board:7.3.2` - 友盟分享面板 - `com.umeng.umsdk:share-wx:7.3.2` - 微信分享 - `com.umeng.umsdk:share-qq:7.3.2` - QQ分享 - `com.umeng.umsdk:share-sina:7.3.2` - 新浪微博分享 ✅ **代码实现已完成** - `ShareServiceImpl` 已实现友盟分享 SDK 调用,并实现 `IShareService` 接口 - `ShareServiceImpl` 已通过 ARouter 注册(`@Route(path = "/share/service")`) - `ShareCallbackImpl` 已实现 `IShareCallback` 接口,并通过 ARouter 注册(`@Route(path = "/share/callback")`) - `ShareServiceFactory` 已创建,内部使用 ARouter 获取服务 - `IShareService` 接口已在 `base-core` 模块定义 - `IShareCallback` 接口已在 `base-core` 模块定义 - `WXEntryActivity` 已移至 `base-core` 模块,通过 ARouter 注入回调实现 - **ARouter 集成完成**:模块间解耦,通过 ARouter 进行依赖注入 ## 需要您配置的内容 ### 1. 在友盟官网注册应用 1. 访问 [友盟+官网](https://www.umeng.com/) 2. 注册账号并创建应用 3. 获取 **AppKey** 和 **AppSecret** ### 2. 配置第三方平台 #### 2.1 微信平台配置 1. 访问 [微信开放平台](https://open.weixin.qq.com/) 2. 创建移动应用,获取 **AppID** 和 **AppSecret** #### 2.2 QQ平台配置 1. 访问 [QQ开放平台](https://open.qq.com/) 2. 创建移动应用,获取 **AppID** 和 **AppKey** #### 2.3 新浪微博配置 1. 访问 [新浪微博开放平台](https://open.weibo.com/) 2. 创建移动应用,获取 **AppKey** 和 **AppSecret** ### 3. 配置 AndroidManifest.xml **注意**:权限声明和回调 Activity 配置已在各模块的 `AndroidManifest.xml` 中完成,`app` 模块无需配置。 - ✅ **权限声明**:已在 `capability-share/src/main/AndroidManifest.xml` 中配置 - ✅ **回调 Activity**: - `WXEntryActivity` 已在 `base-core/src/main/AndroidManifest.xml` 中配置 - `AuthActivity`(QQ)、`WBShareTransActivity`(微博)已在 `capability-share/src/main/AndroidManifest.xml` 中配置 - ✅ **ARouter 初始化**:已在 `XinDaZhouApplication` 中完成(见步骤5) **说明**: - ✅ 所有配置都在各模块内部管理,`app` 模块无需配置 - ✅ AppKey 和平台配置通过代码完成(见步骤4),更灵活 ### 4. 配置资源文件(推荐方式) **注意**:配置位置已改为 `capability-share/src/main/res/values/strings.xml`,`app` 模块无需配置。 在 `capability-share/src/main/res/values/strings.xml` 中配置分享参数(**推荐方式,配置统一管理**): ```xml 您的友盟 AppKey developer-default 您的微信 AppID 您的微信 AppSecret 您的QQ AppID 您的QQ AppKey tencent您的QQ AppID 您的新浪微博 AppKey 您的新浪微博 AppSecret 您的新浪微博回调地址 ``` ### 5. 在 Application 中初始化(统一入口) 在您的 `XinDaZhouApplication` 类中初始化分享服务: ```kotlin // app/src/main/java/com/narutohuo/xindazhou/XinDaZhouApplication.kt package com.narutohuo.xindazhou import android.app.Application import com.alibaba.android.arouter.launcher.ARouter import com.narutohuo.xindazhou.share.factory.ShareServiceFactory class XinDaZhouApplication : Application() { override fun onCreate() { super.onCreate() // ========== 初始化 ARouter(必须在其他初始化之前)========== if (BuildConfig.DEBUG) { ARouter.openLog() ARouter.openDebug() } ARouter.init(this) // ========== 初始化分享服务(从资源文件读取配置)========== try { ShareServiceFactory.init(context = this) } catch (e: Exception) { // 分享服务初始化失败不影响应用运行,但分享功能将不可用 android.util.Log.e("XinDaZhouApplication", "分享服务初始化失败", e) } } } ``` **优势**: - ✅ **最简单**:只需一行代码,配置都在资源文件中 - ✅ **统一入口**:通过 `ShareServiceFactory.init()` 统一初始化,代码更清晰 - ✅ **ARouter 解耦**:通过 ARouter 实现模块间解耦,base-core 与 share 模块完全解耦 - ✅ 业务层不直接依赖友盟API - ✅ 如果更换SDK,只需修改实现层,业务层无需改动 - ✅ 配置统一管理,代码更清晰 ### 6. 使用分享功能(完全封装,无需处理回调) **重要更新**:分享功能已完全封装,业务层**不需要**在 `MainActivity` 中处理 `onActivityResult`! 分享组件内部使用透明代理 Activity 自动处理所有回调,业务层只需要调用 `share()` 方法即可: ```kotlin // app/src/main/java/com/narutohuo/xindazhou/user/ui/profile/UserFragment.kt class UserFragment : Fragment() { private val shareService = ShareServiceFactory.getInstance() private fun shareContent() { val content = ShareContent.builder() .setTitle("分享标题") .setDescription("分享描述") .setUrl("https://example.com") .build() // 直接调用 share() 方法,自动处理所有回调 shareService.share(requireActivity(), content) { response -> if (response.success) { Toast.makeText(requireContext(), "分享成功", Toast.LENGTH_SHORT).show() } } } } ``` **说明**: - ✅ **完全封装**:业务层不需要处理 `onActivityResult`,所有回调都在组件内部处理 - ✅ **使用简单**:只需调用 `share()` 方法,传入分享内容和回调即可 - ✅ **透明代理**:组件内部使用透明 Activity 处理回调,用户看不到 - ✅ **自动关闭**:分享完成后,透明 Activity 自动关闭,回到原界面 ## 支持的分享平台 ### 已完整支持(通过友盟SDK) - ✅ **微信** - `shareToWeChat()` - ✅ **微信朋友圈** - `shareToWeChatMoments()` - ✅ **QQ** - `shareToQQ()` - ✅ **QQ空间** - `shareToQZone()` - ✅ **新浪微博** - `shareToWeibo()` ### 部分支持(待实现) - ⚠️ **抖音** - `shareToDouyin()` - 待实现 - ⚠️ **小红书** - `shareToXiaohongshu()` - 待实现 - ⚠️ **快手** - `shareToKuaishou()` - 待实现 - ✅ **系统分享** - `shareToSystem()` - 调用系统分享菜单 ## 使用示例 ### 在 Fragment 中使用分享(实际项目示例) 分享功能在 Fragment 中使用: ```kotlin // app/src/main/java/com/narutohuo/xindazhou/user/ui/profile/UserFragment.kt package com.narutohuo.xindazhou.user.ui.profile import android.view.View import android.widget.Button import android.widget.Toast import androidx.fragment.app.Fragment import com.narutohuo.xindazhou.R import com.narutohuo.xindazhou.share.factory.ShareServiceFactory import com.narutohuo.xindazhou.share.model.ShareContent import com.narutohuo.xindazhou.share.model.ShareResponse import timber.log.Timber class UserFragment : Fragment() { // 获取分享服务实例(单例) private val shareService = ShareServiceFactory.getInstance() override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 示例:分享按钮点击 view.findViewById