简世博客

一个简单的世界——博客空间,写了一些Android相关的技术文章,和一些点滴的想法

0%

万能json to code 在线工具

支持各种语言

最近找json to dart的时候发现的,试了其他工具,不好用,还有bug,这个就好多了。

https://app.quicktype.io/

android studio编译比命令行调用gradle编译快很多

从Android Studio 2.3版本之后,通过Android Studio打包普遍比通过命令行调用gradle编译要快很多。这是因为Android Studio增加了一项功能。通过Android Studio打包是,检测到连接的手机android本部大于21,就会关闭传统multidex方案,而使用速度快得多的新版多dex打包流程。

google原文如下:
https://developer.android.com/studio/build/optimize-your-build

1
2
3
4
// To avoid using legacy multidex when building from the command line,
// set minSdkVersion to 21 or higher. When using Android Studio 2.3 or higher,
// the build automatically avoids legacy multidex when deploying to a device running
// API level 21 or higher—regardless of what you set as your minSdkVersion.

传统multidex和新版多dex打包区别

传统multidex打包流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
app:kaptGenerateStubsDevDebugKotlin
app:kaptDevDebugKotlin
app:compileDevDebugKotlin
app:javaPreCompileDevDebug
app:compileDevDebugJavaWithJavac
app:compileDevDebugSources
app:transformClassesWithStackFramesFixerForDevDebug
app:transformClassesWithDesugarForDevDebug
app:transformClassesWithDexBuilderForDevDebug
app:transformClassesWithMultidexlistForDevDebug
app:transformDexArchiveWithDexMergerForDevDebug
app:transformNativeLibsWithMergeJniLibsForDevDebug
app:transformResourcesWithMergeJavaResForDevDebug
app:packageDevDebug
app:assembleDevDebug

新版多dex打包流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
:app:kaptGenerateStubsDevDebugKotlin
:app:kaptDevDebugKotlin
:app:compileDevDebugKotlin
:app:generateDevDebugSources
:app:javaPreCompileDevDebug
:app:compileDevDebugJavaWithJavac
:app:compileDevDebugSources
:app:transformClassesWithStackFramesFixerForDevDebug
:app:transformClassesWithDesugarForDevDebug
:app:transformClassesWithDexBuilderForDevDebug
:app:transformDexArchiveWithDexMergerForDevDebug
:app:transformNativeLibsWithMergeJniLibsForDevDebug
:app:transformResourcesWithMergeJavaResForDevDebug
:app:packageDevDebug
:app:assembleDevDebug

可以看出,传统multidex比新版多dex打包,多了一个transformClassesWithMultidexlist的任务,而这个任务耗费时间非常的长。
这就是导致命令行调用gradle命令编译比Android Studio慢的区别。

Android Studio 如何改变了打包流程

Android Studio是通过检测连接手机的参数,来向gradle注入相关属性来修改gradle编译方式。
我们可以在build.gradle中加入如下命令来查看Android Studio注入的属性:

1
println "projectProperties: " + project.gradle.startParameter.projectProperties

project.gradle.startParameter.projectProperties表示当前gradle启动时设置的属性。

我测试发现,注入的属性如下:

1
2
3
4
5
6
projectProperties: [
android.injected.build.density:xxhdpi,
android.injected.build.api:26,
android.injected.invoked.from.ide:true,
android.injected.build.abi:arm64-v8a,armeabi-v7a,armeabi
]

这几个属性:
android.injected.build.density 只打包对应density的资源,
android.injected.build.api 连接手机的android版本,就是这个属性使gradle采用新版多dex打包方案

让命令行调用gradle命令编译和Android Studio一样快

只要在原本的编译命令中加入-Pandroid.injected.build.api=26参数,即可在命令行中也采用新版多dex打包方案

1
./gradlew -Pandroid.injected.build.api=26 assembleDevDebug

我们开发中如果涉及到gradle的开发,经常需要查看各个task的输入输出。我在这里创建了一个空的android项目,然后遍历了它gradle编译时的所有task,并打印了其依赖和输入输出,方便查阅。

遍历的代码非常简单:

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

project.afterEvaluate(new Action<Project>() {
@Override
public void execute(Project project) {
Map<Project, Set<Task>> allTasks = project.getAllTasks(true);
for (Map.Entry<Project, Set<Task>> projectSetEntry : allTasks.entrySet()) {
Set<Task> value = projectSetEntry.getValue();
for (Task task : value) {
try {
System.out.println("----------------------------------");
System.out.println(task.getName());
for (Object o : task.getDependsOn()) {
System.out.println("dependOn--> " + o.toString());
}

for (File file : task.getInputs().getFiles().getFiles()) {
System.out.println("input--> " + file.getAbsolutePath());
}

for (File file : task.getOutputs().getFiles().getFiles()) {
System.out.println("output--> " + file.getAbsolutePath());
}
System.out.println("----------------------------------");
} catch (Exception e) {
e.printStackTrace()
}
}
}
}
});

