Android 平台应用使用RxAndroid

前提: 需要已经在Android Studio中使用过RxAndroid,以便我们可以提取其下载下来的RxAndroid库。


找到库文件

在用户目录的子路径中找到RxAndroid和RxJava(RxAndroid依赖RxJava)的库文件(aar或者jar)。路径一般如下,请根据自己的RxAndroid版本号自行替换路径中某些值。

RxAndroid:

主目录/.gradle/caches/modules-2/files-2.1/io.reactivex/rxandroid/1.0.0/9d4f880d8a3111646977ed77d00a9fd19279225/rxandroid-1.0.0.aar

RxJava:

主目录/.gradle/caches/modules-2/files-2.1/io.reactivex/rxjava/1.0.13/b8668706414b5936d38c8a9e4c2be16e3c999c62/rxjava-1.0.13.jar

注意不要找到rxjava-1.0.13-sources.jar这个源码jar包了。

提取jar文件

提取你jar库文件到你需要的模块下,可以建个libs文件夹存放,比如packages/apps/Launcher3/libs。

rxjava-1.0.13.jar: 纯粹的jar包,自然是不用说,可以直接放在libs下。
rxandroid-1.0.0.aar: aar格式其实是专门为Android制作的压缩包结构,主要针对Android库有时需要声明资源类型因而将其打包成这样的格式。压缩包结构如下:
这里写图片描述

但RxAndroid这个aar库中并不包含资源,只是在AndroidManifest文件中声明了个包名而已。因此我们直接提取其中的classes.jar文件出来作为依赖jar包放在libs下,同时可以将classes.jar重命名成比如我当前RxAndroid版本的rxandroid-1.0.0.jar

在Android.mk文件中声明编译依赖的jar文件

我添加的声明如下:

...
LOCAL_STATIC_JAVA_LIBRARIES += rxjava rxandroid
...
include $(BUILD_PACKAGE)

####################################
include $(CLEAR_VARS)
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES := rxjava:libs/rxjava-1.0.13.jar \
                                        rxandroid:libs/rxandroid-1.0.0.jar
include $(BUILD_MULTI_PREBUILT)
#######################################

其中主要是使用LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES预编译静态java库,并且使用LOCAL_STATIC_JAVA_LIBRARIES使用编译出的库。

更详细的如何在mk文件添加jar包依赖的方法请自行百度。

接着mmm编译成功, 但是 …

将生成的APK安装到手机上,一运行发现挂了,如下异常:

05-16 16:36:50.666  6540  6540 D AndroidRuntime: Shutting down VM
05-16 16:36:50.668  6540  6540 E AndroidRuntime: FATAL EXCEPTION: main
05-16 16:36:50.668  6540  6540 E AndroidRuntime: Process: com.example.ningxiang.appcategory, PID: 6540
05-16 16:36:50.668  6540  6540 E AndroidRuntime: java.lang.ExceptionInInitializerError
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at rx.internal.schedulers.EventLoopsScheduler.<clinit>(EventLoopsScheduler.java:28)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at rx.schedulers.Schedulers.<init>(Schedulers.java:40)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at rx.schedulers.Schedulers.<clinit>(Schedulers.java:33)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at rx.schedulers.Schedulers.io(Schedulers.java:117)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at com.example.ningxiang.appcategory.Main2Activity.onCreate(Main2Activity.java:23)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at android.app.Activity.performCreate(Activity.java:6666)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2762)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2874)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at android.app.ActivityThread.-wrap12(ActivityThread.java)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1612)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at android.os.Handler.dispatchMessage(Handler.java:110)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at android.os.Looper.loop(Looper.java:203)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at android.app.ActivityThread.main(ActivityThread.java:6336)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at java.lang.reflect.Method.invoke(Native Method)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1066)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:927)
05-16 16:36:50.668  6540  6540 E AndroidRuntime: Caused by: java.lang.RuntimeException: java.lang.NoSuchFieldException: No field counter in class Lrx/internal/util/RxThreadFactory; (declaration of 'rx.internal.util.RxThreadFactory' appears in base.apk)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at java.util.concurrent.atomic.AtomicLongFieldUpdater$CASUpdater.<init>(AtomicLongFieldUpdater.java:373)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at java.util.concurrent.atomic.AtomicLongFieldUpdater.newUpdater(AtomicLongFieldUpdater.java:60)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at rx.internal.util.RxThreadFactory.<clinit>(RxThreadFactory.java:24)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    ... 17 more
05-16 16:36:50.668  6540  6540 E AndroidRuntime: Caused by: java.lang.NoSuchFieldException: No field counter in class Lrx/internal/util/RxThreadFactory; (declaration of 'rx.internal.util.RxThreadFactory' appears in base.apk)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at java.lang.Class.getDeclaredField(Native Method)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    at java.util.concurrent.atomic.AtomicLongFieldUpdater$CASUpdater.<init>(AtomicLongFieldUpdater.java:356)
05-16 16:36:50.668  6540  6540 E AndroidRuntime:    ... 19 more

原因是:
Caused by: java.lang.RuntimeException: java.lang.NoSuchFieldException: No field counter in class Lrx/internal/util/RxThreadFactory; (declaration of ‘rx.internal.util.RxThreadFactory’ appears in base.apk)

说是在rx/internal/util/RxThreadFactory类中找不到counter这个字段,于是查看源码,发现counter是存在的,但在整个库中没有直接引用过,而是通过反射使用的。同时查看生成APK中解出来的smali文件确实找不到counter字段。
因此猜测是在编译期优化时被优化掉了。

找大神询问,得知是proguard混淆时优化的,解决方案是禁用混淆或者配置混淆规则,使编译时略过对该库的优化。

使用方法分别如下:
1. 禁用proguard
在Android.mk中添加一行内容:LOCAL_PROGUARD_ENABLED := disabled
如此,便禁用了整个模块的混淆优化。(有点粗暴~)

2. 编辑混淆规则使之忽略RxAndroid和RxJava
2.1 模块下新建文本文件proguard.flags(名字其实可以自定义的哈)
2.2 在proguard.flags中填入内容:-keep class rx.** {*;}
如此可对rx包下的所有类进行排除混淆优化(更多proguard规则配置请自行百度)
2.3 在Android.mk中添加一行:LOCAL_PROGUARD_FLAG_FILES := proguard.flags
这样就将我们编辑的混淆规则引入到编译系统中了。

编译,运行,成功

阅读更多
个人分类: 技术杂记
上一篇AndroidStudio升级后Android Device Monitor打开出错
下一篇Android平台使用okhttp
想对作者说点什么? 我来说一句

RxAndroid/RxJava jar

2016年02月24日 999KB 下载

Rxjava2.1.6 Rxandroid2.0.1 jar包

2017年11月10日 1.83MB 下载

RxAndroid开发各种jar

2016年05月26日 1.96MB 下载

RxJava RxAndroid jar

2017年10月30日 843KB 下载

RxJava和RxAndroid jar包下载

2016年07月30日 841KB 下载

RxAndroid框架JAR包

2016年04月12日 1.01MB 下载

没有更多推荐了,返回首页

关闭
关闭