在开发上述功能的过程中,发现了 flipper 这个工具
flipper 提供了一个桌面客户端,然后这个桌面客户端提供了一个和手机客户端通信的机制,免去了 socket 服务的开销,依靠这个通信机制,我们可以把上述的功能复制过来
基于这个通信机制把 api 名称和 api 参数传到手机客户端上,然后再在客户端里注入的 js 调用相应的 api,无需再维护 socket 服务
###使用 flipper
希望全面了解 flipper 的可以上 https://fbflipper.com/
具体文档查看:flipper 文档
工程中就基于 flipper 开发了一个 api 调试的功能,以及获取当前 Hybrid 页面的客户端数据,下面有一个简单的示例,简单介绍一下接入流程和开发一个插件
###桌面插件
需要有简单 React 组件开发经验,不会的话,照葫芦画瓢 10 分钟也能搞定。
桌面插件是一个 React 组件,用来描述界面,接受发送数据
#####0.前置条件
下载 Node,Yarn
Node.js
Yarn
#####1.创建工程
创建目录,执行 yarn init,目录下会出现一个文件 package.json 注意 name得以 flipper-plugin- 开头
{
“name”: “flipper-plugin-myplugin”,
“version”: “1.0.0”,
“main”: “index.js”,
“license”: “MIT”,
“dependencies”: {}
}
#####2.开始编程
创建 index.js,在 index.js 里面可以编写自己的插件,一个简单的组件可能是这样。
这个插件有三个要注意的点
id 为 “myplugin”,id 很重要,桌面插件和客户端插件 id 一样的话才能发生通信
订阅了客户端 “clientMessage” 的消息
给客户端发送了 “getData” 的消息(稍后会在客户端中接收这个消息)
import {FlipperPlugin, Button, FlexCenter} from ‘flipper’;
export default class extends FlipperPlugin {
static title = ‘
My Plugin’;
static id = ‘myplugin’;
static icon = ‘internet’;
constructor(props) {
super(props);
this.init();
}
init(){
this.state = {
data: ‘null’,
message: ‘null’
};
//订阅客户端发送的数据
this.client.subscribe(‘clientMessage’, res => {
if(res){
this.setState({message:res.message});
}
});
}
sendData(){
//给客户端发消息
this.client.call(‘getData’, {request:“”}).then(res => {
this.setState({data:res.data});
});
}
render() {
const {data, message} = this.state;
return (
点我调用 getData
{'getData 的内容是:' + data}
{'clientMessage 的内容是:' + message}
) } }const mainStyle = {
“margin-top”:60,
“flex-direction”:“column”
}
const commonStyle = {
margin: 20,
};
#####3.加载插件
我编写完桌面插件之后,按照 flipper 提示的方式进行配置,还是无法动态加载我写的插件,最后我是把 flipper 的源码拉下来,将插件工程放到了
flipper/src/plugins/ 文件夹下面,然后执行 yarn build --version --mac 在 dist 文件夹下直接打出包,再使用的。
我不确实这是我的问题还是 flipper 的问题。
这是成功加载起插件的图例,假如没有写对应手机客户端插件的话,是不会显示我们写好的 MyPlugin,所以接下来介绍怎么写一个对应的手机客户端插件
###客户端插件
#####0.依赖
当大家想接入一个 debug 相关的库的时候,可能会考虑说,不想把 debug 的功能带到线上去,有几种做法,大家自行选用
a.在代码中去判断一下,在恰当的时候,把 debug 相关的功能给关掉
好处是做起来很简单轻松
坏处是会在线上引入一个线上根本不需要的库,增大了包体积
b.在非线上的时候引入正式库,在线上包中引入 ‘no-op’ 库,‘no-op’ 库可以理解为正式库的一个空实现, 这里有一个讨论 关于 no-op 的讨论
好处是不会增大太多包体积,虽然还是要引入一个不必要的包
不好的地方可能就是如果官方没有实现 no-op 的库,就需要你自己写
例如:
debugImplementation ‘com.facebook.stetho:stetho-okhttp3:1.5.0’
releaseImplementation ‘com.zhihu.android.library:stetho-no-op:1.0.0’
这种方式似乎也是很多类似库通用的处理方式
c.第三种,新建一个文件夹,比如 flipper,在里面写相关初始化代码,通过某种方式执行这些代码,然后再在 sourceSets 加上 srcDirs 即可 下面的意思是在 mr 或者 debug 包中才加上 srcDirs
dependencies {
…
debugImplementation ‘com.facebook.flipper🐬0.11.1’
mrImplementation ‘com.facebook.flipper🐬0.11.1’
}
android {
sourceSets {
…
debug {
java.srcDirs += “src/flipper/java”;
}
mr {//
java.srcDirs += “src/flipper/java”;
}
}
####1.初始化
/** 官方示例 */
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, false);
/** 这里是 flipper 官方的示例代码,实际上在我们的工程中不是这么做的,实际工程中使用了上面依赖方式的第三种 */
if (BuildConfig.DEBUG && FlipperUtils.shouldEnableFlipper(this)) {
final FlipperClient client = AndroidFlipperClient.getInstance(this);
client.addPlugin(new InspectorFlipperPlugin(this, DescriptorMapping.withDefaults()));
client.addPlugin(new MyFlipperPlugin());
client.start();
}
}
}
/**
* 我们的方式,示例代码,下面精简了一点
*(我们的工程里有一个 Task,在编译 app 时 gradle 插件会自动定位到所有的 Task,并运行时生成依赖图,按依赖顺序启动 Task)
*/
public class FlipperTask extends Task{
public FlipperTask(String name) {
super(name);
}
@Override
public void afterSetup() {
setScheduler(AndroidSchedulers.mainThread());
beFinalizedBy(“Task1”);
}
@Override
public void onRun() {
final Application app = (Application) getInput(“app”);
SoLoader.init(app, false);
FlipperClient client = AndroidFlipperClient.getInstance(app);
if (client != null){
client.addPlugin(new InspectorFlipperPlugin(app, DescriptorMapping.withDefaults()));
client.addPlugin(new MyFlipperPlugin());
client.start();
}
}
}
#####2.编写插件
注意
id 要和桌面插件一致
同时实现了 “getData” 的接收,和 “clientMessage” 的发送
public class MyFlipperPlugin implements FlipperPlugin { ¨K7K }
这样一个简单的插件就写完了,赶紧跑起来试用一下吧!
###手机客户端:
###桌面客户端:
最后,通过这一个简单的 demo,我们把传递的参数改成 ’ Hybrid 接口’ 和 ’ Hybrid 接口的参数’,指示客户端进行的接口调用,复制出远程调用的功能就可以了。
###总结
最终,基于方便的日志查看,基于 flipper 开发的各类插件,比如远程调用 Hybrid 接口,获取当前 Hybrid 数据等等,可以在短时间之内提供一个较好的调试和测试体验。
让测试不需要了解开发细节,客户端开发能独立测试,前端能快速自己确定问题,降低开发中联调的耦合程度。
现在很多公司都会有许多 Hybrid 页面,如何低成本的调试一直是一个问题,大家好什么好的想法也可以一起交流。
###最后
针对Android程序员,我这边给大家整理了一些资料,包括不限于高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter等全方面的Android进阶实践技术;希望能帮助到大家,也节省大家在网上搜索资料的时间来学习,也可以分享动态给身边好友一起学习!
最后
小编这些年深知大多数初中级Android工程师,想要提升自己,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
资料⬅专栏获取
自学效果低效漫长且无助**。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
[外链图片转存中…(img-KlhF4xfy-1719113594258)]一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人
都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
资料⬅专栏获取