下面是运行的结果,记录在这里,方便查阅。

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
----------------------------------
assemble
dependOn--> org.gradle.api.internal.artifacts.DefaultPublishArtifactSet$ArtifactsTaskDependency@6bf36307
dependOn--> assembleDebug
dependOn--> assembleRelease
----------------------------------
----------------------------------
assembleAndroidTest
dependOn--> assembleDebugAndroidTest
----------------------------------
----------------------------------
assembleDebug
dependOn--> packageDebug
dependOn--> compileDebugSources
----------------------------------
----------------------------------
assembleDebugAndroidTest
dependOn--> packageDebugAndroidTest
dependOn--> compileDebugAndroidTestSources
----------------------------------
----------------------------------
assembleDebugUnitTest
dependOn--> compileDebugUnitTestSources
dependOn--> mockableAndroidJar
----------------------------------
----------------------------------
assembleRelease
dependOn--> lintVitalRelease
dependOn--> packageRelease
dependOn--> compileReleaseSources
----------------------------------
----------------------------------
assembleReleaseUnitTest
dependOn--> compileReleaseUnitTestSources
dependOn--> mockableAndroidJar
----------------------------------
----------------------------------
build
dependOn--> check
dependOn--> assemble
----------------------------------
----------------------------------
buildDependents
dependOn--> build
----------------------------------
----------------------------------
buildNeeded
dependOn--> build
----------------------------------
----------------------------------
bundleAppClassesDebug
input--> /Users/username/project/testProject/app/build/tmp/bundleAppClassesDebug/MANIFEST.MF
output--> /Users/username/project/testProject/app/build/intermediates/classes-jar/debug/classes.jar
----------------------------------
----------------------------------
bundleAppClassesDebugAndroidTest
input--> /Users/username/project/testProject/app/build/tmp/bundleAppClassesDebugAndroidTest/MANIFEST.MF
output--> /Users/username/project/testProject/app/build/intermediates/classes-jar/androidTest/debug/classes.jar
----------------------------------
----------------------------------
bundleAppClassesDebugUnitTest
input--> /Users/username/project/testProject/app/build/tmp/bundleAppClassesDebugUnitTest/MANIFEST.MF
output--> /Users/username/project/testProject/app/build/intermediates/classes-jar/test/debug/classes.jar
----------------------------------
----------------------------------
bundleAppClassesRelease
input--> /Users/username/project/testProject/app/build/tmp/bundleAppClassesRelease/MANIFEST.MF
output--> /Users/username/project/testProject/app/build/intermediates/classes-jar/release/classes.jar
----------------------------------
----------------------------------
bundleAppClassesReleaseUnitTest
input--> /Users/username/project/testProject/app/build/tmp/bundleAppClassesReleaseUnitTest/MANIFEST.MF
output--> /Users/username/project/testProject/app/build/intermediates/classes-jar/test/release/classes.jar
----------------------------------
----------------------------------
check
dependOn--> lint
dependOn--> test
----------------------------------
----------------------------------
checkDebugManifest
dependOn--> preDebugBuild
output--> /Users/username/project/testProject/app/build/intermediates/check-manifest/debug
----------------------------------
----------------------------------
checkReleaseManifest
dependOn--> preReleaseBuild
output--> /Users/username/project/testProject/app/build/intermediates/check-manifest/release
----------------------------------
----------------------------------
clean
----------------------------------
----------------------------------
cleanBuildCache
----------------------------------
----------------------------------
compileDebugAidl
dependOn--> preDebugBuild
output--> /Users/username/project/testProject/app/build/intermediates/incremental/compileDebugAidl
output--> /Users/username/project/testProject/app/build/generated/source/aidl/debug
----------------------------------
----------------------------------
compileDebugAndroidTestAidl
dependOn--> preDebugAndroidTestBuild
output--> /Users/username/project/testProject/app/build/intermediates/incremental/compileDebugAndroidTestAidl
output--> /Users/username/project/testProject/app/build/generated/source/aidl/androidTest/debug
----------------------------------
----------------------------------
compileDebugAndroidTestJavaWithJavac
dependOn--> generateDebugAndroidTestSources
input--> /Users/username/project/testProject/app/build/intermediates/javaPrecompile/androidTest/debug/annotationProcessors.json
input--> /Users/username/project/testProject/app/build/intermediates/classes-jar/debug/classes.jar
input--> /Users/username/project/testProject/app/src/androidTest/java/com/example/myapplication/ExampleInstrumentedTest.java
input--> /Users/username/Library/Android/sdk/platforms/android-28/android.jar
output--> /Users/username/project/testProject/app/build/generated/source/apt/androidTest/debug
output--> /Users/username/project/testProject/app/build/intermediates/classes/androidTest/debug
----------------------------------
----------------------------------
compileDebugAndroidTestNdk
dependOn--> preDebugAndroidTestBuild
output--> /Users/username/project/testProject/app/build/intermediates/ndk/androidTest/debug/Android.mk
output--> /Users/username/project/testProject/app/build/intermediates/ndk/androidTest/debug/obj
output--> /Users/username/project/testProject/app/build/intermediates/ndk/androidTest/debug/lib
----------------------------------
----------------------------------
compileDebugAndroidTestRenderscript
dependOn--> processDebugAndroidTestManifest
output--> /Users/username/project/testProject/app/build/intermediates/rs/androidTest/debug/lib
output--> /Users/username/project/testProject/app/build/intermediates/rs/androidTest/debug/obj
output--> /Users/username/project/testProject/app/build/generated/res/rs/androidTest/debug
output--> /Users/username/project/testProject/app/build/generated/source/rs/androidTest/debug
----------------------------------
----------------------------------
compileDebugAndroidTestShaders
dependOn--> mergeDebugAndroidTestShaders
output--> /Users/username/project/testProject/app/build/generated/assets/shaders/androidTest/debug
----------------------------------
----------------------------------
compileDebugAndroidTestSources
dependOn--> compileDebugAndroidTestNdk
dependOn--> compileDebugAndroidTestJavaWithJavac
----------------------------------
----------------------------------
compileDebugJavaWithJavac
dependOn--> generateDebugSources
input--> /Users/username/project/testProject/app/build/intermediates/javaPrecompile/debug/annotationProcessors.json
input--> /Users/username/project/testProject/app/src/main/java/com/example/myapplication/FileUtils.java
input--> /Users/username/project/testProject/app/src/main/java/com/example/myapplication/MainActivity.java
input--> /Users/username/project/testProject/app/src/main/java/com/example/myapplication/AppDelegate.java
input--> /Users/username/project/testProject/app/src/main/java/com/example/myapplication/DebugLog.java
input--> /Users/username/project/testProject/app/src/main/java/com/example/dynamicCmd/CmdInvoker.java
input--> /Users/username/project/testProject/app/src/main/java/com/example/dynamicCmd/command/cmd.java
input--> /Users/username/project/testProject/app/src/main/java/com/example/dynamicCmd/DynamicCmdManager.java
input--> /Users/username/project/testProject/app/build/generated/source/r/debug/com/example/myapplication/R.java
input--> /Users/username/project/testProject/app/build/generated/source/buildConfig/debug/com/example/myapplication/BuildConfig.java
input--> /Users/username/Library/Android/sdk/platforms/android-28/android.jar
output--> /Users/username/project/testProject/app/build/generated/source/apt/debug
output--> /Users/username/project/testProject/app/build/intermediates/classes/debug
----------------------------------
----------------------------------
compileDebugNdk
dependOn--> preDebugBuild
output--> /Users/username/project/testProject/app/build/intermediates/ndk/debug/Android.mk
output--> /Users/username/project/testProject/app/build/intermediates/ndk/debug/obj
output--> /Users/username/project/testProject/app/build/intermediates/ndk/debug/lib
----------------------------------
----------------------------------
compileDebugRenderscript
dependOn--> preDebugBuild
output--> /Users/username/project/testProject/app/build/intermediates/rs/debug/lib
output--> /Users/username/project/testProject/app/build/intermediates/rs/debug/obj
output--> /Users/username/project/testProject/app/build/generated/res/rs/debug
output--> /Users/username/project/testProject/app/build/generated/source/rs/debug
----------------------------------
----------------------------------
compileDebugShaders
dependOn--> mergeDebugShaders
output--> /Users/username/project/testProject/app/build/generated/assets/shaders/debug
----------------------------------
----------------------------------
compileDebugSources
dependOn--> compileDebugNdk
dependOn--> compileDebugJavaWithJavac
----------------------------------
----------------------------------
compileDebugUnitTestJavaWithJavac
dependOn--> compileDebugJavaWithJavac
input--> /Users/username/project/testProject/app/build/intermediates/javaPrecompile/test/debug/annotationProcessors.json
input--> /Users/username/project/testProject/app/build/intermediates/classes/debug
input--> /Users/username/project/testProject/app/src/test/java/com/example/myapplication/ExampleUnitTest.java
input--> /Users/username/Library/Android/sdk/platforms/android-28/android.jar
output--> /Users/username/project/testProject/app/build/generated/source/apt/test/debug
output--> /Users/username/project/testProject/app/build/intermediates/classes/test/debug
----------------------------------
----------------------------------
compileDebugUnitTestSources
dependOn--> processDebugUnitTestJavaRes
dependOn--> compileDebugUnitTestJavaWithJavac
dependOn--> processDebugJavaRes
----------------------------------
----------------------------------
compileLint
output--> /Users/username/project/testProject/app/build/intermediates/lint
----------------------------------
----------------------------------
compileReleaseAidl
dependOn--> preReleaseBuild
output--> /Users/username/project/testProject/app/build/intermediates/incremental/compileReleaseAidl
output--> /Users/username/project/testProject/app/build/generated/source/aidl/release
----------------------------------
----------------------------------
compileReleaseJavaWithJavac
dependOn--> generateReleaseSources
input--> /Users/username/project/testProject/app/build/intermediates/javaPrecompile/release/annotationProcessors.json
input--> /Users/username/project/testProject/app/src/main/java/com/example/myapplication/FileUtils.java
input--> /Users/username/project/testProject/app/src/main/java/com/example/myapplication/MainActivity.java
input--> /Users/username/project/testProject/app/src/main/java/com/example/myapplication/AppDelegate.java
input--> /Users/username/project/testProject/app/src/main/java/com/example/myapplication/DebugLog.java
input--> /Users/username/project/testProject/app/src/main/java/com/example/dynamicCmd/CmdInvoker.java
input--> /Users/username/project/testProject/app/src/main/java/com/example/dynamicCmd/command/cmd.java
input--> /Users/username/project/testProject/app/src/main/java/com/example/dynamicCmd/DynamicCmdManager.java
input--> /Users/username/project/testProject/app/build/generated/source/r/release/com/example/myapplication/R.java
input--> /Users/username/project/testProject/app/build/generated/source/buildConfig/release/com/example/myapplication/BuildConfig.java
input--> /Users/username/Library/Android/sdk/platforms/android-28/android.jar
output--> /Users/username/project/testProject/app/build/generated/source/apt/release
output--> /Users/username/project/testProject/app/build/intermediates/classes/release
----------------------------------
----------------------------------
compileReleaseNdk
dependOn--> preReleaseBuild
output--> /Users/username/project/testProject/app/build/intermediates/ndk/release/Android.mk
output--> /Users/username/project/testProject/app/build/intermediates/ndk/release/obj
output--> /Users/username/project/testProject/app/build/intermediates/ndk/release/lib
----------------------------------
----------------------------------
compileReleaseRenderscript
dependOn--> preReleaseBuild
output--> /Users/username/project/testProject/app/build/intermediates/rs/release/lib
output--> /Users/username/project/testProject/app/build/intermediates/rs/release/obj
output--> /Users/username/project/testProject/app/build/generated/res/rs/release
output--> /Users/username/project/testProject/app/build/generated/source/rs/release
----------------------------------
----------------------------------
compileReleaseShaders
dependOn--> mergeReleaseShaders
output--> /Users/username/project/testProject/app/build/generated/assets/shaders/release
----------------------------------
----------------------------------
compileReleaseSources
dependOn--> compileReleaseNdk
dependOn--> compileReleaseJavaWithJavac
----------------------------------
----------------------------------
compileReleaseUnitTestJavaWithJavac
dependOn--> compileReleaseJavaWithJavac
input--> /Users/username/project/testProject/app/build/intermediates/javaPrecompile/test/release/annotationProcessors.json
input--> /Users/username/project/testProject/app/build/intermediates/classes/release
input--> /Users/username/project/testProject/app/src/test/java/com/example/myapplication/ExampleUnitTest.java
input--> /Users/username/Library/Android/sdk/platforms/android-28/android.jar
output--> /Users/username/project/testProject/app/build/generated/source/apt/test/release
output--> /Users/username/project/testProject/app/build/intermediates/classes/test/release
----------------------------------
----------------------------------
compileReleaseUnitTestSources
dependOn--> processReleaseUnitTestJavaRes
dependOn--> processReleaseJavaRes
dependOn--> compileReleaseUnitTestJavaWithJavac
----------------------------------
----------------------------------
connectedAndroidTest
dependOn--> connectedDebugAndroidTest
----------------------------------
----------------------------------
connectedCheck
dependOn--> connectedAndroidTest
----------------------------------
----------------------------------
connectedDebugAndroidTest
dependOn--> assembleDebug
dependOn--> assembleDebugAndroidTest
input--> /Users/username/Library/Android/sdk/build-tools/26.0.2/split-select
input--> /Users/username/project/testProject/app/build/outputs/apk/androidTest/debug
input--> /Users/username/project/testProject/app/build/outputs/apk/debug
output--> /Users/username/project/testProject/app/build/outputs/code-coverage/connected
----------------------------------
----------------------------------
consumeConfigAttr
----------------------------------
----------------------------------
createDebugCompatibleScreenManifests
output--> /Users/username/project/testProject/app/build/intermediates/manifests/density/debug
----------------------------------
----------------------------------
createReleaseCompatibleScreenManifests
output--> /Users/username/project/testProject/app/build/intermediates/manifests/density/release
----------------------------------
----------------------------------
deviceAndroidTest
----------------------------------
----------------------------------
deviceCheck
dependOn--> deviceAndroidTest
----------------------------------
----------------------------------
extractProguardFiles
dependOn--> preBuild
output--> /Users/username/project/testProject/build/intermediates/proguard-files/proguard-android-optimize.txt-3.0.1
output--> /Users/username/project/testProject/build/intermediates/proguard-files/proguard-defaults.txt-3.0.1
output--> /Users/username/project/testProject/build/intermediates/proguard-files/proguard-android.txt-3.0.1
----------------------------------
----------------------------------
generateDebugAndroidTestAssets
dependOn--> compileDebugAndroidTestShaders
----------------------------------
----------------------------------
generateDebugAndroidTestBuildConfig
dependOn--> processDebugAndroidTestManifest
output--> /Users/username/project/testProject/app/build/generated/source/buildConfig/androidTest/debug
----------------------------------
----------------------------------
generateDebugAndroidTestResValues
output--> /Users/username/project/testProject/app/build/generated/res/resValues/androidTest/debug
----------------------------------
----------------------------------
generateDebugAndroidTestResources
dependOn--> compileDebugAndroidTestRenderscript
dependOn--> generateDebugAndroidTestResValues
----------------------------------
----------------------------------
generateDebugAndroidTestSources
dependOn--> processDebugAndroidTestResources
dependOn--> prepareLintJar
dependOn--> generateDebugAndroidTestBuildConfig
dependOn--> compileDebugAndroidTestRenderscript
dependOn--> compileDebugAndroidTestAidl
----------------------------------
----------------------------------
generateDebugAssets
dependOn--> compileDebugShaders
----------------------------------
----------------------------------
generateDebugBuildConfig
dependOn--> checkDebugManifest
output--> /Users/username/project/testProject/app/build/generated/source/buildConfig/debug
----------------------------------
----------------------------------
generateDebugResValues
output--> /Users/username/project/testProject/app/build/generated/res/resValues/debug
----------------------------------
----------------------------------
generateDebugResources
dependOn--> compileDebugRenderscript
dependOn--> generateDebugResValues
----------------------------------
----------------------------------
generateDebugSources
dependOn--> processDebugResources
dependOn--> prepareLintJar
dependOn--> compileDebugRenderscript
dependOn--> compileDebugAidl
dependOn--> generateDebugBuildConfig
----------------------------------
----------------------------------
generateReleaseAssets
dependOn--> compileReleaseShaders
----------------------------------
----------------------------------
generateReleaseBuildConfig
dependOn--> checkReleaseManifest
output--> /Users/username/project/testProject/app/build/generated/source/buildConfig/release
----------------------------------
----------------------------------
generateReleaseResValues
output--> /Users/username/project/testProject/app/build/generated/res/resValues/release
----------------------------------
----------------------------------
generateReleaseResources
dependOn--> compileReleaseRenderscript
dependOn--> generateReleaseResValues
----------------------------------
----------------------------------
generateReleaseSources
dependOn--> prepareLintJar
dependOn--> processReleaseResources
dependOn--> compileReleaseRenderscript
dependOn--> generateReleaseBuildConfig
dependOn--> compileReleaseAidl
----------------------------------
----------------------------------
installDebug
dependOn--> assembleDebug
input--> /Users/username/Library/Android/sdk/platform-tools/adb
input--> /Users/username/Library/Android/sdk/build-tools/26.0.2/split-select
----------------------------------
----------------------------------
installDebugAndroidTest
dependOn--> assembleDebugAndroidTest
input--> /Users/username/Library/Android/sdk/platform-tools/adb
input--> /Users/username/Library/Android/sdk/build-tools/26.0.2/split-select
----------------------------------
----------------------------------
javaPreCompileDebug
dependOn--> preDebugBuild
output--> /Users/username/project/testProject/app/build/intermediates/javaPrecompile/debug/annotationProcessors.json
----------------------------------
----------------------------------
javaPreCompileDebugAndroidTest
dependOn--> preDebugAndroidTestBuild
input--> /Users/username/project/testProject/app/build/intermediates/classes-jar/debug/classes.jar
output--> /Users/username/project/testProject/app/build/intermediates/javaPrecompile/androidTest/debug/annotationProcessors.json
----------------------------------
----------------------------------
javaPreCompileDebugUnitTest
dependOn--> preDebugUnitTestBuild
input--> /Users/username/project/testProject/app/build/intermediates/classes/debug
output--> /Users/username/project/testProject/app/build/intermediates/javaPrecompile/test/debug/annotationProcessors.json
----------------------------------
----------------------------------
javaPreCompileRelease
dependOn--> preReleaseBuild
output--> /Users/username/project/testProject/app/build/intermediates/javaPrecompile/release/annotationProcessors.json
----------------------------------
----------------------------------
javaPreCompileReleaseUnitTest
dependOn--> preReleaseUnitTestBuild
input--> /Users/username/project/testProject/app/build/intermediates/classes/release
output--> /Users/username/project/testProject/app/build/intermediates/javaPrecompile/test/release/annotationProcessors.json
----------------------------------
----------------------------------
lint
input--> /Users/username/project/testProject/app/build/intermediates/lint/lint.jar
input--> /Users/username/project/testProject/app/build/intermediates/manifests/full/debug
input--> /Users/username/project/testProject/app/build/outputs/logs/manifest-merger-debug-report.txt
input--> /Users/username/project/testProject/app/build/intermediates/classes/debug
input--> /Users/username/project/testProject/app/build/intermediates/manifests/full/release
input--> /Users/username/project/testProject/app/build/outputs/logs/manifest-merger-release-report.txt
input--> /Users/username/project/testProject/app/build/intermediates/classes/release
----------------------------------
----------------------------------
lintDebug
input--> /Users/username/project/testProject/app/build/intermediates/lint/lint.jar
input--> /Users/username/project/testProject/app/build/intermediates/manifests/full/debug
input--> /Users/username/project/testProject/app/build/outputs/logs/manifest-merger-debug-report.txt
input--> /Users/username/project/testProject/app/build/intermediates/classes/debug
----------------------------------
----------------------------------
lintRelease
input--> /Users/username/project/testProject/app/build/intermediates/lint/lint.jar
input--> /Users/username/project/testProject/app/build/intermediates/manifests/full/release
input--> /Users/username/project/testProject/app/build/outputs/logs/manifest-merger-release-report.txt
input--> /Users/username/project/testProject/app/build/intermediates/classes/release
----------------------------------
----------------------------------
lintVitalRelease
dependOn--> task ':app:compileReleaseJavaWithJavac'
input--> /Users/username/project/testProject/app/build/intermediates/lint/lint.jar
input--> /Users/username/project/testProject/app/build/intermediates/manifests/full/release
input--> /Users/username/project/testProject/app/build/outputs/logs/manifest-merger-release-report.txt
input--> /Users/username/project/testProject/app/build/intermediates/classes/release
----------------------------------
----------------------------------
mergeDebugAndroidTestAssets
dependOn--> generateDebugAndroidTestAssets
input--> /Users/username/project/testProject/app/build/generated/assets/shaders/androidTest/debug
output--> /Users/username/project/testProject/app/build/intermediates/incremental/mergeDebugAndroidTestAssets
output--> /Users/username/project/testProject/app/build/intermediates/assets/androidTest/debug
----------------------------------
----------------------------------
mergeDebugAndroidTestJniLibFolders
dependOn--> generateDebugAndroidTestAssets
output--> /Users/username/project/testProject/app/build/intermediates/incremental/mergeDebugAndroidTestJniLibFolders
output--> /Users/username/project/testProject/app/build/intermediates/jniLibs/androidTest/debug
----------------------------------
----------------------------------
mergeDebugAndroidTestResources
dependOn--> generateDebugAndroidTestResources
input--> /Users/username/project/testProject/app/build/generated/res/resValues/androidTest/debug
input--> /Users/username/project/testProject/app/build/generated/res/rs/androidTest/debug
output--> /Users/username/project/testProject/app/build/intermediates/blame/res/androidTest/debug
output--> /Users/username/project/testProject/app/build/generated/res/pngs/androidTest/debug
output--> /Users/username/project/testProject/app/build/intermediates/incremental/mergeDebugAndroidTestResources
output--> /Users/username/project/testProject/app/build/intermediates/res/merged/androidTest/debug
----------------------------------
----------------------------------
mergeDebugAndroidTestShaders
output--> /Users/username/project/testProject/app/build/intermediates/incremental/mergeDebugAndroidTestShaders
output--> /Users/username/project/testProject/app/build/intermediates/shaders/androidTest/debug
----------------------------------
----------------------------------
mergeDebugAssets
dependOn--> generateDebugAssets
input--> /Users/username/project/testProject/app/build/generated/assets/shaders/debug
output--> /Users/username/project/testProject/app/build/intermediates/incremental/mergeDebugAssets
output--> /Users/username/project/testProject/app/build/intermediates/assets/debug
----------------------------------
----------------------------------
mergeDebugJniLibFolders
dependOn--> generateDebugAssets
output--> /Users/username/project/testProject/app/build/intermediates/incremental/mergeDebugJniLibFolders
output--> /Users/username/project/testProject/app/build/intermediates/jniLibs/debug
----------------------------------
----------------------------------
mergeDebugResources
dependOn--> generateDebugResources
input--> /Users/username/project/testProject/app/build/generated/res/resValues/debug
input--> /Users/username/project/testProject/app/build/generated/res/rs/debug
output--> /Users/username/project/testProject/app/build/intermediates/blame/res/debug
output--> /Users/username/project/testProject/app/build/generated/res/pngs/debug
output--> /Users/username/project/testProject/app/build/intermediates/incremental/mergeDebugResources
output--> /Users/username/project/testProject/app/build/intermediates/res/merged/debug
----------------------------------
----------------------------------
mergeDebugShaders
output--> /Users/username/project/testProject/app/build/intermediates/incremental/mergeDebugShaders
output--> /Users/username/project/testProject/app/build/intermediates/shaders/debug
----------------------------------
----------------------------------
mergeReleaseAssets
dependOn--> generateReleaseAssets
input--> /Users/username/project/testProject/app/build/generated/assets/shaders/release
output--> /Users/username/project/testProject/app/build/intermediates/incremental/mergeReleaseAssets
output--> /Users/username/project/testProject/app/build/intermediates/assets/release
----------------------------------
----------------------------------
mergeReleaseJniLibFolders
dependOn--> generateReleaseAssets
output--> /Users/username/project/testProject/app/build/intermediates/incremental/mergeReleaseJniLibFolders
output--> /Users/username/project/testProject/app/build/intermediates/jniLibs/release
----------------------------------
----------------------------------
mergeReleaseResources
dependOn--> generateReleaseResources
input--> /Users/username/project/testProject/app/build/generated/res/resValues/release
input--> /Users/username/project/testProject/app/build/generated/res/rs/release
output--> /Users/username/project/testProject/app/build/intermediates/blame/res/release
output--> /Users/username/project/testProject/app/build/generated/res/pngs/release
output--> /Users/username/project/testProject/app/build/intermediates/incremental/mergeReleaseResources
output--> /Users/username/project/testProject/app/build/intermediates/merged-not-compiled-resources/release
output--> /Users/username/project/testProject/app/build/intermediates/res/merged/release
----------------------------------
----------------------------------
mergeReleaseShaders
output--> /Users/username/project/testProject/app/build/intermediates/incremental/mergeReleaseShaders
output--> /Users/username/project/testProject/app/build/intermediates/shaders/release
----------------------------------
----------------------------------
mockableAndroidJar
input--> /Users/username/Library/Android/sdk/platforms/android-28/android.jar
output--> /Users/username/project/testProject/app/build/generated/mockable-android-28.v3.jar
----------------------------------
----------------------------------
packageDebug
dependOn--> processDebugResources
dependOn--> mergeDebugAssets
dependOn--> validateSigningDebug
dependOn--> compileDebugJavaWithJavac
input--> /Users/username/project/testProject/app/build/intermediates/assets/debug
input--> /Users/username/project/testProject/app/build/intermediates/manifests/full/debug
input--> /Users/username/project/testProject/app/build/intermediates/res/debug
input--> /Users/username/.android/debug.keystore
output--> /Users/username/project/testProject/app/build/intermediates/incremental/packageDebug
output--> /Users/username/project/testProject/app/build/outputs/apk/debug
----------------------------------
----------------------------------
packageDebugAndroidTest
dependOn--> processDebugAndroidTestResources
dependOn--> compileDebugAndroidTestJavaWithJavac
dependOn--> mergeDebugAndroidTestAssets
dependOn--> validateSigningDebugAndroidTest
input--> /Users/username/project/testProject/app/build/intermediates/assets/androidTest/debug
input--> /Users/username/project/testProject/app/build/intermediates/manifest/androidTest/debug
input--> /Users/username/project/testProject/app/build/intermediates/res/androidTest/debug
input--> /Users/username/.android/debug.keystore
output--> /Users/username/project/testProject/app/build/intermediates/incremental/packageDebugAndroidTest
output--> /Users/username/project/testProject/app/build/outputs/apk/androidTest/debug
----------------------------------
----------------------------------
packageRelease
dependOn--> mergeReleaseAssets
dependOn--> processReleaseResources
dependOn--> compileReleaseJavaWithJavac
input--> /Users/username/project/testProject/app/build/intermediates/assets/release
input--> /Users/username/project/testProject/app/build/intermediates/manifests/full/release
input--> /Users/username/project/testProject/app/build/intermediates/res_stripped/release
output--> /Users/username/project/testProject/app/build/intermediates/incremental/packageRelease
output--> /Users/username/project/testProject/app/build/outputs/apk/release
----------------------------------
----------------------------------
platformAttrExtractor
input--> /Users/username/Library/Android/sdk/platforms/android-28/android.jar
output--> /Users/username/project/testProject/app/build/intermediates/attr/R.txt
----------------------------------
----------------------------------
preBuild
----------------------------------
----------------------------------
preDebugAndroidTestBuild
dependOn--> preBuild
output--> /Users/username/project/testProject/app/build/intermediates/prebuild/androidTest/debug
----------------------------------
----------------------------------
preDebugBuild
dependOn--> preBuild
output--> /Users/username/project/testProject/app/build/intermediates/prebuild/debug
----------------------------------
----------------------------------
preDebugUnitTestBuild
dependOn--> preBuild
----------------------------------
----------------------------------
preReleaseBuild
dependOn--> extractProguardFiles
dependOn--> preBuild
output--> /Users/username/project/testProject/app/build/intermediates/prebuild/release
----------------------------------
----------------------------------
preReleaseUnitTestBuild
dependOn--> extractProguardFiles
dependOn--> preBuild
----------------------------------
----------------------------------
prepareLintJar
output--> /Users/username/project/testProject/app/build/intermediates/lint/lint.jar
----------------------------------
----------------------------------
processDebugAndroidTestJavaRes
dependOn--> preDebugAndroidTestBuild
output--> /Users/username/project/testProject/app/build/intermediates/sourceFolderJavaResources/androidTest/debug
----------------------------------
----------------------------------
processDebugAndroidTestManifest
input--> /Users/username/project/testProject/app/build/intermediates/manifests/full/debug
output--> /Users/username/project/testProject/app/build/intermediates/manifest/androidTest/debug
----------------------------------
----------------------------------
processDebugAndroidTestResources
input--> /Users/username/project/testProject/app/build/intermediates/res/merged/androidTest/debug
input--> /Users/username/project/testProject/app/build/intermediates/manifest/androidTest/debug
input--> /Users/username/project/testProject/app/build/intermediates/splits-support/androidTest/debug/split-list.gson
output--> /Users/username/project/testProject/app/build/intermediates/incremental/processDebugAndroidTestResources
output--> /Users/username/project/testProject/app/build/intermediates/res/androidTest/debug
output--> /Users/username/project/testProject/app/build/generated/source/r/androidTest/debug
output--> /Users/username/project/testProject/app/build/intermediates/res/symbol-table-with-package/androidTest/debug/package-aware-r.txt
output--> /Users/username/project/testProject/app/build/intermediates/symbols/androidTest/debug/R.txt
----------------------------------
----------------------------------
processDebugJavaRes
dependOn--> preDebugBuild
output--> /Users/username/project/testProject/app/build/intermediates/sourceFolderJavaResources/debug
----------------------------------
----------------------------------
processDebugManifest
dependOn--> checkDebugManifest
input--> /Users/username/project/testProject/app/build/intermediates/manifests/density/debug
input--> /Users/username/project/testProject/app/src/main/AndroidManifest.xml
output--> /Users/username/project/testProject/app/build/intermediates/manifests/instant-run/debug
output--> /Users/username/project/testProject/app/build/intermediates/manifests/full/debug
output--> /Users/username/project/testProject/app/build/outputs/logs/manifest-merger-debug-report.txt
----------------------------------
----------------------------------
processDebugResources
input--> /Users/username/project/testProject/app/build/intermediates/res/merged/debug
input--> /Users/username/project/testProject/app/build/intermediates/manifests/full/debug
input--> /Users/username/project/testProject/app/build/intermediates/splits-support/debug/split-list.gson
output--> /Users/username/project/testProject/app/build/intermediates/incremental/processDebugResources
output--> /Users/username/project/testProject/app/build/intermediates/res/debug
output--> /Users/username/project/testProject/app/build/generated/source/r/debug
output--> /Users/username/project/testProject/app/build/intermediates/res/symbol-table-with-package/debug/package-aware-r.txt
output--> /Users/username/project/testProject/app/build/intermediates/symbols/debug/R.txt
----------------------------------
----------------------------------
processDebugUnitTestJavaRes
dependOn--> preDebugUnitTestBuild
output--> /Users/username/project/testProject/app/build/intermediates/sourceFolderJavaResources/test/debug
----------------------------------
----------------------------------
processReleaseJavaRes
dependOn--> preReleaseBuild
output--> /Users/username/project/testProject/app/build/intermediates/sourceFolderJavaResources/release
----------------------------------
----------------------------------
processReleaseManifest
dependOn--> checkReleaseManifest
input--> /Users/username/project/testProject/app/build/intermediates/manifests/density/release
input--> /Users/username/project/testProject/app/src/main/AndroidManifest.xml
output--> /Users/username/project/testProject/app/build/intermediates/manifests/instant-run/release
output--> /Users/username/project/testProject/app/build/intermediates/manifests/full/release
output--> /Users/username/project/testProject/app/build/outputs/logs/manifest-merger-release-report.txt
----------------------------------
----------------------------------
processReleaseResources
input--> /Users/username/project/testProject/app/build/intermediates/res/merged/release
input--> /Users/username/project/testProject/app/build/intermediates/manifests/full/release
input--> /Users/username/project/testProject/app/build/intermediates/splits-support/release/split-list.gson
output--> /Users/username/project/testProject/app/build/intermediates/incremental/processReleaseResources
output--> /Users/username/project/testProject/app/build/intermediates/proguard-rules/release/aapt_rules.txt
output--> /Users/username/project/testProject/app/build/intermediates/res/release
output--> /Users/username/project/testProject/app/build/generated/source/r/release
output--> /Users/username/project/testProject/app/build/intermediates/res/symbol-table-with-package/release/package-aware-r.txt
output--> /Users/username/project/testProject/app/build/intermediates/symbols/release/R.txt
----------------------------------
----------------------------------
processReleaseUnitTestJavaRes
dependOn--> preReleaseUnitTestBuild
output--> /Users/username/project/testProject/app/build/intermediates/sourceFolderJavaResources/test/release
----------------------------------
----------------------------------
resolveConfigAttr
----------------------------------
----------------------------------
signingReport
----------------------------------
----------------------------------
sourceSets
----------------------------------
----------------------------------
splitsDiscoveryTaskDebug
output--> /Users/username/project/testProject/app/build/intermediates/splits-support/debug/split-list.gson
----------------------------------
----------------------------------
splitsDiscoveryTaskDebugAndroidTest
output--> /Users/username/project/testProject/app/build/intermediates/splits-support/androidTest/debug/split-list.gson
----------------------------------
----------------------------------
splitsDiscoveryTaskRelease
output--> /Users/username/project/testProject/app/build/intermediates/splits-support/release/split-list.gson
----------------------------------
----------------------------------
test
dependOn--> testDebugUnitTest
dependOn--> testReleaseUnitTest
----------------------------------
----------------------------------
testDebugUnitTest
input--> /Users/username/project/testProject/app/build/intermediates/manifests/full/debug
input--> /Users/username/project/testProject/app/build/intermediates/classes/test/debug
input--> /Users/username/project/testProject/app/build/intermediates/sourceFolderJavaResources/test/debug
input--> /Users/username/project/testProject/app/build/intermediates/classes/debug
input--> /Users/username/project/testProject/app/build/intermediates/sourceFolderJavaResources/debug
input--> /Users/username/project/testProject/app/build/generated/mockable-android-28.v3.jar
output--> /Users/username/project/testProject/app/build/test-results/testDebugUnitTest/binary
output--> /Users/username/project/testProject/app/build/reports/tests/testDebugUnitTest
output--> /Users/username/project/testProject/app/build/test-results/testDebugUnitTest
----------------------------------
----------------------------------
testReleaseUnitTest
input--> /Users/username/project/testProject/app/build/intermediates/manifests/full/release
input--> /Users/username/project/testProject/app/build/intermediates/classes/test/release
input--> /Users/username/project/testProject/app/build/intermediates/sourceFolderJavaResources/test/release
input--> /Users/username/project/testProject/app/build/intermediates/classes/release
input--> /Users/username/project/testProject/app/build/intermediates/sourceFolderJavaResources/release
input--> /Users/username/project/testProject/app/build/generated/mockable-android-28.v3.jar
output--> /Users/username/project/testProject/app/build/test-results/testReleaseUnitTest/binary
output--> /Users/username/project/testProject/app/build/reports/tests/testReleaseUnitTest
output--> /Users/username/project/testProject/app/build/test-results/testReleaseUnitTest
----------------------------------
----------------------------------
transformClassesAndResourcesWithProguardForRelease
output--> /Users/username/project/testProject/app/build/outputs/mapping/release/mapping.txt
output--> /Users/username/project/testProject/app/build/outputs/mapping/release/dump.txt
output--> /Users/username/project/testProject/app/build/outputs/mapping/release/seeds.txt
output--> /Users/username/project/testProject/app/build/outputs/mapping/release/usage.txt
output--> /Users/username/project/testProject/app/build/intermediates/transforms/proguard/release
----------------------------------
----------------------------------
transformClassesWithDexBuilderForDebug
output--> /Users/username/project/testProject/app/build/intermediates/transforms/dexBuilder/debug
----------------------------------
----------------------------------
transformClassesWithDexBuilderForDebugAndroidTest
output--> /Users/username/project/testProject/app/build/intermediates/transforms/dexBuilder/androidTest/debug
----------------------------------
----------------------------------
transformClassesWithDexForRelease
input--> /Users/username/project/testProject/app/build/intermediates/multi-dex/release/maindexlist.txt
output--> /Users/username/project/testProject/app/build/intermediates/transforms/dex/release
----------------------------------
----------------------------------
transformClassesWithShrinkResForRelease
input--> /Users/username/project/testProject/app/build/generated/source/r/release
input--> /Users/username/project/testProject/app/build/intermediates/merged-not-compiled-resources/release
input--> /Users/username/project/testProject/app/build/outputs/mapping/release/mapping.txt
input--> /Users/username/project/testProject/app/build/intermediates/manifests/full/release
input--> /Users/username/project/testProject/app/build/intermediates/res/release
input--> /Users/username/project/testProject/app/build/intermediates/splits-support/release/split-list.gson
output--> /Users/username/project/testProject/app/build/intermediates/res_stripped/release
----------------------------------
----------------------------------
transformDexArchiveWithDexMergerForDebug
output--> /Users/username/project/testProject/app/build/intermediates/transforms/dexMerger/debug
----------------------------------
----------------------------------
transformDexArchiveWithDexMergerForDebugAndroidTest
output--> /Users/username/project/testProject/app/build/intermediates/transforms/dexMerger/androidTest/debug
----------------------------------
----------------------------------
transformDexArchiveWithExternalLibsDexMergerForDebug
output--> /Users/username/project/testProject/app/build/intermediates/transforms/externalLibsDexMerger/debug
----------------------------------
----------------------------------
transformDexArchiveWithExternalLibsDexMergerForDebugAndroidTest
output--> /Users/username/project/testProject/app/build/intermediates/transforms/externalLibsDexMerger/androidTest/debug
----------------------------------
----------------------------------
transformNativeLibsWithMergeJniLibsForDebug
output--> /Users/username/project/testProject/app/build/intermediates/incremental/debug-mergeJniLibs/zip-cache
output--> /Users/username/project/testProject/app/build/intermediates/transforms/mergeJniLibs/debug
----------------------------------
----------------------------------
transformNativeLibsWithMergeJniLibsForDebugAndroidTest
output--> /Users/username/project/testProject/app/build/intermediates/incremental/debugAndroidTest-mergeJniLibs/zip-cache
output--> /Users/username/project/testProject/app/build/intermediates/transforms/mergeJniLibs/androidTest/debug
----------------------------------
----------------------------------
transformNativeLibsWithMergeJniLibsForRelease
output--> /Users/username/project/testProject/app/build/intermediates/incremental/release-mergeJniLibs/zip-cache
output--> /Users/username/project/testProject/app/build/intermediates/transforms/mergeJniLibs/release
----------------------------------
----------------------------------
transformNativeLibsWithStripDebugSymbolForDebug
input--> /Users/username/Library/Android/sdk/ndk-bundle/toolchains/x86-4.9/prebuilt/darwin-x86_64/bin/i686-linux-android-strip
input--> /Users/username/Library/Android/sdk/ndk-bundle/toolchains/mips64el-linux-android-4.9/prebuilt/darwin-x86_64/bin/mips64el-linux-android-strip
input--> /Users/username/Library/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-strip
input--> /Users/username/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-strip
input--> /Users/username/Library/Android/sdk/ndk-bundle/toolchains/x86_64-4.9/prebuilt/darwin-x86_64/bin/x86_64-linux-android-strip
output--> /Users/username/project/testProject/app/build/intermediates/transforms/stripDebugSymbol/debug
----------------------------------
----------------------------------
transformNativeLibsWithStripDebugSymbolForRelease
input--> /Users/username/Library/Android/sdk/ndk-bundle/toolchains/x86-4.9/prebuilt/darwin-x86_64/bin/i686-linux-android-strip
input--> /Users/username/Library/Android/sdk/ndk-bundle/toolchains/mips64el-linux-android-4.9/prebuilt/darwin-x86_64/bin/mips64el-linux-android-strip
input--> /Users/username/Library/Android/sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin/aarch64-linux-android-strip
input--> /Users/username/Library/Android/sdk/ndk-bundle/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-strip
input--> /Users/username/Library/Android/sdk/ndk-bundle/toolchains/x86_64-4.9/prebuilt/darwin-x86_64/bin/x86_64-linux-android-strip
output--> /Users/username/project/testProject/app/build/intermediates/transforms/stripDebugSymbol/release
----------------------------------
----------------------------------
transformResourcesWithMergeJavaResForDebug
output--> /Users/username/project/testProject/app/build/intermediates/incremental/debug-mergeJavaRes/zip-cache
output--> /Users/username/project/testProject/app/build/intermediates/transforms/mergeJavaRes/debug
----------------------------------
----------------------------------
transformResourcesWithMergeJavaResForDebugAndroidTest
output--> /Users/username/project/testProject/app/build/intermediates/incremental/debugAndroidTest-mergeJavaRes/zip-cache
output--> /Users/username/project/testProject/app/build/intermediates/transforms/mergeJavaRes/androidTest/debug
----------------------------------
----------------------------------
transformResourcesWithMergeJavaResForDebugUnitTest
output--> /Users/username/project/testProject/app/build/intermediates/incremental/debugUnitTest-mergeJavaRes/zip-cache
output--> /Users/username/project/testProject/app/build/intermediates/transforms/mergeJavaRes/test/debug
----------------------------------
----------------------------------
transformResourcesWithMergeJavaResForRelease
output--> /Users/username/project/testProject/app/build/intermediates/incremental/release-mergeJavaRes/zip-cache
output--> /Users/username/project/testProject/app/build/intermediates/transforms/mergeJavaRes/release
----------------------------------
----------------------------------
transformResourcesWithMergeJavaResForReleaseUnitTest
output--> /Users/username/project/testProject/app/build/intermediates/incremental/releaseUnitTest-mergeJavaRes/zip-cache
output--> /Users/username/project/testProject/app/build/intermediates/transforms/mergeJavaRes/test/release
----------------------------------
----------------------------------
uninstallAll
dependOn--> uninstallRelease
dependOn--> uninstallDebug
dependOn--> uninstallDebugAndroidTest
----------------------------------
----------------------------------
uninstallDebug
input--> /Users/username/Library/Android/sdk/platform-tools/adb
----------------------------------
----------------------------------
uninstallDebugAndroidTest
input--> /Users/username/Library/Android/sdk/platform-tools/adb
----------------------------------
----------------------------------
uninstallRelease
input--> /Users/username/Library/Android/sdk/platform-tools/adb
----------------------------------
----------------------------------
validateSigningDebug
----------------------------------
----------------------------------
validateSigningDebugAndroidTest
----------------------------------
----------------------------------
writeDebugApplicationId
output--> /Users/username/project/testProject/app/build/intermediates/applicationId/debug
----------------------------------
----------------------------------
writeReleaseApplicationId
output--> /Users/username/project/testProject/app/build/intermediates/applicationId/release
----------------------------------

