Android - DeepLink的应用及原理

278 阅读2分钟

DeepLink的基本内容

1. 基本概念:

// DeepLink就像是应用的"门牌号码"
// 允许从外部直接跳转到应用的指定页面

生活比喻:

想象你去一个大商场:

普通启动:
从商场大门进入 -> 查看导航 -> 找到目标店铺

DeepLink:
直接从商场指定入口进入目标店铺

2. 基本使用:

<!-- AndroidManifest.xml -->
<activity android:name=".ProductActivity">
    <intent-filter>
        <!-- 方式一:网页链接 -->
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data 
            android:scheme="https"           <!-- 协议 -->
            android:host="example.com"       <!-- 域名 -->
            android:pathPrefix="/product" /> <!-- 路径 -->
            
        <!-- 方式二:自定义协议 -->
        <data 
            android:scheme="myapp"          <!-- 自定义协议 -->
            android:host="product"          <!-- 页面类型 -->
            android:pathPrefix="/detail" /> <!-- 具体路径 -->
    </intent-filter>
</activity>
// 方式一:网页链接
https://example.com/product?id=123
// 方式二:自定义协议
myapp://product/detail?id=123

class ProductActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // 获取跳转参数
        intent?.data?.let { uri ->
            // 解析参数
            val productId = uri.getQueryParameter("id")
            val source = uri.getQueryParameter("source")
            
            when (uri.host) {
                "product" -> showProduct(productId)
                "cart" -> showCart()
                "order" -> showOrder(orderId)
            }
        }
    }
}

3. 常见使用场景:

推送跳转:

// 收到推送消息,直接打开指定商品页面
class PushReceiver {
    fun onReceive(context: Context, intent: Intent) {
        // myapp://product/detail?id=123
        val deepLink = intent.getStringExtra("deep_link")
        context.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(deepLink)))
    }
}

分享链接:

// 分享商品链接给好友
class ShareManager {
    fun shareProduct(product: Product) {
        val deepLink = "https://example.com/product/${product.id}"
        val intent = Intent().apply {
            action = Intent.ACTION_SEND
            putExtra(Intent.EXTRA_TEXT, deepLink)
            type = "text/plain"
        }
        startActivity(Intent.createChooser(intent, "分享商品"))
    }
}

4. 实际应用示例:

电商应用:

// 1. 商品详情页
myapp://product/detail?id=123

// 2. 购物车页面
myapp://cart

// 3. 订单详情页
myapp://order/detail?orderId=456

社交应用:

// 1. 用户主页
myapp://user/profile?uid=789

// 2. 具体帖子
myapp://post/detail?pid=101

// 3. 聊天页面
myapp://chat?targetUid=202
// 1. 推送消息跳转
val notification = NotificationCompat.Builder(context, channelId)
    .setContentIntent(
        PendingIntent.getActivity(
            context,
            0,
            Intent(Intent.ACTION_VIEW, 
                Uri.parse("myapp://product/detail?id=123")
            ),
            PendingIntent.FLAG_UPDATE_CURRENT
        )
    )

// 2. 分享商品链接
val shareIntent = Intent().apply {
    action = Intent.ACTION_SEND
    putExtra(Intent.EXTRA_TEXT, 
        "https://example.com/product?id=123")
    type = "text/plain"
}

// 3. 扫码跳转
fun onQrCodeScanned(qrCode: String) {
    if (qrCode.startsWith("myapp://")) {
        startActivity(Intent(Intent.ACTION_VIEW, 
            Uri.parse(qrCode)))
    }
}

5. 处理DeepLink:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        // 处理DeepLink
        intent?.data?.let { uri ->
            when {
                uri.host == "product" -> {
                    // 获取商品ID
                    val productId = uri.getQueryParameter("id")
                    navigateToProduct(productId)
                }
                uri.host == "order" -> {
                    val orderId = uri.getQueryParameter("orderId")
                    navigateToOrder(orderId)
                }
            }
        }
    }
}

6. 最佳实践:

统一路由管理:

object Router {
    // 生成DeepLink
    fun generateDeepLink(route: String, params: Map<String, String>): String {
        return buildString {
            append("myapp://")
            append(route)
            if (params.isNotEmpty()) {
                append("?")
                params.forEach { (key, value) ->
                    append("$key=$value&")
                }
            }
        }
    }
    
    // 处理DeepLink
    fun handleDeepLink(uri: Uri) {
        val route = uri.host
        val params = uri.queryParameterNames.associateWith { 
            uri.getQueryParameter(it) 
        }
        navigate(route, params)
    }
}
object DeepLinkRouter {
    private val routes = mapOf(
        "product" to ProductActivity::class.java,
        "cart" to CartActivity::class.java,
        "order" to OrderActivity::class.java
    )
    
    fun navigate(uri: Uri) {
        val host = uri.host
        val targetClass = routes[host] ?: return
        
        val intent = Intent(context, targetClass).apply {
            data = uri  // 传递所有参数
        }
        startActivity(intent)
    }
}

7. 安全考虑:

class DeepLinkValidator {
    fun validate(uri: Uri): Boolean {
        // 1. 检查域名白名单
        if (!isValidHost(uri.host)) return false
        
        // 2. 检查参数合法性
        if (!validateParams(uri.queryParameterNames)) return false
        
        // 3. 检查用户登录状态
        if (needLogin(uri.path) && !isUserLoggedIn()) return false
        
        return true
    }
}

生活场景对比:

没有DeepLink:
1. 打开商场
2. 查找商铺位置
3. 步行到达
4. 进入商铺

有DeepLink:
1. 扫码/点击链接
2. 直接进入目标商铺

DeepLink就像是应用的"快捷通道",让用户能够:

  1. 从外部直接进入应用指定页面
  2. 分享应用内容给其他用户
  3. 通过推送直接打开特定页面
  4. 提供更好的用户体验