最新Android 上玩转 DeepLink:如何最大程度的向 App 引流,2024年最新字节跳动 社招 面经

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上我搜集整理的2019-2021BATJ 面试真题解析,我把大厂面试中常被问到的技术点整理成了PDF,包知识脉络 + 诸多细节。

节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

《960全网最全Android开发笔记》

《379页Android开发面试宝典》

历时半年,我们整理了这份市面上最全面的安卓面试题解析大全
包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。

如何使用它?

1.可以通过目录索引直接翻看需要的知识点,查漏补缺。
2.五角星数表示面试问到的频率,代表重要推荐指数

《507页Android开发相关源码解析》

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

腾讯、字节跳动、阿里、百度等BAT大厂 2019-2021面试真题解析

资料太多,全部展示会影响篇幅,暂时就先列举这些部分截图

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  1. 管理 URL 路径和 Activity 的对应关系。

为了统一入口,我们创建一个入口 Activity: RouterActivty,它用来向系统声明 App 能 打开哪些链接,同时接受外界传递过来的 URL。首先我们在 Manifest 里声明它:









上面的声明表示,RouterActivty 可以打开所有域名为news.zhoulujue.com 的 https/http 链接。 这个 RouterActivty 在收到 news.zhoulujue.com/article/123… 后,需要 负责将 /article/123456/ 解析出来,根据 对应关系 找到ArticleActivity,唤起它并且 把123456这个 id 作为参数传递给ArticleActivity

常见的 Router 框架通过在 Activity 的类名上添加注解来管理对应关系:

@Route(path = “/acticel/”)
public class ArticleActivity extend Activity {

}

实际上它在处理这个注解的时候生成了一个建造者模式里的 builder,然后向 管理中心 注册,说 自己(ArticleActivity)能处理/acticel/xxx的子域名。

Scheme 的选择很重要:URL Scheme 唤醒

上面简述原理的时候说道了 Manifest 的声明,我们只声明了 android:scheme="http"android:scheme="http" , 但是实际上很多 App 还会用特定 scheme 的方式来唤起 App,例如在 iOS 早期没有 UniversalLink 的时候,大家这样来唤起。

像淘宝就会用 tbopen的 scheme,例如 tbopen://item.taobao.com/item.htm?id=xxxx,当你在网页点击链接以后,页面会创建一个隐藏的 iframe,用它来打开自定义 scheme 的 URL,浏览器无法响应时,向系统发送一个 Action 为 android.intent.action.VIEW、Data 为 tbopen://item.taobao.com/item.htm?id=xxxx 的 Intent,如果 App 已经按照上述章节改造,那么系统将唤起 RouterActivity 并将 Intent 传递过去。

所以问题就来了:如何选取一个 URL Scheme 使得“浏览器无法响应”,所以你的scheme 最好满足以下两个条件:

  1. 区别于其他应用:唯一性
  2. 区别于浏览器已经能处理的 scheme:特殊性

在我们上述假设的新闻 App 里,我们可以定义 scheme 为 zljnews,那么在 URL Scheme 发送的 URL 将会是这样:

指向id=123456的新闻详情页:zljnews://news.zhoulujue.com/article/123456/
指向id=123457的新闻专题页:zljnews://news.zhoulujue.com/story/123457/
指向id=123456的新闻讨论页:zljnews://news.zhoulujue.com/article/123456/comments/

为了避免某些应用会预处理 scheme 和 host,我们还需要将 URL Scheme 的 Host 也做相应 更改:

指向id=123456的新闻详情页:zljnews://zljnews/article/123456/
指向id=123457的新闻专题页:zljnews://zljnews/story/123457/
指向id=123456的新闻讨论页:zljnews://zljnews/article/123456/comments/

这样的我们的 Manifest 里 RouterActivity 的声明要改为:

















App Links 与 Universal Links,来自官方的方式

我们假设一个用例:用户在印象笔记里写了一篇笔记,笔记里有一个链接: http://news.zhoulujue.com/article/123456/。 那么问题来了:用户点击以后,将会发生什么?

答案是:很大的可能是系统弹出一个对话框,列出若干个 App,问你想用哪一个打开。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这样体验其实不够好,因为用户路径变长了,转化率 将下降。所以我们应该尽可能去掉这个 对话框,其实上述章节说到了一个方法:将 http://news.zhoulujue.com/article/123456/ 改为 zljnews://zljnews/article/123456/,原理是我们选取了看起来"唯一性"的 scheme, 但是如果用户没有安装你的 App,这个体验就相当糟糕了,用户在点击以后将没有任何反应。