tldr ! 比 man 简单好用的命令手册

使用Linux或者Mac时,经常会忘记某些命令的用法,这个时候经常就需要去百度或者谷歌搜索命令的使用说明。其实系统自带了man命令来查看手册,但是man显示的使用手册往往又臭又长,我仅仅需要临时用一个命令,为什么非要看这么长的说明书?

tldr是简化版的使用手册,并不会像man一样把所有的使用参数和说明都列出来,而是只显示常用的几个使用Sample和说明。
这是tldr tar的例子,只显示常用的7个使用方式的例子,仅有17行。 而对应的man tar 可是400多行,看使用手册都看晕了。
tldr tar例子

安装

https://github.com/tldr-pages/tldr

tldr的安装非常简单。

Ubuntu上只要运行sudo apt install tldr即可安装成功。
Mac上运行brew install tldr即可安装成功。
其他安装方式请参考 https://tldr.sh/

What does “tldr” mean?
TL;DR stands for “Too Long; Didn’t Read”. It originates in Internet slang, where it is used to indicate that a long text (or parts of it) has been skipped as too lengthy. Read more in Wikipedia’s TL;DR article.

“tldr”是什么意思?

TL; DR代表“太长;没读”。它起源于互联网俚语,用于表示长文本(或其中的一部分)被过度冗长。阅读更多维基百科的TL; DR文章


