嘿,兄弟!移动端调试工具Flipper了解一下

什么是Flipper

Flipper是facebook开源的一个面向移动端(Android/iOS)开发者的桌面调试平台。

开源地址: https://github.com/facebook/flipper

官网地址: https://fbflipper.com/

它分为两个部分

  • macOS的桌面应用程序(目前仅支持macOS)
  • Android和iOS的原生SDK

桌面部分

可以在github下载最新版,当我们在Android或iOS应用中集成好SDK之后,打开桌面应用,可以看到如下窗口,目前它有几个内置的插件,分别是:

  • Logs
  • Layout Inspector
  • Network
  • Sandbox
  • Shared Preferences
  • LeakCanary
  • Crash Reporter Plugin

flipper-1.png

注意:除了内置的插件之外,也可以自己开发插件,实现定制的功能

Android SDK集成

0、添加依赖

1
2
3
4
5
6
7
debugImplementation 'com.facebook.flipper:flipper:0.14.1'
debugImplementation 'com.facebook.soloader:soloader:0.5.1'

debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.6.1'
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.6.1'

implementation 'com.squareup.okhttp3:okhttp:3.6.0'

1、添加权限

1
2
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

2、启用插件

其中Log默认是打开的无需添加,其他需要通过代码来启用,关键代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
...
SoLoader.init(this, false);

final FlipperClient client = AndroidFlipperClient.getInstance(this);

//Network插件
final NetworkFlipperPlugin networkPlugin = new NetworkFlipperPlugin();
final FlipperOkhttpInterceptor interceptor = new FlipperOkhttpInterceptor(networkPlugin);
client.addPlugin(networkPlugin);

//Inspector插件
client.addPlugin(new InspectorFlipperPlugin(this, DescriptorMapping.withDefaults()));

//Sandbox插件
client.addPlugin(new SandboxFlipperPlugin(new SandboxFlipperPluginStrategy() {
@Nullable
@Override
public Map<String, String> getKnownSandboxes() {
Map map = new HashMap();
return map;
}

@Override
public void setSandbox(@Nullable String sandbox) {

}
}));

//SP插件
client.addPlugin(new SharedPreferencesFlipperPlugin(this, "flipper_shared_preference"));

//LeakCanary插件
client.addPlugin(new LeakCanaryFlipperPlugin());

//CrashReporter插件
client.addPlugin(CrashReporterPlugin.getInstance());

client.start();
...

使用效果

Logs

Logs和Android Studio的logcat类似,可以显示log的不同级别及过滤。

flipper-2.png

Network

当发起一个网络请求(目前仅支持OkHttp库发起的请求),可以在Network标签下看到详细的网络请求情况。包括request和response。在使用中发现,response在中文解码支持不好,会有乱码。

flipper-network.png

Layout

可以在Layout标签下看到Activity布局。有一个好处是,当修改View的样式或者文字等其他属性时,可以实时反馈到手机或模拟器上。

flipper-layout.png

Shared Preferences

在Shared Preferences标签下,可以显示sp文件的keyvalue,并且在此修改的值也可以实时在手机或模拟器上修改。

flipper-4.png

LeakCanary

经测试,这部分功能不是很稳定,内存泄漏信息不能完整显示。

flipper-leak.png

关于Sandbox和CrashReporter,目前文档上的使用不是特别明确,不在演示。

结论

Flipper截止目前(2019-01-18)最新的版本是v0.14.1,开源的时间也没多久,有一些功能和文档还不是特别完善,比如有一些功能仅支持Android或者仅支持iOS,但是仓库的更新非常频繁,并且支持开发者自己开发插件。我们一起期待Flipper越来越好用。

作者博客: https://democome.com

演示demo: https://github.com/77Y/FlipperSample

补充

iOS Objective-c集成指南

初始化Podfile

相比于Android,iOS集成相对简单一些。可以使用CocoaPods。新建项目,然后pod init初始化Podfile文件,并添加Flipper的依赖,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
project 'democome.xcodeproj'
source 'https://github.com/facebook/flipper.git'
source 'https://github.com/CocoaPods/Specs'
swift_version = "4.1"
flipperkit_version = '0.14.1'

target 'democome' do
platform :ios, '9.0'

