牛人必修 Ant编译android工程 ,并Proguard代码混淆,v4混淆配置
一,准备ant
ant 官网可下载
http://ant.apache.org/
ant 环境配置:
1。解压ant的包到本地目录。
2。在环境变量中设置ANT_HOME,值为你的安装目录。
3。把ANT_HOME/bin加到你系统环境的path。
更多的介绍可以去google相信有很多
二,详细步骤和说明,这里我们要知道一些Android命令。
前提条件已配置好android sdk 环境,所以可以在任意目录下执行android 命令,不然则要切换到 android-sdk\tools目录下
我这里已经配置好了,所以无论我在什么路径下了。
1.创建一个android项目
参数说明:
-k /--package 为命名空间(包名)-a /--name 工程名
-p /--path 项目 -t 为目标平台的版本编号
C:\Documents and Settings\Administrator>android create project -k com.android.Ta
nk -a Tank -t 4 -p F:\tank
列出不同版本平台的对应id编号 android.bat list targets /android list
C:\Documents and Settings\Administrator>android.bat list targets
对已经存在的android工程,我们可以update下(修改平台的版本),这样会自动添加build.xml 等ant 的配置文件
C:\Documents and Settings\Administrator>android update project --name Tank -t 11
-p F:\tank
编译:直接ant 是不会有文件输出的,所以后面一定要带上参数
ant 参数如下:
* debug:带调试用签名的构建
* release:构建应用程序,生成的apk必须签名才可以发布
* install:安装调试构建的包到运行着的模拟器或者设备;
* reinstall
* uninstall
开始执行编译:
E:\MyLiB\Android\AndroidAnt\MyBoardCastReciver>ant debug
Buildfile: E:\MyLiB\Android\AndroidAnt\MyBoardCastReciver\build.xml
[setup] Android SDK Tools Revision 7
[setup] Project Target: Android 2.2
[setup] API level: 8
[setup]
[setup] ------------------
[setup] Resolving library dependencies:
[setup] ------------------
[setup] Ordered libraries:
[setup] ------------------
[setup]
[setup] WARNING: No minSdkVersion value set. Application will install on all
Android versions.
[setup]
[setup] Importing rules file: tools\ant\ant_rules_r3.xml
[javac]****警告:编码 ascii 的不可映射字符********
出现“警告:编码 ascii 的不可映射字符”错误
编译乱码解决办法:
查看输出提示:
[setup] Importing rules file: tools\ant\ant_rules_r3.xml
找到sdk目录下的
打开找到节点:
把ascii改为gbk即可。
启动相应模拟器:emulator -avd avdName
E:\MyLiB\Android\AndroidAnt\Toast>emulator -avd tank
列出已有avd 的列表
E:\MyLiB\Android\AndroidAnt\Toast\bin>adb devices
List of devices attached
emulator-5554 device
安装到指定avd
E:\MyLiB\Android\AndroidAnt\Toast\bin>adb -s emulator-5554 install Toast-debug.a
pk
ok ,ant 编译android 并手动安装apk文件就写到这里了。是不是也很COOL!
首先,做任何开发前,肯定是各种环境搭建和配置啊,ant的搭建很简单:
一、安装ant
到官方主页http://ant.apache.org下载新版(目前为Ant-1.9.2)的ant,得到的是一个apache-ant-1.8.1-bin.zip的压缩包。将其解压到你的硬盘上,例如:D:\Android\apache-ant-1.9.2
二、配置环境变量
window中设置ant环境变量:
ANT_HOME D:/Android/apache-ant-1.9.2
path D:/Android/apache-ant-1.9.2/bin
classpath D:/Android/apache-ant-1.9.2/lib
linux中设置ant环境变量:
root用户登陆,用vi编辑器修改root目录下的".bash_profile"属性文件,假设Ant安装在/user/local/ant目录下,要在文件的最后加上
"exportANT_HOME=/user/local/ant"和"export PATH=$PATH:$ANT_HOME/bin"
三、验证ant
为了验证ant是否成功安装,可以进行如下操作:
依次选择:开始->运行->cmd,输入如下命令:ant
如果出现如下内容,说明安装成功:
Buildfile: build.xml does not exist!
Build failed
当然,JAVA_HOME、ANDROID_SDK_HOME等的配置这里就不说了
四、我们就在项目中添加build.xml
code如下:
001 | <? xml version = "1.0" encoding = "utf-8" ?> |
002 | < project |
003 | name = "HappyShopping" |
004 | default = "release" > |
005 |
006 |
|
007 |
008 | < property environment = "env" /> |
009 |
|
010 |
011 | < property |
012 | name = "appName" |
013 | value = "${ant.project.name}" /> |
014 |
|
015 |
016 | < property |
017 | name = "sdk-folder" |
018 | value = "${env.ANDROID_SDK_HOME}" /> |
019 |
|
020 |
021 | < property |
022 | name = "sdk-platform-folder" |
023 | value = "${sdk-folder}/platforms/android-16" /> |
024 |
|
025 |
026 | < property |
027 | name = "sdk-tools" |
028 | value = "${sdk-folder}/tools" /> |
029 |
|
030 |
031 | < property |
032 | name = "sdk-platform-tools" |
033 | value = "${sdk-folder}/platform-tools" /> |
034 |
035 |
|
036 |
037 | < property |
038 | name = "aapt" |
039 | value = "${sdk-platform-tools}/aapt" /> |
040 |
041 | < property |
042 | name = "aidl" |
043 | value = "${sdk-platform-tools}/aidl" /> |
044 |
045 | < property |
046 | name = "dx" |
047 | value = "${sdk-platform-tools}/dx.bat" /> |
048 |
049 | < property |
050 | name = "apkbuilder" |
051 | value = "${sdk-tools}/apkbuilder.bat" /> |
052 |
053 | < property |
054 | name = "jarsigner" |
055 | value = "${env.JAVA_HOME}/bin/jarsigner" /> |
056 |
057 |
|
058 |
059 | < property |
060 | name = "android-jar" |
061 | value = "${sdk-platform-folder}/android.jar" /> |
062 |
063 | < property |
064 | name = "android-maps-jar" |
065 | value = "${sdk-folder}/add-ons/addon_google_apis_google_inc_8/libs/maps.jar" /> |
066 |
067 |
|
068 |
069 | < property |
070 | name = "framework-aidl" |
071 | value = "${sdk-platform-folder}/framework.aidl" /> |
072 |
073 |
|
074 |
075 | < property |
076 | name = "outdir-gen" |
077 | value = "gen" /> |
078 |
|
079 |
080 | < property |
081 | name = "outdir-bin" |
082 | value = "bin" /> |
083 |
084 |
|
085 |
086 | < property |
087 | name = "manifest-xml" |
088 | value = "AndroidManifest.xml" /> |
089 |
|
090 |
091 | < property |
092 | name = "resource-dir" |
093 | value = "res" /> |
094 |
095 | < property |
096 | name = "asset-dir" |
097 | value = "assets" /> |
098 |
|
099 |
100 | < property |
101 | name = "srcdir" |
102 | value = "src" /> |
103 |
104 | < property |
105 | name = "srcdir-ospath" |
106 | value = "${basedir}/${srcdir}" /> |
107 |
|
108 |
109 | < property |
110 | name = "external-lib" |
111 | value = "libs" /> |
112 |
113 | < property |
114 | name = "external-lib-ospath" |
115 | value = "${basedir}/${external-lib}" /> |
116 |
117 |
|
118 |
119 | < property |
120 | name = "outdir-classes" |
121 | value = "${outdir-bin}" /> |
122 |
123 | < property |
124 | name = "outdir-classes-ospath" |
125 | value = "${basedir}/${outdir-classes}" /> |
126 |
127 |
|
128 |
129 | < property |
130 | name = "dex-file" |
131 | value = "classes.dex" /> |
132 |
133 | < property |
134 | name = "dex-path" |
135 | value = "${outdir-bin}/${dex-file}" /> |
136 |
137 | < property |
138 | name = "dex-ospath" |
139 | value = "${basedir}/${dex-path}" /> |
140 |
141 |
|
142 |
143 | < property |
144 | name = "resources-package" |
145 | value = "${outdir-bin}/resources.ap_" /> |
146 |
147 | < property |
148 | name = "resources-package-ospath" |
149 | value = "${basedir}/${resources-package}" /> |
150 |
151 |
|
152 |
153 | < property |
154 | name = "out-unsigned-package" |
155 | value = "${outdir-bin}/${appName}-unsigned.apk" /> |
156 |
157 | < property |
158 | name = "out-unsigned-package-ospath" |
159 | value = "${basedir}/${out-unsigned-package}" /> |
160 |
161 |
|
162 |
163 | < property |
164 | name = "keystore-file" |
165 | value = "${basedir}/naomi" /> |
166 |
167 |
|
168 |
169 | < property |
170 | name = "out-signed-package" |
171 | value = "${outdir-bin}/${appName}.apk" /> |
172 |
173 | < property |
174 | name = "out-signed-package-ospath" |
175 | value = "${basedir}/${out-signed-package}" /> |
176 |
177 |
|
178 | < property |
179 | name = "proguard-home" |
180 | value = "D:/Android/android-sdk-windows/tools/proguard/lib" /> |
181 |
182 | < target name = "init" > |
183 |
184 | < echo > |
185 | Initializing all output directories... |
186 |
echo > |
187 |
188 | < delete dir = "${outdir-bin}" /> |
189 |
190 | < mkdir dir = "${outdir-bin}" /> |
191 |
192 | < mkdir dir = "${outdir-classes}" /> |
193 |
target > |
194 |
195 |
|
196 |
197 | < target |
198 | name = "gen-R" |
199 | depends = "init" > |
200 |
201 | < echo > |
202 | Generating R.java from the resources... |
203 |
echo > |
204 |
205 | < exec |
206 | executable = "${aapt}" |
207 | failonerror = "true" > |
208 |
209 | < arg value = "package" /> |
210 |
211 | < arg value = "-f" /> |
212 |
213 | < arg value = "-m" /> |
214 |
215 | < arg value = "-J" /> |
216 |
217 | < arg value = "${outdir-gen}" /> |
218 |
219 | < arg value = "-S" /> |
220 |
221 | < arg value = "${resource-dir}" /> |
222 |
223 | < arg value = "-M" /> |
224 |
225 | < arg value = "${manifest-xml}" /> |
226 |
227 | < arg value = "-I" /> |
228 |
229 | < arg value = "${android-jar}" /> |
230 |
exec > |
231 |
target > |
232 |
|
233 |
234 | < target |
235 | name = "aidl" |
236 | depends = "gen-R" > |
237 |
238 | < echo > |
239 | Compiling .aidl into java files... |
240 |
echo > |
241 |
242 | < apply |
243 | executable = "${aidl}" |
244 | failonerror = "true" > |
245 |
246 |
|
247 |
248 | < arg value = "-p${framework-aidl}" /> |
249 |
|
250 |
251 | < arg value = "-I${srcdir}" /> |
252 |
|
253 |
254 | < arg value = "-o${outdir-gen}" /> |
255 |
|
256 |
257 | < fileset dir = "${srcdir}" > |
258 |
259 | < include name = "**/*.aidl" /> |
260 |
fileset > |
261 |
apply > |
262 |
target > |
263 |
264 |
|
265 |
266 | < target |
267 | name = "compile" |
268 | depends = "aidl" > |
269 |
270 | < echo > |
271 | Compiling java source code... |
272 |
echo > |
273 |
274 | < javac |
275 | bootclasspath = "${android-jar}" |
276 | destdir = "${outdir-classes}" |
277 | encoding = "utf-8" |
278 | srcdir = "." |
279 | target = "1.5" > |
280 |
281 | < classpath > |
282 |
283 | < fileset |
284 | dir = "${external-lib}" |
285 | includes = "*.jar" /> |
286 |
287 | < filelist > |
288 |
289 | < file name = "${android-maps-jar}" /> |
290 |
filelist > |
291 |
classpath > |
292 |
javac > |
293 |
target > |
294 |
295 |
|
296 |
297 | < target |
298 | name = "proguard" |
299 | depends = "compile" > |
300 | < echo > |
301 | Proguad .... |
302 |
echo > |
303 | < jar |
304 | basedir = "${outdir-classes}" |
305 | destfile = "temp.jar" /> |
306 |
307 | < java |
308 | failonerror = "true" |
309 | fork = "true" |
310 | jar = "${proguard-home}/proguard.jar" > |
311 |
312 | < jvmarg value = "-Dmaximum.inlined.code.length=32" /> |
313 |
314 | < arg value = "-injars temp.jar" /> |
315 |
316 | < arg value = "-outjars optimized.jar" /> |
317 |
318 | < arg value = "-libraryjars ${android-jar}" /> |
319 |
320 | < arg value = "-dontpreverify" /> |
321 |
322 | < arg value = "-dontoptimize" /> |
323 |
324 | < arg value = "-dontusemixedcaseclassnames" /> |
325 |
326 | < arg value = "-repackageclasses ''" /> |
327 |
328 | < arg value = "-allowaccessmodification" /> |
329 |
330 |
|
331 | |
332 | < arg value = "@proguard-project.txt" /> |
333 | |
334 |
335 |
java > |
336 |
337 | < delete file = "temp.jar" /> |
338 |
339 | < delete dir = "${outdir-classes}" /> |
340 |
341 | < mkdir dir = "${outdir-classes}" /> |
342 |
343 | < unzip |
344 | dest = "${outdir-classes}" |
345 | src = "optimized.jar" /> |
346 |
347 | < delete file = "optimized.jar" /> |
348 |
target > |
349 |
350 |
|
351 |
352 | < target |
353 | name = "dex" |
354 | depends = "proguard" > |
355 |
356 | < echo > |
357 | Converting compiled files and external libraries into a .dex file... |
358 |
echo > |
359 |
360 | < exec |
361 | executable = "${dx}" |
362 | failonerror = "true" > |
363 |
364 | < arg value = "--dex" /> |
365 |
|
366 |
367 | < arg value = "--output=${dex-ospath}" /> |
368 |
|
369 |
370 | < arg value = "${outdir-classes-ospath}" /> |
371 |
372 | < arg value = "${external-lib-ospath}" /> |
373 |
exec > |
374 |
target > |
375 |
376 |
|
377 |
378 | < target name = "package-res-and-assets" > |
379 |
380 | < echo > |
381 | Packaging resources and assets... |
382 |
echo > |
383 |
384 | < exec |
385 | executable = "${aapt}" |
386 | failonerror = "true" > |
387 |
388 | < arg value = "package" /> |
389 |
390 | < arg value = "-f" /> |
391 |
392 | < arg value = "-M" /> |
393 |
394 | < arg value = "${manifest-xml}" /> |
395 |
396 | < arg value = "-S" /> |
397 |
398 | < arg value = "${resource-dir}" /> |
399 |
400 | < arg value = "-A" /> |
401 |
402 | < arg value = "${asset-dir}" /> |
403 |
404 | < arg value = "-I" /> |
405 |
406 | < arg value = "${android-jar}" /> |
407 |
408 | < arg value = "-F" /> |
409 |
410 | < arg value = "${resources-package}" /> |
411 |
exec > |
412 |
target > |
413 |
414 |
|
415 |
416 | < target |
417 | name = "package" |
418 | depends = "dex, package-res-and-assets" > |
419 |
420 | < echo > |
421 | Packaging unsigned apk for release... |
422 |
echo > |
423 |
424 | < exec |
425 | executable = "${apkbuilder}" |
426 | failonerror = "true" > |
427 |
428 | < arg value = "${out-unsigned-package-ospath}" /> |
429 |
430 | < arg value = "-u" /> |
431 |
432 | < arg value = "-z" /> |
433 |
434 | < arg value = "${resources-package-ospath}" /> |
435 |
436 | < arg value = "-f" /> |
437 |
438 | < arg value = "${dex-ospath}" /> |
439 |
440 | < arg value = "-rf" /> |
441 |
442 | < arg value = "${srcdir-ospath}" /> |
443 |
exec > |
444 |
445 | < echo > |
446 | It will need to be signed with jarsigner before being published. |
447 |
echo > |
448 |
target > |
449 |
450 |
|
451 |
452 | < target |
453 | name = "jarsigner" |
454 | depends = "package" > |
455 |
456 | < echo > |
457 | Packaging signed apk for release... |
458 |
echo > |
459 |
460 | < exec |
461 | executable = "${jarsigner}" |
462 | failonerror = "true" > |
463 |
464 | < arg value = "-keystore" /> |
465 |
466 | < arg value = "${keystore-file}" /> |
467 |
468 | < arg value = "-storepass" /> |
469 |
470 | < arg value = "123456" /> |
471 |
472 | < arg value = "-keypass" /> |
473 |
474 | < arg value = "123456" /> |
475 |
476 | < arg value = "-signedjar" /> |
477 |
478 | < arg value = "${out-signed-package-ospath}" /> |
479 |
480 | < arg value = "${out-unsigned-package-ospath}" /> |
481 |
|
482 |
483 | < arg value = "blockcheng" /> |
484 |
exec > |
485 |
target > |
486 |
487 |
|
488 |
489 | < target |
490 | name = "release" |
491 | depends = "jarsigner" > |
492 |
493 |
|
494 |
495 | < echo > |
496 | delete unsigned apk |
497 |
echo > |
498 | < delete file = "${out-unsigned-package-ospath}" /> |
499 | < echo > |
500 | copy apk from ${out-signed-package-ospath} to D:/workspaceAndroid/Release/happyShopping.apk |
501 |
echo > |
502 | < copy |
503 | file = "${out-signed-package-ospath}" |
504 | tofile = "D:/workspaceAndroid/Release/happyShopping.apk" /> |
505 | < echo > |
506 | clean the workspace bin folder.... |
507 |
echo > |
508 | < delete dir = "${outdir-classes}" /> |
509 | < delete file = "${dex-ospath}" /> |
510 | < delete file = "${resources-package-ospath}" /> |
511 | < delete file = "${outdir-bin}" /> |
512 | < echo > |
513 |
echo > |
514 |
target > |
515 | |
516 |
project > |
五、配置proguard属性:
proguard-project.txt
001 | # To enable ProGuard in your project, edit project.properties |
002 | # to define the proguard.config property as described in that file. |
003 | # |
004 | # Add project specific ProGuard rules here. |
005 | # By default, the flags in this file are appended to flags specified |
006 | # in ${sdk.dir}/tools/proguard/proguard-android.txt |
007 | # You can edit the include path and order by changing the ProGuard |
008 | # include property in project.properties. |
009 | # |
010 | # For more details, see |
011 | # http://developer.android.com/guide/developing/tools/proguard.html |
012 |
013 | # Add any project specific keep options here: |
014 |
015 | # If your project uses WebView with JS, uncomment the following |
016 | # and specify the fully qualified class name to the JavaScript interface |
017 | # class: |
018 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { |
019 | # public *; |
020 | #} |
021 | -optimizationpasses 5 |
022 | -dontusemixedcaseclassnames |
023 | -dontskipnonpubliclibraryclasses |
024 | -dontskipnonpubliclibraryclassmembers |
025 | -dontskipnonpubliclibraryclasses |
026 | -dontpreverify |
027 |
028 |
029 | -libraryjars libs/android-support-v4.jar |
030 | -libraryjars libs/core.jar |
031 |
032 | -verbose |
033 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* |
034 |
035 | -dontwarn android.support.v4.** |
036 |
037 | -keep class android.support.v4.app.** { *; } |
038 |
039 | -keep interface android.support.v4.app.** { *; } |
040 |
041 | -keep class com.actionbarsherlock.** { *; } |
042 |
043 | -keep interface com.actionbarsherlock.** { *; } |
044 |
045 | -keepattributes *Annotation* |
046 |
047 | -keep public class * extends android.app.Activity |
048 |
049 | -keep public class * extends android.support.v4.app.Fragment |
050 |
051 | -keep public class * extends android.support.v4.app.FragmentActivity |
052 |
053 | -keep public class * extends android.app.Application |
054 |
055 |
056 | -keep public class * extends android.app.Service |
057 |
058 | -keep public class * extends android.content.BroadcastReceiver |
059 |
060 | -keep public class * extends android.content.ContentProvider |
061 |
062 | -keep public class * extends android.app.backup.BackupAgentHelper |
063 |
064 | -keep public class * extends android.preference.Preference |
065 |
066 | -keep public class * extends blockcheng.BssicAct |
067 |
068 | -keep public class * extends blockcheng.controller.BCFragment |
069 |
070 | -keep public class com.android.vending.licensing.ILicensingService |
071 |
072 | -keepclasseswithmembernames class * { |
073 | native |
074 | } |
075 |
076 | -keepclasseswithmembers class * { |
077 | public |
078 | } |
079 | |
080 | -keepclasseswithmembers class * { |
081 | public |
082 | } |
083 |
084 | -keepclassmembers class * extends android.app.Activity { |
085 | public void *(android.view.View); |
086 | } |
087 |
088 | -keepclassmembers enum * { |
089 | public static **[] values(); |
090 | public static ** valueOf(java.lang.String); |
091 | } |
092 |
093 | -keepclassmembers class * { |
094 | public |
095 | } |
096 |
097 | -keep public class blockcheng.R$*{ |
098 | public static final int *; |
099 | } |
100 |
101 | -keep public class blockcheng.controller.BlockchengClass.JavaScriptInterface { |
102 | public |
103 | } |
104 |
105 | -keepnames class blockcheng.controller.BlockchengClass$* { |
106 | public |
107 | public |
108 | } |
109 |
110 | -keepnames class blockcheng.controller.BlockchengClass$* { |
111 | public |
112 | public void showContacts(); |
113 | } |
上面的配置中,blockcheng、BC等开头的类,都是被我替换的,不是真实的,具体的类包名和类名,以各人自己的为主。
注意,这个混淆中,开始几行配置很重要,网上很多同学问的ant、proguard相关的错误(什么找不到app.android.v4类等),都是因为缺少这几行导致,但没人回答,这里,我就直接给出了:
01 | -libraryjars libs/android-support-v4.jar |
02 | -libraryjars libs/core.jar |
03 |
04 | -verbose |
05 | -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* |
06 |
07 | -dontwarn android.support.v4.** |
08 |
09 | -keep class android.support.v4.app.** { *; } |
10 |
11 | -keep interface android.support.v4.app.** { *; } |
12 |
13 | -keep class com.actionbarsherlock.** { *; } |
14 |
15 | -keep interface com.actionbarsherlock.** { *; } |
16 |
17 | -keepattributes *Annotation* |
18 |
19 | -keep public class * extends android.app.Activity |
20 |
21 | -keep public class * extends android.support.v4.app.Fragment |
22 |
23 | -keep public class * extends android.support.v4.app.FragmentActivity |
这个配置主要是针对 android-support.v4和库相关的,请需要的同学注意。
最后的几行配置,是因为我代码中调用了asset中js文件导致的,js相关的操作代码,是不可以混淆的,故需要避开。
六、运行ant命令,构建开始:
命令行输入类似: D:/Android/apache-ant-1.9.2/bin/ant.bat -buildfile D:/workspa
ceAndroid/naomiHappyShopping/build.xml
就可以完成代码混淆和apk输出:
view source print ?01 | ....... |
02 | release: |
03 | [ echo ] |
04 | [ echo ] delete unsigned apk |
05 | [ echo ] |
06 | [delete] Deleting: D:\workspaceAndroid\naomiHappyShopping\bin\HappyShoppingAn |
07 | t-unsigned.apk |
08 | [ echo ] |
09 | [ echo ] copy apk from D:\workspaceAndroid\naomiHappyShopping |
10 | /bin/HappyShoppingAnt.apk to D:/workspaceAndroid/Release/happyShopping.apk |
11 | [ echo ] |
12 | [copy] Copying 1 file to D:\workspaceAndroid\Release |
13 | [ echo ] |
14 | [ echo ] clean the workspace bin folder.... |
15 | [ echo ] |
16 | [delete] Deleting directory D:\workspaceAndroid\naomiHappyShopping\bin |
17 | [ echo ] |
18 | [ echo ] |
19 |
20 | BUILD SUCCESSFUL |
21 | Total time : 41 seconds |
另外注意:不同人的路径等配置,需要根据各人自己的来,不能直接拷贝引用。
转自 :http://my.oschina.net/chengliqun/blog/158820
更多相关文章
- 没有一行代码,「2020 新冠肺炎记忆」这个项目却登上了 GitHub 中
- 一款常用的 Squid 日志分析工具
- GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
- RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
- Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
- Android权限机制
- Android开发(一):Android(安卓)Studio及SDK下载安装教程2020
- android截图事件监听
- Android(安卓)读取工程中的txt文件