tldr类似的还有bro,也是显示命令关键Sample,并且还多了快捷的提交Sample和给Sample投票的功能
http://bropages.org/
bropage tar 例子


400多行的man tar手册

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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
TAR(1)                                                                                  tar                                                                                 TAR(1)


tar - tar 档案文件管理程序的 GNU 版本。


tar <操作参数> [选项]

操作参数:
[-]A --catenate --concatenate
[-]c --create
[-]d --diff --compare
[-]r --append
[-]t --list
[-]u --update
[-]x --extract --get
--delete

常用选项:
-C, --directory 目录
-f, --file 文件
-j, --bzip2
-J, --xz
-p, --preserve-permissions
-v, --verbose
-z, --gzip

所有选项:
[ -a, --auto-compress ] [ --add-file 文件 ] [ --anchored ] [ --atime-preserve ] [ -b, --blocking-factor N ] [ -B, --read-full-records ] [ --backup[=备份类型] ] [ --block-
compress ] [ -C, --directory 目录 ] [ --checkpoint ] [ --delay-directory-restore ] [ --exclude 文件或目录 ] [ --exclude-caches ] [ --exclude-caches-all ] [ --exclude-
caches-under ] [ --exclude-tag 文件 ] [ --exclude-tag-all 文件 ] [ --exclude-tag-under 文件 ] [ -f, --file [主机名:]文件 ] [ -F, --info-script 文件, --new-volume-script 文
件 ] [ --force-local ] [ --format 格式 ] [ -g, --listed-incremental 快照 ] [ -G, --incremental ] [ --group 组 ] [ -h, --dereference ] [ --help ] [ -i, --ignore-zeros ] [
-I, --use-compress-program 程序 ] [ --ignore-case ] [ --ignore-command-error ] [ --ignore-failed-read ] [ --index-file 文件 ] [ -j, --bzip2 ] [ -J, --xz ] [ -k, --keep-
old-files ] [ -K, --starting-file 文件 ] [ --keep-newer-files ] [ -l, --check-links ] [ -L, --tape-length N ] [ --lzip ] [ --lzma ] [ --lzop ] [ -m, --touch,
--modification-time ] [ -M, --multi-volume ] [ --mode 权限 ] [ --mtime 日期 ] [ -N, --after-date 日期, --newer 日期 ] [ --newer-mtime 日期 ] [ --no-anchored ] [ --no-auto-
compress ] [ --no-delay-directory-restore ] [ --no-ignore-case ] [ --no-ignore-command-error ] [ --no-overwrite-dir ] [ --no-quote-chars ] [ --no-recursion ] [ --no-same-
permissions ] [ --no-unquote ] [ --no-wildcards ] [ --no-wildcards-match-slash ] [ --null ] [ --numeric-owner ] [ -o, --old-archive, --portability, --no-same-owner ] [ -O,
--to-stdout ] [ --occurrence 次数 ] [ --one-file-system ] [ --overwrite ] [ --overwrite-dir ] [ --owner 用户 ] [ -p, --same-permissions, --preserve-permissions ] [ -P,
--absolute-names ] [ --pax-option 关键字列表 ] [ --posix ] [ --preserve ] [ --quote-chars 字符串 ] [ --quote-style 风格 ] [ -R, --block-number ] [ --record-size 字节数 ] [
--recursion ] [ --recursive-unlink ] [ --remove-files ] [ --restrict ] [ --rmt-command 命令 ] [ --rsh-command 命令 ] [ -s, --same-order, --preserve-order ] [ -S, --sparse
] [ --same-owner ] [ --show-defaults ] [ --show-omitted-dirs ] [ --show-transformed-names, --show-stored-names ] [ --strip-components 目录层数 ] [ --suffix 后缀 ] [ -T,
--files-from 文件 ] [ --test-label ] [ --to-command 命令 ] [ --transform sed表达式 ] [ --totals ] [ -U, --unlink-first ] [ --unquote ] [ --utc ] [ -v, --verbose ] [ -V,
--label 名称 ] [ --version ] [ --volno-file 文件 ] [ -w, --interactive, --confirmation ] [ -W, --verify ] [ --wildcards ] [ --wildcards-match-slash ] [ -X, --exclude-from
文件 ] [ -z, --gzip, --gunzip, --ungzip ] [ -Z, --compress, --uncompress ] [ -[0-7][lmh] ]


这是tar的GNU版本的手册页。 tar是一个用于储存或提取tar文件的程序。 tar文件可放在磁盘中, 也可以存为普通文件。 tar 的第一个参数必须是操作参数A、c、d、r、t、u、x 中的一个,
参数后面可跟着任意可选选项。 tar的最后一个参数是你要处理的文件或目录的名字。 如果你指定了一个目录, 该目录的所有子目录都将被加入存档。


tar -xvf foo.tar
提取 foo.tar 文件并显示提取过程

tar -xzf foo.tar.gz
提取用 gzip 压缩的文件 foo.tar.gz

tar -cjf foo.tar.bz2 bar/
用 bzip 为目录 bar 创建一个叫做 foo.tar.bz2存档

tar -xjf foo.tar.bz2 -C bar/
把用 bzip 压缩的文件 foo.tar.bz2 提取到 bar 目录

tar -xzf foo.tar.gz blah.txt
把文件 blah.txt 从 foo.tar.gz 中提取出来

注意: 当压缩或提取的时候, 压缩类型选项常常是不必需的, 因为tar会根据文件的后缀自动选择压缩类型。




-A, --catenate, --concatenate
将一存档与已有的存档合并

-c, --create
创建一个新的存档

-d, --diff, --compare
比较存档与相应的未存档文件的不同之处

-r, --append
将文件附加到存档结尾

-t, --list
列出存档中文件的目录

-u, --update
仅将较新的文件附加到存档中

-x, --extract, --get
从存档提取文件

--delete
把指定文件从存档中删除(不要用于磁带!)


-C, --directory 目录
提取存档到指定目录

-f, --file [主机名:]文件
指定存档或设备中的文件 (默认是 "-", 表示 标准输入/输出)

-j, --bzip2
用 bzip2 处理存档; 用于 .bz2 文件

-J, --xz
用 xz 处理存档; 用于 .xz 文件

-p, --preserve-permissions
提取所有保护信息

-v, --verbose
显示文件处理过程

-z, --gzip, --ungzip
用 gzip 处理存档; 用于 .gz 文件


-a, --auto-compress
根据存档后缀来选择压缩程序

--add-file 文件
添加指定文件到存档 (对以下标线开头的文件很有用)

--anchored
patterns will match the start of file names

--atime-preserve
不改变存档中文件的访问时间

-b, --blocking-factor N
指定块大小为 Nx512 字节(默认N=20)

-B, --read-full-blocks
读取时重组块 (用于读取4.2BSD pipes)

--backup[=备份类型]
备份文件而不是删除它们, 备份类型有simple、numbered等

--block-compress
让磁带的输出结果成块输出

-C, --directory 目录
提取文档到指定目录

--checkpoint
读取存档时显示目录名

--delay-directory-restore
延迟对已提取目录的修改时间和权限的设定, 直到提取结束

--exclude 文件或目录
排除指定文件或目录

--exclude-caches
排除带有 缓存目录 标记的目录

--exclude-tag 文件
排除包含指定文件的目录

-f, --file [主机名:]文件
指定存档或设备中的文件 (默认是 "-", 表示 标准输入/输出)

-F, --info-script 文件, --new-volume-script 文件
在每卷磁带的结尾运行脚本 (会应用--multi-volume选项)

--force-local
存档文件是本地的, 即使它的名称中含有冒号

--format FORMAT
选择创建存档的格式
v7 - Unix V7
oldgnu - GNU tar <=1.12
gnu - GNU tar 1.13
ustar - POSIX.1-1988
posix - POSIX.1-2001

-g, --listed-incremental 快照
创建/列出/提取 新GNU格式的增量备份

--group 组
将添加到存档的文件的组标识设置为指定组, 而不是源文件所在的组; 这个选项对提取无效

-G, --incremental
创建/列出/提取 旧GNU格式的增量备份

-h, --dereference
不存入符号链接; 存入链接指向的文件

--help 显示像本手册这样的帮助信息, 但不像这么详细

-i, --ignore-zeros
忽略存档中的 0 字节块 (那通常意味着文件结束)

-I, --use-compress-program 程序
通过指定程序访问存档 (该程序通常是一个压缩程序; 它需能接受 -d 参数)

--ignore-case
排除文件时不区分大小写

--ignore-command-error
忽略子程序的退出代码

--ignore-failed-read
遇到不可读文件的非零状态不退出

--index-file 文件
将处理过程信息输出到指定文件, 而不是输出到标准输出

-j, --bzip2
用 bzip2 处理存档, 用于 .bz2 文件

-J, --xz
用 xz 处理存档, 用于 .xz 文件

-k, --keep-old-files
保留已存在的文件; 不用存档中的文件覆盖它们

-K, --starting-file FILE
从存档中的指定文件处开始

--keep-newer-files
不覆盖比存档新的文件

-l, --check-links
如果文件系统中文件的硬链接数和存档中记录的不同, 则发出警告

-L, --tape-length N
在写入了N*1024字节后, 更换磁带

-m, --touch, --modification-time
不提取文件的修改时间

-M, --multi-volume
创建/列出/提取 多卷存档

--mode 权限
添加文件时应用指定的权限 (参看 chmod(1))

--mtime 日期
当创建存档时, 使用指定日期作为存档成员的修改日期, 而不是使用文件的实际修改时间

-N, --after-date 日期, --newer 日期
只存储在指定日期后有修改或状态更新 (权限, ACLs, 扩展属性, ...)的文件

--newer-mtime 日期
和 --newer 类似, 但是只存储指定日期后有修改的文件

--no-anchored
匹配任意‘/’后字符项--exclude一起使用

--no-auto-compress
不根据存档后缀来决定使用哪个压缩程序

--no-delay-directory-restore
在目录中的所有文件都被提取完成时, 就设定该目录的修改时间和权限; 这是默认设置

--no-ignore-command-error
对以非零状态终止的子程序的显示警告

--no-ignore-case
用 --exclude 匹配时区分大小写

--no-overwrite-dir
从存档中提取文件时, 保留已存在目录的元数据。

--no-quote-chars 字符串
把指定字符串中的字符从--quote-chars选项指定的字符中去除

