# 友盟分享集成说明
## 目录结构
```
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