此时就需要 AppLinks 和 UniversalLinks 了,一言以蔽之,就是域名持有者向系统证明自己 拥有 news.zhoulujue.com 这个域名并且 App 属于自己,这样系统就会直接将 App 唤起 并把 intent 传递给 App。

如何配置 AppLinks 就不在赘述了,参考官方的教程

App Links 实现的另一种方式

Facebook 在2014年的F8开发者大会上公布了 AppLinks 协议,在Android 的 AppLinks之前(Google I/O 15), 也是一种可行的“链接跳转 App”的方式。 这里也不在赘述细节,可以参考 Facebook 官方的介绍来实现,也特别简单:

Facebook AppLinks

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

非自己的代码怎么办

上面说了很多在网页中唤醒 App 的方式,但是这些都是建立在我们可以改页面 JS 等代码的前提下, 如果页面由第三方提供,举个例子,由广告主提供,表现方式是广告主提供一个落地页放在你的 App 里, 推动第三方去按照你的要求去改动他们的代码,可能比较困难,但是如果只是修改一下跳转链接就可以达到 唤起 App 的效果,这样性价比就比较高了。这个时候就需要 chrome 推荐的 intent scheme 了:

Intent scheme

如代码所示,scheme填写的是我们上面假设的 scheme:zljnews,保持一致。 package 填写 App 包名:com.zhoulujue.news,参考Chrome官方 Intent 编写规范

微信里怎么办

众所周知,微信是限制唤起 App 的行为的,坊间流传着各种微信唤起的 hack,但总是不知道什么时候就被封禁了,这里介绍 微信官方的 正规 搞法:微下载链接:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

如上图,知乎就使用了微下载来向知乎的 App 导流,这种方式 Android iOS 都是通用的,具体实现方式参考腾讯微信官方的文档

优化1:从网页到 App 的无缝体验

假设一个场景,用户访问 http://news.zhoulujue.com 阅读新闻时,被推荐下载了 App,此时安装完毕后打开 App后,最好 的体验当然是帮用户打开他没有看完新闻,直接跳转到刚刚在网页版阅读的文章。 最佳实践是:在用户点击下载时,把当前页面的 URL 写到 APK 文件的 ZIP 文件头里,待用户下载安装完毕后,启动时去读取这个 URL,然后结合上面说到过的 Router,路由到新闻详情页。下面跟我来一步一步实现吧。

在网页上下载APK时:将路径写如 APK 的 ZIP 文件头里

将下面的 Java 代码保存为 WriteAPK.java 并用 javac 编译好。

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.zip.ZipFile;

/**

  • Created by michael on 16/9/8.
    */
    public class WriteApk {

public static void main(String[] args) {
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}
if (args.length < 2) {
System.out.println(“Wrong parameters! Usage : WriteApk path comment\n”);
}
String path = args[0];
String comment = args[1];
writeApk(new File(path), comment);
System.out.println("Complete! File lies in " + path);
try {
ZipFile zipFile = new ZipFile(new File(path));
System.out.println("Zip file comment = " + zipFile.getComment());
} catch(IOException e) {
e.printStackTrace();
System.out.println(“Zip file comment read failed!”);
}
}

public static void writeApk(File file, String comment) {
ZipFile zipFile = null;
ByteArrayOutputStream outputStream = null;
RandomAccessFile accessFile = null;
try {
zipFile = new ZipFile(file);
String zipComment = zipFile.getComment();
if (zipComment != null) {
return;
}

byte[] byteComment = comment.getBytes();
outputStream = new ByteArrayOutputStream();

outputStream.write(byteComment);
outputStream.write(short2Stream((short) byteComment.length));

byte[] data = outputStream.toByteArray();

accessFile = new RandomAccessFile(file, “rw”);
accessFile.seek(file.length() - 2);
accessFile.write(short2Stream((short) data.length));
accessFile.write(data);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (zipFile != null) {
zipFile.close();
}
if (outputStream != null) {
outputStream.close();
}
if (accessFile != null) {
accessFile.close();
}
} catch (Exception e) {

}

}
}

/**

  • 字节数组转换成short(小端序)
Android开发除了flutter还有什么是必须掌握的吗?

相信大多数从事Android开发的朋友们越来越发现,找工作越来越难了,面试的要求越来越高了

除了基础扎实的java知识,数据结构算法,设计模式还要求会底层源码,NDK技术,性能调优,还有会些小程序和跨平台,比如说flutter,以思维脑图的方式展示在下图;

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

[外链图片转存中…(img-kH3ZSHFZ-1715363075737)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化学习资料的朋友,可以戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值