--no-recursion
不递归进入子目录

--no-same-permissions
提取时应用用户的umask, 而不是用已记录的权限

--no-unquote
将所有输入文件或成员的名字作为普通文字, 不解释转义序列

--no-wildcards
不对--exclude使用通配符

--no-wildcards-match-slash
--exclude的通配符不匹配斜杠(/)

--null --files-from读取以空值终止的名字, 禁用--directory

--numeric-owner
总是用数字作为 用户/组 的名字

-o, --old-archive, --portability
相当于--format=v7; 当创建存档时-o选项表示这个行为 (已弃用的行为)

-o, --no-same-owner
提取时不恢复所有权; 当提取时-o选项表示这个行为

-O, --to-stdout
将文件提取到标准输出

--occurrence 次数
只处理指定次数每个已被命名的文件的在操作中的出现; 用于--delete, --diff, --extract, 或 --list

--one-file-system
创建存档时停留在本地文件系统

--overwrite
提取时覆盖已存在的文件和目录中的元数据

--overwrite-dir
提取时覆盖目录中的元数据

--owner 用户
将文件所有者设为指定用户, 而不是原文件的所有者; 这个选项对提取无效

-p, --preserve-permissions, --same-permissions
提取所有保护信息

-P, --absolute-names
将文件名开头的“/”符号看作文件名的一部分

--pax-option 关键字列表
修改tar处理扩展头关键字的方式, 只用于POSIX.1-2001存档

--posix
相当于--format=posix

--preserve
相当于--preserve-permissions加上--same-order

--quote-chars 字符串
总是标出指定字符串中包含的的字符, 即使已选择的标识风格不标识它们

--quote-style 风格
设定显示成员和文件名称的标识风格

-R, --record-number
显示存档中每条信息的记录数字

--record-size 字节数
访问存档时每条记录使用指定的字节数

--recursion
递归进入目录

--recursive-unlink
提取目录之前先把存在的相同名称的目录删除

--remove-files
把文件加入到存档后删除这些文件

--restrict
禁用一些有潜在害处的选项; 目前这会禁用多卷菜单中对shell的调用

--rmt-command 命令
用指定的命令代替默认的/usr/sbin/rmt

--rsh-command 命令
用指定的远程命令代替rsh(1)

-s, --same-order, --preserve-order
名称列表会被排序以匹配存档

-S, --sparse
高效地处理稀疏文件

--same-owner
以相同的所有权创建提取出的文件

--show-defaults
显示tar使用的默认选项

--show-omitted-dirs
显示提取时tar跳过的目录

--show-transformed-names, --show-stored-names
应用了任何sed转换之后, 显示文件或成员名字

--strip-components 目录层数
在提取前, 把文件从前往后指定层数的目录都从提取路径中去掉, 如果文件包含在指定层数中, 则不被提取

--suffix 后缀
备份文件时, 使用指定的后缀, 而不是使用默认后缀‘~’

-T, --files-from 文件
从指定文件中获得要提取或创建的存档的名字

--test-label
读取卷标; 如果一个词被指定了, 则测试它是否匹配这个卷标

--to-command 命令
提取期间, 将提取的文件导入到指定命令的标准输入

--totals
显示用--create参数写入的总字节数

--transform sed表达式
用sed的转换表达式转换文件或成员的名字

-U, --unlink-first
提取文件之前,删除已存在的与之同名的文件

--unquote
不标识输入文件或成员的名字; 这是默认选项

--utc 以UTC时间显示文件的修改日期

-v, --verbose
列出文件的处理情况

-V, --label 名称
用指定卷名创建存档

--version
显示tar程序的版本信息

--volno-file 文件
保持追踪指定文件中多卷存档的卷编号; 和--multi-volume一起使用

-w, --interactive, --confirmation
每一个动作都要求确认

-W, --verify
写完存档后对其进行校验

--wildcards
对--exclude用通配符

--wildcards-match-slash
--exclude的通配符匹配斜杠(/)

-X, --exclude-from 文件

排除列在指定文件中的文件

-z, --gzip, --gunzip, --ungzip
用gzip对存档进行操作

-Z, --compress, --uncompress
用compress对存档进行操作

-[0-7][lmh]
指定驱动器[0-7]和压缩密度[低中高]

BUGS
GNU世界的人, 通常不喜欢man手册, 而是写文档代替之。 tar的维护者也是如此。 所以, 这个man手册页可能会不完全, 或者不够新, 它被包含在Gentoo的portage树中, 因为man是一个非
常好的工具:)。 这个man手册页最初取自Debian Linux, 从那时起已在这里被很好地更新。


请通过 http://bugs.gentoo.org/ 报告Bug。 翻译问题请联系译者或到 https://github.com/lidaobing/manpages-zh/ 提交问题


Debian Linux http://www.debian.org/
Mike Frysinger <vapier@gentoo.org>


CMPP 中文手册页计划 http://cmpp.linuxforum.net (2001/08/08)
Saigut <gosaigut@gmail.com> (2013/11/09)


2014/10/04


本页面中文版由中文 man 手册页计划提供。
中文 man 手册页计划:https://github.com/man-pages-zh/manpages-zh

GNU Mar 2010 TAR(1)

一般网站上有设置页面的,直接在设置页面里选择语言就好了,比如youtube

但是某些网址上没有设置页面,或者设置页面里找不到设置语言的选项,这是可以试试在链接最后面加上hl后缀,Zh-cn表示中文,en表示英文 …… 就可以切换语言了。

url?hl=Zh-cn //切换为中文

url?hl=en  //切换为英文

 

不仅google官网如此,google系列的其他网站也是一样,比如 firebase 

 

Firebase Crashlytics Sdk接入流程

Firebase Crashlytics是收购了Fabric而来的,服务器也是Fabric的,所以虽然Firebase中很多功能在国内是不能用的,但是 Crashlytics 这个功能却是可以用的。 大家可以放心的使用Firebase来做Crash统计分析。

考拉刚刚把crash统计平台迁移到了firebase上,在此记录一下接入Firebase Crashlytics Sdk的流程,以供大家参考。

接入一个新的SDK,最重要的文档就是官方手册,Firebase Crashlytics的官方手册是这个Firebase Crashlytics 使用入门 | Firebase,一定要注意看的是Crashlytics的文档,而不是“Firebase 崩溃报告(Firebase Crash Reporting)”,后者是firebase已经不维护的产品。

步骤一 接入Firebase

Crashlytics作为Firebase的一部分,要使用Crashlytics必须先接入Firebase。

官方文档写明的步骤本文就不再重复了,这部分的官方文档链接如下,请点击链接阅读。
将 Firebase 添加到您的 Android 项目 | Firebase

可选择使用Firebase Assistant自动配置和手动接入Firebase两种方式,推荐先尝试Firebase 智能助理自动配置,如果不能自动配置成功,再尝试手动配置。

上面按照官方文档的操作的步骤中,如果使用Firebase Assistant 要注意一定不要选“Crash Reporting”,这是firebase已经废弃的服务,然而现在新的Crashlytics却不在Assistant列表内。这一步就选Analytics就好了,不用担心选了Analytics多了冗余的依赖,使用Firebase的任何服务都要先依赖Analytics,Analytics是必需的依赖。

另外即使使用了Firebase Assistant 也建议看一遍手动添加的步骤,然后检查一下Firebase 智能助理自动生成的代码是否与手动添加的代码一致,不能完全依赖工具。

这一步完成后,当前下项目的代码情况应该是这样的:

  • 工程级 build.gradle 文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    buildscript {
    // ...
    dependencies {
    // ...
    classpath 'com.google.gms:google-services:4.1.0' // google-services plugin
    }
    }

    allprojects {
    // ...
    repositories {
    // ...
    google() // Google's Maven repository
    }
    }
  • application级 build.gradle文件(通常是 app/build.gradle)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    apply plugin: 'com.android.application'

    android {
    // ...
    }

    dependencies {
    // ...
    implementation 'com.google.firebase:firebase-core:16.0.4'

    // Getting a "Could not find" error? Make sure you have
    // added the Google maven respository to your root build.gradle
    }

    // ADD THIS AT THE BOTTOM
    apply plugin: 'com.google.gms.google-services'
  • google-services.json文件一定要放在application级 build.gradle(通常是 app/build.gradle)同级目录下

    1
    2
    3
    4
    5
    6
    7
    8
    9
    .
    ├── app
    │ ├── build.gradle
    │ ├── google-services.json
    │ └── src
    ├── build.gradle
    ├── gradle.properties
    ├── local.properties
    └── settings.gradle

此时可以sync一遍gradle依赖,运行一下你的app,如果在应用启动时出现如下log
I/FirebaseInitProvider: FirebaseApp initialization successful
则表示,app正常接入了,接下来,就该接入Crashlytics了。

步骤二 Crashlytics SDK接入