pod 'FlipperKit', '~>' + flipperkit_version
pod 'FlipperKit/FlipperKitLayoutComponentKitSupport', '~>' + flipperkit_version
pod 'FlipperKit/SKIOSNetworkPlugin', '~>' + flipperkit_version
pod 'FlipperKit/FlipperKitUserDefaultsPlugin', '~>' + flipperkit_version
# This post_install script adds swift version to yogakit's pod target.
# It also adds -DFB_SONARKIT_ENABLED=1 flag to OTHER_CFLAGS, necessary to build expose Flipper classes in the header files
post_install do |installer|
installer.pods_project.targets.each do |target|
if ['YogaKit'].include? target.name
target.build_configurations.each do |config|
config.build_settings['SWIFT_VERSION'] = swift_version
end
end
end
file_name = Dir.glob("*.xcodeproj")[0]
app_project = Xcodeproj::Project.open(file_name)
app_project.native_targets.each do |target|
target.build_configurations.each do |config|
if (config.build_settings['OTHER_CFLAGS'])
if !(config.build_settings['OTHER_CFLAGS'].include? '-DFB_SONARKIT_ENABLED=1')
puts 'Adding -DFB_SONARKIT_ENABLED=1 in OTHER_CFLAGS...'
config.build_settings['OTHER_CFLAGS'] << '-DFB_SONARKIT_ENABLED=1'
end
else
puts 'OTHER_CFLAGS does not exist, assigining it to `$(inherited), -DFB_SONARKIT_ENABLED=1` '
config.build_settings['OTHER_CFLAGS'] = '$(inherited) -DFB_SONARKIT_ENABLED=1 '
end
app_project.save
end
end
end
end

AppDelegate添加如下代码

1
2
3
4
5
6
7
8
9
FlipperClient *client = [FlipperClient sharedClient];
SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults];
[FlipperKitLayoutComponentKitSupport setUpWithDescriptorMapper: layoutDescriptorMapper];
[client addPlugin: [[FlipperKitLayoutPlugin alloc] initWithRootNode: application
withDescriptorMapper: layoutDescriptorMapper]];

[client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]]; [client start];
[client addPlugin: [[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]];
[client start];

运行效果如下
flipper-oc.png

iOS Swift集成指南

初始化Podfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
project 'democome-swift.xcodeproj'
source 'https://github.com/facebook/flipper.git'
source 'https://github.com/CocoaPods/Specs'
swift_version = "4.2.1"
flipperkit_version = '0.14.1'

target 'democome-swift' do
platform :ios, '9.0'

pod 'FlipperKit', '~>' + flipperkit_version
# Layout and network plugins are not yet supported for swift projects
pod 'FlipperKit/FlipperKitLayoutComponentKitSupport', '~>' + flipperkit_version
pod 'FlipperKit/SKIOSNetworkPlugin', '~>' + flipperkit_version
pod 'FlipperKit/FlipperKitUserDefaultsPlugin', '~>' + flipperkit_version

# If you use `use_frameworks!` in your Podfile,
# uncomment the below $static_framework array and also
# the pre_install section. This will cause Flipper and
# it's dependencies to be static and all other pods to
# be dynamic.

# $static_framework = ['FlipperKit', 'Flipper', 'Folly',
# 'CocoaAsyncSocket', 'ComponentKit', 'DoubleConversion',
# 'glog', 'PeerTalk', 'RSocket', 'Yoga', 'YogaKit',
# 'CocoaLibEvent', 'OpenSSL-Static', 'boost-for-react-native']

# pre_install do |installer|
# installer.pod_targets.each do |pod|
# if $static_framework.include?(pod.name)
# pod.host_requires_frameworks = false
# end
# end
# end

# This post_install script adds -DFB_SONARKIT_ENABLED flag to OTHER_SWIFT_FLAGS, necessary to build swift target
post_install do |installer|
file_name = Dir.glob("*.xcodeproj")[0]
app_project = Xcodeproj::Project.open(file_name)
app_project.native_targets.each do |target|
target.build_configurations.each do |config|
if (config.build_settings['OTHER_SWIFT_FLAGS'])
if !(config.build_settings['OTHER_SWIFT_FLAGS'].include? '-DFB_SONARKIT_ENABLED')
puts 'Adding -DFB_SONARKIT_ENABLED ...'
swift_flags = config.build_settings['OTHER_SWIFT_FLAGS']
if swift_flags.split.last != '-Xcc'
config.build_settings['OTHER_SWIFT_FLAGS'] << ' -Xcc'
end
config.build_settings['OTHER_SWIFT_FLAGS'] << ' -DFB_SONARKIT_ENABLED'
end
else
puts 'OTHER_SWIFT_FLAGS does not exist thus assigning it to `$(inherited) -Xcc -DFB_SONARKIT_ENABLED`'
config.build_settings['OTHER_SWIFT_FLAGS'] = '$(inherited) -Xcc -DFB_SONARKIT_ENABLED'
end
app_project.save
end
end
end
end

这里需要注意Swift版本,需要和你安装的版本保持一致,否则可能会报错,查看Swift版本命令如下:

1
xcrun swift -version

AppDelegate添加如下代码

1
2
3
4
5
let client = FlipperClient.shared()
let layoutDescriptorMapper = SKDescriptorMapper(defaults: ())
FlipperKitLayoutComponentKitSupport.setUpWith(layoutDescriptorMapper)
client?.add(FlipperKitLayoutPlugin(rootNode: application, with: layoutDescriptorMapper!))
client?.start()

运行结果类似,不在贴出。