如果你之前的项目使用的是Fabric Crashlytics,那你可以直接使用[Fabric迁移流程](https://fabric.io/firebase_migration)来快速迁移到Firebase Crashlytics。
否则,请继续看下面的步骤。

首先点击Firebase 控制台中的 Crashlytics按钮来开启Crashlytics服务。

  • 然后,在项目级 build.gradle 中,添加 Crashlytics 代码库和依赖项

    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
    buildscript {
    repositories {
    // ...

    // Add repository
    maven {
    url 'https://maven.fabric.io/public'
    }
    }
    dependencies {
    // ...

    // Check for v3.1.2 or higher
    classpath 'com.google.gms:google-services:4.1.0'

    // Add dependency
    classpath 'io.fabric.tools:gradle:1.26.1'
    }
    }

    allprojects {
    // ...
    repositories {
    // ...

    // Add repository
    maven {
    url 'https://maven.google.com/'
    }
    }
    }

  • 在应用级 build.gradle 中,添加 Crashlytics 相关配置

1
2
3
4
5
6
7
8
9
10
11
12
13
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'

dependencies {
// ...

// Check for v11.4.2 or higher
implementation 'com.google.firebase:firebase-core:16.0.6'

// Add dependency
implementation 'com.crashlytics.sdk.android:crashlytics:2.9.8'
}

做完这一步后,就可以启动app并制造一个crash,到Firebase 控制台中的 Crashlytics页面查看是否有数据上报即可。Firebase的数据上报实时性很高,尤其是新建的项目,数据量很少,出现crash后几秒钟就能在Firebase Crashlytics的平台上看到了。

建议在debug模式下添加 ext.alwaysUpdateBuildId = false标志来阻止 Crashlytics 不断更新其构建 ID,优化日常开发的编译速度。

1
2
3
4
5
6
7
android {
...
buildTypes {
debug {
ext.alwaysUpdateBuildId = false
}
}

步骤三 (可选) Crashlytics SDK NDK Crash监控

Firebase Crashlytics的官方文档只列出来了Java代码的Crash监控使用方式,并没有提及NDK Crash的监控。
对于大部分Android开发者来说,NDK的Crash也确实没有监控的必要,但是考拉这边用了很多第三方so库,这些so库也是有必要监控起来的。
Firebase Crashlytics是由Firebase收购Fabric而来的项目,技术方案也几乎没有变化,所以可以用Fabric监控NDK Crash的使用方式使用Firebase Crashlytics。
Fabric NDK Crash Reporting

  • 在应用级 build.gradle 中,添加 Crashlytics NDK Crash Reporting 相关配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'

// set NDK Crash Reporting enable
crashlytics {
enableNdk true
}

dependencies {
// ...
implementation 'com.google.firebase:firebase-core:16.0.6'

implementation 'com.crashlytics.sdk.android:crashlytics:2.9.8'
// Add ndk dependency
implementation 'com.crashlytics.sdk.android:crashlytics-ndk:2.0.5'
}

在manifest中声明Crashlytics手动初始化

Manifest
1
2
3
4
<!--手动初始化firebase Crashlytics sdk-->
<meta-data
android:name="firebase_crashlytics_collection_enabled"
android:value="false"/>

根据自身app启动流程,选择合适时机手动初始化Crashlytics

1
Fabric.with(context, new Crashlytics(), new CrashlyticsNdk());

如果是本地源码编译的so而不是直接使用第三方提供的so,可以生成并上传符号表来辅助分析crash信息,执行 ./gradlew crashlyticsUploadSymbolsRelease 即可上传符号表。

以上,就完成了Crashlytics SDK NDK Crash监控的配置,可以手动引发一个Ndk Crash来测试,到统计平台上看是否有对于的Crash。

打包NDK代码引发native crash比较麻烦,在此提供一个从java代码引发NDK Crash的方式:

1
2
3
4
5
6
7
public void crashNatively() {
try {
Class.forName("dalvik.system.VMDebug").getMethod("crash").invoke(null);
} catch (Exception e) {
e.printStackTrace();
}
}

步骤四 添加辅助数据帮助分析

通过以上步骤的配置,现在Firebase Crashlytics已经可以正常工作了。并且还附带了发生Crash的时间,机型,系统版本,应用版本等信息以供分析。
Firebase 自带的数据
然而实际使用过程中,我们都期望能得到更详细的用户信息,这时可以自定义添加更多数据,下面是一些考拉中添加的一些常用信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//用户id
Crashlytics.setUserIdentifier(builder.getUserId());
//用户渠道
Crashlytics.setString("Channel", builder.getChannelInfo());
//用户补丁版本
Crashlytics.setString("Version", builder.getUserTag());
//用户当前WebView UA
Crashlytics.setString("WebView UA", WebViewSettings.getUserAgent());
//打包机名称
Crashlytics.setString("BuildHost", BuildInfo.BUILD_HOST);
//打包时间
Crashlytics.setString("BuildTime", BuildInfo.BUILD_TIME);
//最新提交commit id
Crashlytics.setString("GitLog", BuildInfo.BUILD_GIT_LOG);

这些自定义的数据可以在,Firebase Crashlytics的“键”选项卡下面看到。
辅助数据
通过setUserIdentifier所设置的用户Id还可以用于搜索。
UserId搜索
还可以通过Crashlytics.log方法,打入自定义日志用于分析。
日志

开发过程中,还会遇到通过try catch捕获了异常,不造成崩溃,但是又希望能够统计上报该异常的情况。这个时候,可以使用Crashlytics.logException(throwable)方法将异常统计上来。
在Firebase的过滤条件中选择,不严重的事件类型,即可过滤该异常。

不严重异常

步骤五 修改ProGuard混淆规则

参考官方文档 获取经过反混淆处理的崩溃报告 配置即可。

1
2
3
4
5
6
7
8
-keepattributes *Annotation*
-keepattributes SourceFile,LineNumberTable
-keep public class * extends java.lang.Exception
-keep class com.crashlytics.** { *; }
-dontwarn com.crashlytics.**

// 删除-printmapping mapping.txt 这一行
// -printmapping mapping.txt

步骤六(可选) oppo部分机型谷歌服务框架弹框优化

做完以上所有步骤,基本就可以上线了。但是实际使用中发现,有用户反馈在oppo手机上会提示需要先下载谷歌服务框架才能运行。按照oppo手机的提示操作,下载好谷歌服务框架就能正常使用。
这个现象有些影响用户体验,虽然实际出现这个现象的手机是极少数(找了很多天,才在一台旧版的oppo A53m上复现了这个问题,怀疑是oppo旧版系统并且很久没有更新过才会出现),但是秉着提升用户体验的角度,还是专门做了优化。

这个弹框是这样的。

一般这种问题,只要在这种手机上,关掉crash分析即可。
然而在出现这个弹框后,app无法得到任何通知,就直接被oppo系统杀掉了,并且也找不到可靠的途径来判断是否会弹这个框。
经过一番debug加测试,基本确定,是有Activity变化的时候,会触发Firebase的统计上报功能,这时会触发com.google.android.gms.measurement.AppMeasurementReceiver这个Receiver,然后触发com.google.android.gms.measurement.AppMeasurementService这个service,然后调用gms上传数据到服务器。国内手机一般都没有gms框架,正常情况下这里发现没有gms的时候,就会走Firebase SDK内置的应用内上传逻辑。但是oppo手机比较奇怪,它应该是内置了gms上传事件的接收器,然而这个接收器的作用,不是上传数据,而是把app进程杀死,然后弹个窗(我也是醉了)。

看起来app是无法对这个现象做任何处理了,即使是通过机型来做黑名单,都不能很好的判断,毕竟即使是同一个机型,也仅有极少数会出现这个弹框,存在很大的误伤概率。
这种情况下,只剩下了一种办法,先让这个现象出现,然后下次启动时再通过上次是否出现了这个现象,来规避问题。虽然会至少出现一次不友好现象,但至少比用户一直不下载谷歌服务框架就一直出现弹窗要好一些。
流程图
新建了一个Int类型SharePreference值,默认是0,当app第一次启动的时候,设为-1,MainActivity启动成功后,设为1。
这样,下次启动时,如果发现没有这个SharePreference值为-1,则表示上次没有成功启动,就关闭Firebase。
这里的关闭还有些特殊,直接不初始化Firebase的话,会完全失去Crash监控效果,我们只把AppMeasurementReceiver这个Receiver diasble,这样只是失去了用户信息上报,少了些log和轻微影响数据百分比准确度,不影响正常crash上报功能,最大程度保留了功能完整性。

1
2
3
4
5
6
7
8
9
int activityInitSuccessFlag = PreferencesUtils.getInt(CrashCollector.ACTIVITY_INIT_SUCCESS_FLAG, 0);
if (activityInitSuccessFlag == 0) {
PreferencesUtils.saveInt(CrashCollector.ACTIVITY_INIT_SUCCESS_FLAG, -1);
CrashCollector.setGmsReceiverEnable(getApplication(), true);
} else if (activityInitSuccessFlag == 1) {
CrashCollector.setGmsReceiverEnable(getApplication(), true);
} else if (activityInitSuccessFlag == -1) {
CrashCollector.setGmsReceiverEnable(getApplication(), false);
}
1
2
3
4
5
private void MainActivityInitSuccess() {
if (CrashCollector.sGmsReceiverEnableEnable) {
PreferencesUtils.saveInt(CrashCollector.ACTIVITY_INIT_SUCCESS_FLAG, 1);
}
}
1
2
3
4
5
6
7
8
9
public static void setGmsReceiverEnable(Context context, boolean enable) {
sGmsReceiverEnableEnable = enable;
PackageManager pm = context.getApplicationContext().getPackageManager();
ComponentName componentName = new ComponentName(context.getPackageName(),
"com.google.android.gms.measurement.AppMeasurementReceiver");
int state = enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
pm.setComponentEnabledSetting(componentName, state, PackageManager.DONT_KILL_APP);
}

以上,就是全部Firebase Crashlytics的接入步骤,以供参考。

引用:

  1. Firebase Crashlytics 使用入门 | Firebase
  2. 将 Firebase 添加到您的 Android 项目 | Firebase
  3. Fabric NDK Crash Reporting
  4. 获取经过反混淆处理的崩溃报告

转自:http://balistardut.github.io/2016/01/30/Linux%E7%A3%81%E7%9B%98%E7%9B%B8%E5%85%B3-%E5%88%86%E5%8C%BA%E4%B8%8E%E4%BF%AE%E5%A4%8D/

 

Linux磁盘相关-分区与修复

Jan 30, 2016 in linux

问题描述:

移动硬盘分配空间如下(其中sdb1,sdb3,sdb4为主分区,sdb5、6、7为逻辑分区):
sdb 8:16 0 465.7G 0 disk
├─sdb1 8:17 0 18.7G 0 part /
├─sdb2 8:18 0 1K 0 part
├─sdb3 8:19 0 78G 0 part /media/james/My Documentes
├─sdb4 8:20 0 319.2G 0 part /media/james/UUI
├─sdb5 8:21 0 10.9G 0 part
├─sdb6 8:22 0 7.8G 0 part /media/james/mint
└─sdb7 8:23 0 31.2G 0 part /media/james/home


原来sdb5挂载在Ubuntu15.04的根目录/下,sdb6挂载在目录/usr/share下(因为该目录占用空间大,不得已将数据复制出来覆盖了原来的mint,运行时挂载,这是一个不错的扩容方法),sdb7挂载在/home下(空间最大,但是由于安装软件多,大部分都在/usr下)。问题出现在,将Ubuntu安装在3个分区上后,还是经常出现开机iNode错误,不得已必须强制关机,重启后无法进入图形界面,而进入了emergency mode的命令行界面,输入密码可正常登陆,跳过则进入Ubuntu原本的图形界面,自己安装的软件全部没有,怀疑home目录没挂载上,进入sdb1分区的deepin系统,发现sdb5无法挂载,显示不能识别的文件系统。
尝试win下修复,但都无法挂载sdb5,分区表肯定损坏了,最后又把MBR给整坏了,硬盘已经完全无法启动操作系统了。无奈最后在sdb1上新安装了mintKDE系统,才修复了MBR。期间尝试了多个网友的办法,增加了不少技能。

1. 磁盘分区查看命令

1.1 lsblk

lsblk能列出当前系统存在的硬盘和硬盘分区情况,如下。
sdb 8:16 0 465.7G 0 disk
├─sdb1 8:17 0 18.7G 0 part /
├─sdb2 8:18 0 1K 0 part
├─sdb3 8:19 0 78G 0 part /media/james/My Documentes
├─sdb4 8:20 0 319.2G 0 part /media/james/UUI
├─sdb5 8:21 0 10.9G 0 part
├─sdb6 8:22 0 7.8G 0 part /media/james/mint
└─sdb7 8:23 0 31.2G 0 part /media/james/home

我总是能看到sdb5分区,但是无法挂载。

1.2 df

df 能列出硬盘分区挂载情况及使用情况,掌握磁盘是否占满。
james@james-ThinkPad-T440p:~ > df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sdb1 19G 4.6G 13G 27% /
/dev/sdb7 31G 3.5G 26G 12% /media/james/home
/dev/sdb6 7.6G 3.6G 3.7G 50% /media/james/mint
/dev/sda1 101G 45G 56G 45% /media/james/系统
/dev/sdb3 78G 74G 4.4G 95% /media/james/My Documentes
/dev/sdb4 320G 312G 7.5G 98% /media/james/UU

2. 磁盘分区工具

2.1 分区工具 fdisk

fdisk能为空磁盘分区,并且能修复partition order的错误,以前由于系统频繁装卸,存在这个错误,这个修复后,一直出现inode错误。fdisk还能列出分区的开始与结束柱头。
常用用法:fdisk /dev/sda //进入交互模式对磁盘进行操作

2.2 分区工具 parted

parted也是一个命令行分区工具。可以修改分区参数,还有一个找回丢失分区表的功能。但是我没有通过这个命令找到丢失的sdb5的分区表
参考:parted命令详解
linux的parted手册

3. 磁盘修复工具

3.1 主引导记录

(1)MBR:”Master Boot Record”主引导记录,BIOS检测到一个硬盘后,将磁盘的0 cylinder(0柱面),0 head(0磁头),1 sector(1扇区)的内容经过简单判断后,加载到内存中指定位置,然后跳转至该位置运行。MBR大小为512bytes,其中主要存放引导程序和该硬盘的分区表。
(2)GRUB:”GRand Unified Bootloader”:多重操作系统启动管理器,通过运行GRUB来引导进入操作系统。
(3)启动过程为:首先启动到BIOS,然后检测硬盘的MBR,将MBR该扇区的内容(也就是写在上面的GRUB)装入内存运行,再通过GRUB来引导操作系统。
(4)grub2分为2部分,一部分在MBR上,一部分在操作系统的/boot/grub下。如果进入引导界面,没有发现启动选项,而只有grub rescue,则可以通过交互找到另外一部分进行启动。操作流程如下: Ubuntu——grub rescue 主引导修复 
参考:从失败的 Linux 引导中恢复

3.2 MBR修复命令行工具 grub-install

我的情况是grub rescue都被搞的无法显示了,只能通过其他方法来做。
grub-install可以将grub写入到磁盘的MBR中,但是我没有尝试成功,报错说:path ‘/boot/grub’ is not readable by GRUB on boot ,Installation is impossible 问题
然后看国外网友说Boot-Repair可以修复。
参考:GRUB配置的安装和写入硬盘的MBR
Linux中安装GRUB的两种方式

3.3 图形工具Boot-Repair

Boot-Repair是Ubuntu下一款修复启动项的图形工具,需要增加ppa,通过网络安装,由于无法成功添加ppa,没能尝试成功。后面看可以下载镜像安装。
参考:Boot Repair-能一键修复ubuntu启动/引导项的软件

3.4 图形工具 easyBCD与bootice

easyBCD是windows下一款修复启动项工具,尝试了一下,可以成功制作windows与linux双启动项,但是由于sdb5始终无法识别挂载,且它制作的启动项不是想要的grub2。
bootice也是win下的修复启动项工具,但局限于修复windows的开机启动,没找到grub2的启动修复选项,win下的修复做的很好。

3.5 磁盘修复命令 e2fsck

e2fsck能检查坏轨,并能自动修复磁盘错误,检查时不能挂载磁盘。使用e2fsck -a /dev/sdb5可以检查磁盘错误并自动修复。
参考:Linux磁盘修复e2fsck命令

3.6 磁盘修复命令 fsck

fsck也是磁盘修改命令,检查时也不能挂载磁盘。使用fsck.ext4 /dev/sdb5可以检查磁盘错误并自动修复。运行这条命令后,出现很多问题,确认后修复。再尝试挂载sdb5,成功挂载,并且能显示分区里的文件。
参考:修复被破坏了的linux文件系统分区表

首先安装fcitx

一、检测是否安装fcitx

首先检测是否有fcitx,因为搜狗拼音依赖fcitx

> fcitx

提示:

程序“fcitx”尚未安装。 您可以使用以下命令安装:

> sudo apt-get install fcitx-bin

 

二、安装fcitx

sudo apt-get install fcitx-bin

相关的依赖库和框架都会自动安装上。

sudo apt-get install fcitx-table

安装输入法

三、配置fcitx

默认iBus(非常难用),前面我们说过了,安装完fcixt后你尽可以如意地在 键盘输入方式系统 处把它替换为fcitx(如下图)。然后重启Ubuntu。

四、选择需要的输入法

点击Ubuntu右上角顶栏的小键盘图标中打开,配置,如下图:

配置之后,就可以使用拼音输入了。

五、安装搜狗拼音

访问搜狗输入法For Linux

https://pinyin.sogou.com/linux/?r=pinyin

点击立即下载64bit,下载安装文件。

下载后,双击下载的文件。

点击安装,输入密码,就可以安装了。安装完成重启Ubuntu。

重启后,点击右上角小键盘-设置,调整一下输入法顺序。熟悉的输入感觉就来了。

更改设置,点击输入操作条上的扳手按钮,可以设置皮肤,设置熟悉的习惯,还可以登录个人中心,同步个人词库。

这个canScrollVertically方法有两个坑

    /**
     * Check if this view can be scrolled vertically in a certain direction.
     *
     * @param direction Negative to check scrolling up, positive to check scrolling down.
     * @return true if this view can be scrolled in the specified direction, false otherwise.
     */
    public boolean canScrollVertically(int direction) {
        final int offset = computeVerticalScrollOffset();
        final int range = computeVerticalScrollRange() - computeVerticalScrollExtent();
        if (range == 0) return false;
        if (direction < 0) {
            return offset > 0;
        } else {
            return offset < range - 1;
        }
    }

第一个坑:

注释的翻译是这样的:

检查此视图是否可以在某个方向上垂直滚动,
@param direction负值检查向上滚动,正向检查向下滚动。
@return如果此视图可以在指定方向滚动,则为true,否则为false

然而实际上,我把传入的direction设为负值,才是判断手指能否向下滑动,正值是判断手指能否向上滑动。不知道是不是作者对这个“滚动”的对象或者坐标系跟我理解的不同,总之,在我看来,这个注释和代码效果是完全相反的。

 

第二个坑,当recyclerview第一项是空布局的时候,包括本身是gone,高度是0 等等情况,都会导致用canScrollVertically(-1)始终返回true。也就是滑到顶部,不能在继续滑动的时候,这个方法仍然认为还可以继续滑动。

简直是大坑!!!这么常用的代码有这种问题,还不在注释中说明!不一点点debug源码,根本找不到原因。

知道了原因后,解决起来就很简单了,在原有布局外面嵌套一层布局,加上minHeight="1px"属性即可。

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:minHeight="1px"
    >
    <ExampleView
        android:id="@+id/example_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        />
</FrameLayout>

 

1. 关于Vim

vim是我最喜欢的编辑器,也是Linux下第二强大的编辑器。 虽然emacs是公认的世界第一,我认为使用emacs并没有使用vi进行编辑来得高效。 如果是初学vi,运行一下vimtutor是个聪明的决定。 (如果你的系统环境不是中文,而你想使用中文的vimtutor,就运行vimtutor zh)

1.1 Vim的几种模式

  • 正常模式:可以使用快捷键命令,或按:输入命令行。
  • 插入模式:可以输入文本,在正常模式下,按i、a、o等都可以进入插入模式。
  • 可视模式:正常模式下按v可以进入可视模式, 在可视模式下,移动光标可以选择文本。按V进入可视行模式, 总是整行整行的选中。ctrl+v进入可视块模式。
  • 替换模式:正常模式下,按R进入。

 

2. 启动Vim

  • vim -c cmd file: 在打开文件前,先执行指定的命令;
  • vim -r file: 恢复上次异常退出的文件;
  • vim -R file: 以只读的方式打开文件,但可以强制保存;
  • vim -M file: 以只读的方式打开文件,不可以强制保存;
  • vim -y num file: 将编辑窗口的大小设为num行;
  • vim + file: 从文件的末尾开始;
  • vim +num file: 从第num行开始;
  • vim +/string file: 打开file,并将光标停留在第一个找到的string上。
  • vim –remote file: 用已有的vim进程打开指定的文件。 如果你不想启用多个vim会话,这个很有用。但要注意, 如果你用vim,会寻找名叫VIM的服务器;如果你已经有一个gvim在运行了, 你可以用gvim –remote file在已有的gvim中打开文件。

3. 文档操作

  • :e file –关闭当前编辑的文件,并开启新的文件。 如果对当前文件的修改未保存,vi会警告。
  • :e! file –放弃对当前文件的修改,编辑新的文件。
  • :e+file – 开始新的文件,并从文件尾开始编辑。
  • :e+n file – 开始新的文件,并从第n行开始编辑。
  • :enew –编译一个未命名的新文档。(CTRL-W n)
  • :e – 重新加载当前文档。
  • :e! – 重新加载当前文档,并丢弃已做的改动。
  • :e#或ctrl+^ – 回到刚才编辑的文件,很实用。
  • :f或ctrl+g – 显示文档名,是否修改,和光标位置。
  • :f filename – 改变编辑的文件名,这时再保存相当于另存为。
  • gf – 打开以光标所在字符串为文件名的文件。
  • :w – 保存修改。
  • :n1,n2w filename – 选择性保存从某n1行到另n2行的内容。
  • :wq – 保存并退出。
  • ZZ – 保存并退出。
  • :x – 保存并退出。
  • :q[uit] ——退出当前窗口。(CTRL-W q或CTRL-W CTRL-Q)
  • :saveas newfilename – 另存为
  • :browse e – 会打开一个文件浏览器让你选择要编辑的文件。 如果是终端中,则会打开netrw的文件浏览窗口; 如果是gvim,则会打开一个图形界面的浏览窗口。 实际上:browse后可以跟任何编辑文档的命令,如sp等。 用browse打开的起始目录可以由browsedir来设置:
    • :set browsedir=last – 用上次访问过的目录(默认);
    • :set browsedir=buffer – 用当前文件所在目录;
    • :set browsedir=current – 用当前工作目录;
  • :Sex – 水平分割一个窗口,浏览文件系统;
  • :Vex – 垂直分割一个窗口,浏览文件系统;

4. 光标的移动

4.1 基本移动

以下移动都是在normal模式下。

  • h或退格: 左移一个字符;
  • l或空格: 右移一个字符;
  • j: 下移一行;
  • k: 上移一行;
  • gj: 移动到一段内的下一行;
  • gk: 移动到一段内的上一行;
  • +或Enter: 把光标移至下一行第一个非空白字符。
  • -: 把光标移至上一行第一个非空白字符。
  • w: 前移一个单词,光标停在下一个单词开头;
  • W: 移动下一个单词开头,但忽略一些标点;
  • e: 前移一个单词,光标停在下一个单词末尾;
  • E: 移动到下一个单词末尾,如果词尾有标点,则移动到标点;
  • b: 后移一个单词,光标停在上一个单词开头;
  • B: 移动到上一个单词开头,忽略一些标点;
  • ge: 后移一个单词,光标停在上一个单词末尾;
  • gE: 同 ge ,不过‘单词’包含单词相邻的标点。
  • (: 前移1句。
  • ): 后移1句。
  • {: 前移1段。
  • }: 后移1段。
  • fc: 把光标移到同一行的下一个c字符处
  • Fc: 把光标移到同一行的上一个c字符处
  • tc: 把光标移到同一行的下一个c字符前
  • Tc: 把光标移到同一行的上一个c字符后
  • ;: 配合f & t使用,重复一次
  • ,: 配合f & t使用,反向重复一次

上面的操作都可以配合n使用,比如在正常模式(下面会讲到)下输入3h, 则光标向左移动3个字符。

  • 0: 移动到行首。
  • g0: 移到光标所在屏幕行行首。
  • ^: 移动到本行第一个非空白字符。
  • g^: 同 ^ ,但是移动到当前屏幕行第一个非空字符处。
  • : 移动光标所在屏幕行行尾。
  • n|: 把光标移到递n列上。
  • nG: 到文件第n行。
  • :n<cr> 移动到第n行。
  • :$<cr> 移动到最后一行。
  • H: 把光标移到屏幕最顶端一行。
  • M: 把光标移到屏幕中间一行。
  • L: 把光标移到屏幕最底端一行。
  • gg: 到文件头部。
  • G: 到文件尾部。

4.2 翻屏

  • ctrl+f: 下翻一屏。
  • ctrl+b: 上翻一屏。
  • ctrl+d: 下翻半屏。
  • ctrl+u: 上翻半屏。
  • ctrl+e: 向下滚动一行。
  • ctrl+y: 向上滚动一行。
  • n%: 到文件n%的位置。
  • zz: 将当前行移动到屏幕中央。
  • zt: 将当前行移动到屏幕顶端。
  • zb: 将当前行移动到屏幕底端。

4.3 标记

使用标记可以快速移动。到达标记后,可以用Ctrl+o返回原来的位置。 Ctrl+o和Ctrl+i 很像浏览器上的 后退 和 前进 。

  • m{a-z}: 标记光标所在位置,局部标记,只用于当前文件。
  • m{A-Z}: 标记光标所在位置,全局标记。标记之后,退出Vim, 重新启动,标记仍然有效。
  • `{a-z}: 移动到标记位置。
  • ‘{a-z}: 移动到标记行的行首。
  • `{0-9}:回到上[2-10]次关闭vim时最后离开的位置。
  • “: 移动到上次编辑的位置。”也可以,不过“精确到列,而”精确到行 。如果想跳转到更老的位置,可以按C-o,跳转到更新的位置用C-i。
  • `”: 移动到上次离开的地方。
  • `.: 移动到最后改动的地方。
  • :marks 显示所有标记。
  • :delmarks a b – 删除标记a和b。
  • :delmarks a-c – 删除标记a、b和c。
  • :delmarks a c-f – 删除标记a、c、d、e、f。
  • :delmarks! – 删除当前缓冲区的所有标记。
  • :help mark-motions 查看更多关于mark的知识。

 

5. 插入文本

5.1 基本插入

  • i: 在光标前插入;一个小技巧:按8,再按i,进入插入模式,输入=, 按esc进入命令模式,就会出现8个=。 这在插入分割线时非常有用,如30i+<esc>就插入了36个+组成的分割线。
  • I: 在当前行第一个非空字符前插入;
  • gI: 在当前行第一列插入;
  • a: 在光标后插入;
  • A: 在当前行最后插入;
  • o: 在下面新建一行插入;
  • O: 在上面新建一行插入;
  • :r filename在当前位置插入另一个文件的内容。
  • :[n]r filename在第n行插入另一个文件的内容。
  • :r !date 在光标处插入当前日期与时间。同理,:r !command可以将其它shell命令的输出插入当前文档。

5.2 改写插入

  • c[n]w: 改写光标后1(n)个词。
  • c[n]l: 改写光标后n个字母。
  • c[n]h: 改写光标前n个字母。
  • [n]cc: 修改当前[n]行。
  • [n]s: 以输入的文本替代光标之后1(n)个字符,相当于c[n]l。
  • [n]S: 删除指定数目的行,并以所输入文本代替之。

注意,类似cnw,dnw,ynw的形式同样可以写为ncw,ndw,nyw。

 

6. 剪切复制和寄存器

6.1 剪切和复制、粘贴

  • [n]x: 剪切光标右边n个字符,相当于d[n]l。
  • [n]X: 剪切光标左边n个字符,相当于d[n]h。
  • y: 复制在可视模式下选中的文本。
  • yy or Y: 复制整行文本。
  • y[n]w: 复制一(n)个词。
  • y[n]l: 复制光标右边1(n)个字符。
  • y[n]h: 复制光标左边1(n)个字符。
  • yor D: 删除(剪切)当前位置到行尾的内容。
  • d[n]w: 删除(剪切)1(n)个单词
  • d[n]l: 删除(剪切)光标右边1(n)个字符。
  • d[n]h: 删除(剪切)光标左边1(n)个字符。
  • d0: 删除(剪切)当前位置到行首的内容
  • [n] dd: 删除(剪切)1(n)行。
  • :m,nd<cr> 剪切m行到n行的内容。
  • d1G或dgg: 剪切光标以上的所有行。
  • dG: 剪切光标以下的所有行。
  • daw和das:剪切一个词和剪切一个句子,即使光标不在词首和句首也没关系。
  • d/f<cr>:这是一个比较高级的组合命令,它将删除当前位置 到下一个f之间的内容。
  • p: 在光标之后粘贴。
  • P: 在光标之前粘贴。

6.2 文本对象

  • aw:一个词
  • as:一句。
  • ap:一段。
  • ab:一块(包含在圆括号中的)。

y, d, c, v都可以跟文本对象。

6.3 寄存器

  • a-z:都可以用作寄存器名。”ayy把当前行的内容放入a寄存器。
  • A-Z:用大写字母索引寄存器,可以在寄存器中追加内容。 如”Ayy把当前行的内容追加到a寄存器中。
  • :reg 显示所有寄存器的内容。
  • “”:不加寄存器索引时,默认使用的寄存器。
  • “*:当前选择缓冲区,”*yy把当前行的内容放入当前选择缓冲区。
  • “+:系统剪贴板。”+yy把当前行的内容放入系统剪贴板。

 

7. 查找与替换

7.1 查找

  • /something: 在后面的文本中查找something。
  • ?something: 在前面的文本中查找something。
  • /pattern/+number: 将光标停在包含pattern的行后面第number行上。
  • /pattern/-number: 将光标停在包含pattern的行前面第number行上。
  • n: 向后查找下一个。
  • N: 向前查找下一个。

可以用grep或vimgrep查找一个模式都在哪些地方出现过,

其中:grep是调用外部的grep程序,而:vimgrep是vim自己的查找算法。

用法为: :vim[grep]/pattern/[g] [j] files

g的含义是如果一个模式在一行中多次出现,则这一行也在结果中多次出现。

j的含义是grep结束后,结果停在第j项,默认是停在第一项。

vimgrep前面可以加数字限定搜索结果的上限,如

:1vim/pattern/ % 只查找那个模式在本文件中的第一个出现。

 

其实vimgrep在读纯文本电子书时特别有用,可以生成导航的目录。

比如电子书中每一节的标题形式为:n. xxxx。你就可以这样:

:vim/^d{1,}./ %

然后用:cw或:copen查看结果,可以用C-w H把quickfix窗口移到左侧,

就更像个目录了。

 

7.2 替换

  • :s/old/new - 用new替换当前行第一个old。
  • :s/old/new/g - 用new替换当前行所有的old。
  • :n1,n2s/old/new/g - 用new替换文件n1行到n2行所有的old。
  • :%s/old/new/g - 用new替换文件中所有的old。
  • :%s/^/xxx/g - 在每一行的行首插入xxx,^表示行首。
  • :%s/表示行尾。
  • 所有替换命令末尾加上c,每个替换都将需要用户确认。 如:%s/old/new/gc,加上i则忽略大小写(ignore)。

还有一种比替换更灵活的方式,它是匹配到某个模式后执行某种命令,

语法为 :[range]g/pattern/command

例如 :%g/^ xyz/normal dd。

表示对于以一个空格和xyz开头的行执行normal模式下的dd命令。

关于range的规定为:

  • 如果不指定range,则表示当前行。
  • m,n: 从m行到n行。
  • 0: 最开始一行(可能是这样)。
  • $: 最后一行
  • .: 当前行
  • %: 所有行

 

7.3 正则表达式

高级的查找替换就要用到正则表达式。

  • \d: 表示十进制数(我猜的)
  • \s: 表示空格
  • \S: 非空字符
  • \a: 英文字母
  • \|: 表示 或
  • \.: 表示.
  • {m,n}: 表示m到n个字符。这要和 \s与\a等连用,如 \a\{m,n} 表示m 到n个英文字母。
  • {m,}: 表示m到无限多个字符。
  • **: 当前目录下的所有子目录。

:help pattern得到更多帮助。

 


8. 排版

8.1 基本排版

  • << 向左缩进一个shiftwidth
  • >> 向右缩进一个shiftwidth
  • :ce(nter) 本行文字居中
  • :le(ft) 本行文字靠左
  • :ri(ght) 本行文字靠右
  • gq 对选中的文字重排,即对过长的文字进行断行
  • gqq 重排当前行
  • gqnq 重排n行
  • gqap 重排当前段
  • gqnap 重排n段
  • gqnj 重排当前行和下面n行
  • gqQ 重排当前段对文章末尾
  • J 拼接当前行和下一行
  • gJ 同 J ,不过合并后不留空格。

8.2 拼写检查

  • :set spell-开启拼写检查功能
  • :set nospell-关闭拼写检查功能
  • ]s-移到下一个拼写错误的单词
  • [s-作用与上一命令类似,但它是从相反方向进行搜索
  • z=-显示一个有关拼写错误单词的列表,可从中选择
  • zg-告诉拼写检查器该单词是拼写正确的
  • zw-与上一命令相反,告诉拼写检查器该单词是拼写错误的

8.3 统计字数

g ^g可以统计文档字符数,行数。 将光标放在最后一个字符上,用字符数减去行数可以粗略统计中文文档的字数。 以上对 Mac 或 Unix 的文件格式适用。 如果是 Windows 文件格式(即换行符有两个字节),字数的统计方法为: 字符数 - 行数 * 2。

 


9. 编辑多个文件

9.1 一次编辑多个文件

我们可以一次打开多个文件,如

vi a.txt b.txt c.txt
  • 使用:next(:n)编辑下一个文件。
  • :2n 编辑下2个文件。
  • 使用:previous或:N编辑上一个文件。
  • 使用:wnext,保存当前文件,并编辑下一个文件。
  • 使用:wprevious,保存当前文件,并编辑上一个文件。
  • 使用:args 显示文件列表。
  • :n filenames或:args filenames 指定新的文件列表。
  • vi -o filenames 在水平分割的多个窗口中编辑多个文件。
  • vi -O filenames 在垂直分割的多个窗口中编辑多个文件。

9.2 多标签编辑

  • vim -p files: 打开多个文件,每个文件占用一个标签页。
  • :tabe, tabnew – 如果加文件名,就在新的标签中打开这个文件, 否则打开一个空缓冲区。
  • ^w gf – 在新的标签页里打开光标下路径指定的文件。
  • :tabn – 切换到下一个标签。Control + PageDown,也可以。
  • :tabp – 切换到上一个标签。Control + PageUp,也可以。
  • [n] gt – 切换到下一个标签。如果前面加了 n , 就切换到第n个标签。第一个标签的序号就是1。
  • :tab split – 将当前缓冲区的内容在新页签中打开。
  • :tabc[lose] – 关闭当前的标签页。
  • :tabo[nly] – 关闭其它的标签页。
  • :tabs – 列出所有的标签页和它们包含的窗口。
  • :tabm[ove] [N] – 移动标签页,移动到第N个标签页之后。 如 tabm 0 当前标签页,就会变成第一个标签页。

9.3 缓冲区

  • :buffers或:ls或:files 显示缓冲区列表。
  • ctrl+^:在最近两个缓冲区间切换。
  • :bn – 下一个缓冲区。
  • :bp – 上一个缓冲区。
  • :bl – 最后一个缓冲区。
  • :b[n]或:[n]b – 切换到第n个缓冲区。
  • :nbw(ipeout) – 彻底删除第n个缓冲区。
  • :nbd(elete) – 删除第n个缓冲区,并未真正删除,还在unlisted列表中。
  • :ba[ll] – 把所有的缓冲区在当前页中打开,每个缓冲区占一个窗口。

 

10. 分屏编辑

  • vim -o file1 file2:水平分割窗口,同时打开file1和file2
  • vim -O file1 file2:垂直分割窗口,同时打开file1和file2

10.1 水平分割

  • :split(:sp) – 把当前窗水平分割成两个窗口。(CTRL-W s 或 CTRL-W CTRL-S) 注意如果在终端下,CTRL-S可能会冻结终端,请按CTRL-Q继续。
  • :split filename – 水平分割窗口,并在新窗口中显示另一个文件。
  • :nsplit(:nsp) – 水平分割出一个n行高的窗口。
  • :[N]new – 水平分割出一个N行高的窗口,并编辑一个新文件。 (CTRL-W n或 CTRL-W CTRL-N)
  • ctrl+w f –水平分割出一个窗口,并在新窗口打开名称为光标所在词的文件 。
  • C-w C-^ – 水平分割一个窗口,打开刚才编辑的文件。

10.2 垂直分割

  • :vsplit(:vsp) – 把当前窗口分割成水平分布的两个窗口。 (CTRL-W v或CTRL CTRL-V)
  • :[N]vne[w] – 垂直分割出一个新窗口。
  • :vertical 水平分割的命令: 相应的垂直分割。

10.3 关闭子窗口

  • :qall – 关闭所有窗口,退出vim。
  • :wall – 保存所有修改过的窗口。
  • :only – 只保留当前窗口,关闭其它窗口。(CTRL-W o)
  • :close – 关闭当前窗口,CTRL-W c能实现同样的功能。 (象 :q :x同样工作 )

10.4 调整窗口大小

  • ctrl+w + –当前窗口增高一行。也可以用n增高n行。
  • ctrl+w - –当前窗口减小一行。也可以用n减小n行。
  • ctrl+w _ –当前窗口扩展到尽可能的大。也可以用n设定行数。
  • :resize n – 当前窗口n行高。
  • ctrl+w = – 所有窗口同样高度。
  • n ctrl+w _ – 当前窗口的高度设定为n行。
  • ctrl+w < –当前窗口减少一列。也可以用n减少n列。
  • ctrl+w > –当前窗口增宽一列。也可以用n增宽n列。
  • ctrl+w | –当前窗口尽可能的宽。也可以用n设定列数。

10.5 切换和移动窗口

如果支持鼠标,切换和调整子窗口的大小就简单了。

  • ctrl+w ctrl+w: 切换到下一个窗口。或者是ctrl+w w。
  • ctrl+w p: 切换到前一个窗口。
  • ctrl+w h(l,j,k):切换到左(右,下,上)的窗口。
  • ctrl+w t(b):切换到最上(下)面的窗口。<BR>
  • ctrl+w H(L,K,J): 将当前窗口移动到最左(右、上、下)面。
  • ctrl+w r:旋转窗口的位置。
  • ctrl+w T: 将当前的窗口移动到新的标签页上。

 

11. 快速编辑

11.1 改变大小写

  • ~: 反转光标所在字符的大小写。
  • 可视模式下的U或u:把选中的文本变为大写或小写。
  • gu(U)接范围(如$,或G),可以把从光标当前位置到指定位置之间字母全部 转换成小写或大写。如ggguG,就是把开头到最后一行之间的字母全部变为小 写。再如gu5j,把当前行和下面四行全部变成小写。

11.2 替换(normal模式)

  • r: 替换光标处的字符,同样支持汉字。
  • R: 进入替换模式,按esc回到正常模式。

11.3 撤消与重做(normal模式)

  • [n] u: 取消一(n)个改动。
  • :undo 5 – 撤销5个改变。
  • :undolist – 你的撤销历史。
  • ctrl + r: 重做最后的改动。
  • U: 取消当前行中所有的改动。
  • :earlier 4m – 回到4分钟前
  • :later 55s – 前进55秒

11.4 宏

  • . –重复上一个编辑动作
  • qa:开始录制宏a(键盘操作记录)
  • q:停止录制
  • @a:播放宏a

 

12. 编辑特殊文件

12.1 文件加解密

  • vim -x file: 开始编辑一个加密的文件。
  • :X – 为当前文件设置密码。
  • :set key= – 去除文件的密码。

这里是 滇狐总结的比较高级的vi技巧。

12.2 文件的编码

  • :e ++enc=utf8 filename, 让vim用utf-8的编码打开这个文件。
  • :w ++enc=gbk,不管当前文件什么编码,把它转存成gbk编码。
  • :set fenc或:set fileencoding,查看当前文件的编码。
  • 在vimrc中添加set fileencoding=ucs-bom,utf-8,cp936,vim会根据要打开的文件选择合适的编码。 注意:编码之间不要留空格。 cp936对应于gbk编码。 ucs-bom对应于windows下的文件格式。

让vim 正确处理文件格式和文件编码,有赖于 ~/.vimrc的正确配置

12.3 文件格式

大致有三种文件格式:unix, dos, mac. 三种格式的区别主要在于回车键的编码:dos 下是回车加换行,unix 下只有 换行符,mac 下只有回车符。

  • :e ++ff=dos filename, 让vim用dos格式打开这个文件。
  • :w ++ff=mac filename, 以mac格式存储这个文件。
  • :set ff,显示当前文件的格式。
  • 在vimrc中添加set fileformats=unix,dos,mac,让vim自动识别文件格式。

 

13. 编程辅助

13.1 一些按键

  • gd: 跳转到局部变量的定义处;
  • gD: 跳转到全局变量的定义处,从当前文件开头开始搜索;
  • g;: 上一个修改过的地方;
  • g,: 下一个修改过的地方;
  • [[: 跳转到上一个函数块开始,需要有单独一行的{。
  • ]]: 跳转到下一个函数块开始,需要有单独一行的{。
  • []: 跳转到上一个函数块结束,需要有单独一行的}。
  • ][: 跳转到下一个函数块结束,需要有单独一行的}。
  • [{: 跳转到当前块开始处;
  • ]}: 跳转到当前块结束处;
  • [/: 跳转到当前注释块开始处;
  • ]/: 跳转到当前注释块结束处;
  • %: 不仅能移动到匹配的(),{}或[]上,而且能在#if,#else, #endif之间跳跃。

下面的括号匹配对编程很实用的。

  • ci’, di’, yi’:修改、剪切或复制’之间的内容。
  • ca’, da’, ya’:修改、剪切或复制’之间的内容,包含’。
  • ci”, di”, yi”:修改、剪切或复制”之间的内容。
  • ca”, da”, ya”:修改、剪切或复制”之间的内容,包含”。
  • ci(, di(, yi(:修改、剪切或复制()之间的内容。
  • ca(, da(, ya(:修改、剪切或复制()之间的内容,包含()。
  • ci[, di[, yi[:修改、剪切或复制[]之间的内容。
  • ca[, da[, ya[:修改、剪切或复制[]之间的内容,包含[]。
  • ci{, di{, yi{:修改、剪切或复制{}之间的内容。
  • ca{, da{, ya{:修改、剪切或复制{}之间的内容,包含{}。
  • ci<, di<, yi<:修改、剪切或复制<>之间的内容。
  • ca<, da<, ya<:修改、剪切或复制<>之间的内容,包含<>。

13.2 ctags

  • ctags -R: 生成tag文件,-R表示也为子目录中的文件生成tags
  • :set tags=path/tags – 告诉ctags使用哪个tag文件
  • :tag xyz – 跳到xyz的定义处,或者将光标放在xyz上按C-],返回用C-t
  • :stag xyz – 用分割的窗口显示xyz的定义,或者C-w ], 如果用C-w n ],就会打开一个n行高的窗口
  • :ptag xyz – 在预览窗口中打开xyz的定义,热键是C-w }。
  • :pclose – 关闭预览窗口。热键是C-w z。
  • :pedit abc.h – 在预览窗口中编辑abc.h
  • :psearch abc – 搜索当前文件和当前文件include的文件,显示包含abc的行。

有时一个tag可能有多个匹配,如函数重载,一个函数名就会有多个匹配。 这种情况会先跳转到第一个匹配处。

  • :[n]tnext – 下一[n]个匹配。
  • :[n]tprev – 上一[n]个匹配。
  • :tfirst – 第一个匹配
  • :tlast – 最后一个匹配
  • :tselect tagname – 打开选择列表

tab键补齐

  • :tag xyz<tab> – 补齐以xyz开头的tag名,继续按tab键,会显示其他的。
  • :tag /xyz<tab> – 会用名字中含有xyz的tag名补全。

13.3 cscope

  • cscope -Rbq: 生成cscope.out文件
  • :cs add /path/to/cscope.out /your/work/dir
  • :cs find c func – 查找func在哪些地方被调用
  • :cw – 打开quickfix窗口查看结果

13.4 gtags

Gtags综合了ctags和cscope的功能。 使用Gtags之前,你需要安装GNU Gtags。 然后在工程目录运行 gtags 。

  • :Gtags funcname 定位到 funcname 的定义处。
  • :Gtags -r funcname 查询 funcname被引用的地方。
  • :Gtags -s symbol 定位 symbol 出现的地方。
  • :Gtags -g string Goto string 出现的地方。 :Gtags -gi string 忽略大小写。
  • :Gtags -f filename 显示 filename 中的函数列表。 你可以用 :Gtags -f % 显示当前文件。
  • :Gtags -P pattern 显示路径中包含特定模式的文件。 如 :Gtags -P .h$ 显示所有头文件, :Gtags -P /vm/ 显示vm目录下的文件。

13.5 编译

vim提供了:make来编译程序,默认调用的是make, 如果你当前目录下有makefile,简单地:make即可。

如果你没有make程序,你可以通过配置makeprg选项来更改make调用的程序。 如果你只有一个abc.Java文件,你可以这样设置:

set makeprg=javac\ abc.java

然后:make即可。如果程序有错,可以通过quickfix窗口查看错误。 不过如果要正确定位错误,需要设置好errorformat,让vim识别错误信息。 如:

:setl efm=%A%f:%l:\ %m,%-Z%p^,%-C%.%#

%f表示文件名,%l表示行号, %m表示错误信息,其它的还不能理解。 请参考 :help errorformat。

13.6 快速修改窗口

其实是quickfix插件提供的功能, 对编译调试程序非常有用 :)

  • :copen – 打开快速修改窗口。
  • :cclose – 关闭快速修改窗口。

快速修改窗口在make程序时非常有用,当make之后:

  • :cl – 在快速修改窗口中列出错误。
  • :cn – 定位到下一个错误。
  • :cp – 定位到上一个错误。
  • :cr – 定位到第一个错误。

13.7 自动补全

  • C-x C-s – 拼写建议。
  • C-x C-v – 补全vim选项和命令。
  • C-x C-l – 整行补全。
  • C-x C-f – 自动补全文件路径。弹出菜单后,按C-f循环选择,当然也可以按 C-n和C-p。
  • C-x C-p 和C-x C-n – 用文档中出现过的单词补全当前的词。 直接按C-p和C-n也可以。
  • C-x C-o – 编程时可以补全关键字和函数名啊。
  • C-x C-i – 根据头文件内关键字补全。
  • C-x C-d – 补全宏定义。
  • C-x C-n – 按缓冲区中出现过的关键字补全。 直接按C-n或C-p即可。

当弹出补全菜单后:

  • C-p 向前切换成员;
  • C-n 向后切换成员;
  • C-e 退出下拉菜单,并退回到原来录入的文字;
  • C-y 退出下拉菜单,并接受当前选项。

13.8 多行缩进缩出

  • 正常模式下,按两下>;光标所在行会缩进。
  • 如果先按了n,再按两下>;,光标以下的n行会缩进。
  • 对应的,按两下<;,光标所在行会缩出。
  • 如果在编辑代码文件,可以用=进行调整。
  • 在可视模式下,选择要调整的代码块,按=,代码会按书写规则缩排好。
  • 或者n =,调整n行代码的缩排。

13.9 折叠

  • zf – 创建折叠的命令,可以在一个可视区域上使用该命令;
  • zd – 删除当前行的折叠;
  • zD – 删除当前行的折叠;
  • zfap – 折叠光标所在的段;
  • zo – 打开折叠的文本;
  • zc – 收起折叠;
  • za – 打开/关闭当前折叠;
  • zr – 打开嵌套的折行;
  • zm – 收起嵌套的折行;
  • zR (zO) – 打开所有折行;
  • zM (zC) – 收起所有折行;
  • zj – 跳到下一个折叠处;
  • zk – 跳到上一个折叠处;
  • zi – enable/disable fold;

 

14. 命令行

normal模式下按:进入命令行模式

14.1 命令行模式下的快捷键:

  • 上下方向键:上一条或者下一条命令。如果已经输入了部分命令,则找上一 条或者下一条匹配的命令。
  • 左右方向键:左/右移一个字符。
  • C-w: 向前删除一个单词。
  • C-h: 向前删除一个字符,等同于Backspace。
  • C-u: 从当前位置移动到命令行开头。
  • C-b: 移动到命令行开头。
  • C-e: 移动到命令行末尾。
  • Shift-Left: 左移一个单词。
  • Shift-Right: 右移一个单词。
  • @: 重复上一次的冒号命令。
  • q: 正常模式下,q然后按’:’,打开命令行历史缓冲区, 可以像编辑文件一样编辑命令。
  • q/和q? 可以打开查找历史记录。

14.2 执行外部命令

  • :! cmd 执行外部命令。
  • :!! 执行上一次的外部命令。
  • :sh 调用shell,用exit返回vim。
  • :r !cmd 将命令的返回结果插入文件当前位置。
  • :m,nw !cmd 将文件的m行到n行之间的内容做为命令输入执行命令。

 

15. 其它

15.1 工作目录

  • :pwd 显示vim的工作目录。
  • :cd path 改变vim的工作目录。
  • :set autochdir 可以让vim 根据编辑的文件自动切换工作目录。

15.2 一些快捷键(收集中)

  • K: 打开光标所在词的manpage。
  • *: 向下搜索光标所在词。
  • g*: 同上,但部分符合即可。
  • #: 向上搜索光标所在词。
  • g#: 同上,但部分符合即可。
  • g C-g: 统计全文或统计部分的字数。

15.3 在线帮助

  • :h(elp)或F1 打开总的帮助。
  • :help user-manual 打开用户手册。
  • 命令帮助的格式为:第一行指明怎么使用那个命令; 然后是缩进的一段解释这个命令的作用,然后是进一步的信息。
  • :helptags somepath 为somepath中的文档生成索引。
  • :helpgrep 可以搜索整个帮助文档,匹配的列表显示在quickfix窗口中。
  • Ctrl+] 跳转到tag主题,Ctrl+t 跳回。
  • :ver 显示版本信息。

15.4 一些小功能

  • 简单计算器: 在插入模式下,输入C-r =,然后输入表达式,就能在 光标处得到计算结果。