Replugin踩坑日记

Fragment坑

因为项目需要,开始接触插件化结构,最近RePlugin的信息比较火,社区比较活跃。查看了RePlugin的一些基本信息后,选择使用RePlugin作为插件化利器。

第一个需要的需求就是加载插件apk中的fragment在宿主中显示。在查看sample时,惊喜地发现其中就有相关的例子。由于RePlugin的Sample大而全,也不好直接下载运行,因此自己创建了对应的宿主,插件项目,对应的将Sample中的实例代码抽取出来并运行,是可以运行成功的。(此处比较高兴_

但是…(转折来了o(╥﹏╥)o)

这里记录的坑是在实际操作过程中按顺序出现的(o( ̄︶ ̄)o)

Fragment加载

在使用RePlugin过程中,除了按照wiki中步骤接入宿主,插件外。就是开始在宿主中加载,调用插件内组件。目前需求的是在宿主中加载显示插件中的Fragment,因此下载到Sample来进行查看。其中的Fragment类DemoFragment,DemoCodeFragment两个类。

而创建自己的host,plugin工程后,首页需要解决的就是宿主,插件中共同的support包中的fragment。
按照官方wiki接入插件配置后,将fragment.jar也排除了。但是在运行时却还是会抛出异常ClassNotFoundException。

后来发现:

  1. fragment.jar版本不对,在自己创建的项目中是compileSdkVersion=28,targetSdkVersion=28.
  2. 在module下build.gradle中配置的排除support-v4的写法不准确。

修改:

  1. 将项目中已经依赖 appcompat-v7:版本号 中找到classes.jar包,将其拷贝出来后修改名为fragment.jar。
  2. 修改module下build.gradle中的configurations模块。
configurations {
    if (rootProject.isPlugin) {
        print '插件化,进行support-v4剔除工作'
        all*.exclude group: 'com.android.support', module: 'support-fragment'
    }
}

Sample中build.gradle在 module 的值是’support-v4’,在较新的版本中修改为 ‘support-fragment’。

这样在调用fragment的时候就你不会有问题了。

PS:相关的提示来自《插件 AppCompatActivity 与 v4.Fragment共存》

资源找不到(Resource$NotFoundException)

在使用appcompat-v7编译后,运行插件调用Activity时抛出异常,资源找不到。

4207  4207 D AndroidRuntime: Shutting down VM
09-25 15:36:32.680  4207  4207 W System.err: java.lang.RuntimeException: Unable to start activity ComponentInfo{com.xx.host/com.xx.host.loader.a.ActivityN1NRNTS5}: android.content.res.Resources$NotFoundException: Resource ID #0x7f08005a
09-25 15:36:32.680  4207  4207 W System.err: 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2681)
09-25 15:36:32.681  4207  4207 W System.err: 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2744)
09-25 15:36:32.681  4207  4207 W System.err: 	at android.app.ActivityThread.-wrap12(ActivityThread.java)
09-25 15:36:32.681  4207  4207 W System.err: 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1481)
09-25 15:36:32.681  4207  4207 W System.err: 	at android.os.Handler.dispatchMessage(Handler.java:102)
09-25 15:36:32.681  4207  4207 W System.err: 	at android.os.Looper.loop(Looper.java:154)
09-25 15:36:32.681  4207  4207 W System.err: 	at android.app.ActivityThread.main(ActivityThread.java:6144)
09-25 15:36:32.681  4207  4207 W System.err: 	at java.lang.reflect.Method.invoke(Native Method)
09-25 15:36:32.681  4207  4207 W System.err: 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
09-25 15:36:32.681  4207  4207 W System.err: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
09-25 15:36:32.681  4207  4207 W System.err: Caused by: android.content.res.Resources$NotFoundException: Resource ID #0x7f08005a
09-25 15:36:32.681  4207  4207 W System.err: 	at android.content.res.ResourcesImpl.getValue(ResourcesImpl.java:190)
09-25 15:36:32.681  4207  4207 W System.err: 	at android.content.res.Resources.getValue(Resources.java:1290)
09-25 15:36:32.681  4207  4207 W System.err: 	at android.support.v7.widget.AppCompatDrawableManager.createDrawableIfNeeded(AppCompatDrawableManager.java:235)
09-25 15:36:32.681  4207  4207 W System.err: 	at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:200)
09-25 15:36:32.682  4207  4207 W System.err: 	at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:191)
09-25 15:36:32.682  4207  4207 W System.err: 	at android.support.v7.widget.AppCompatDrawableManager.checkVectorDrawableSetup(AppCompatDrawableManager.java:753)
09-25 15:36:32.682  4207  4207 W System.err: 	at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:196)
09-25 15:36:32.682  4207  4207 W System.err: 	at android.support.v7.widget.TintTypedArray.getDrawableIfKnown(TintTypedArray.java:86)
09-25 15:36:32.682  4207  4207 W System.err: 	at android.support.v7.app.AppCompatDelegateImpl.<init>(AppCompatDelegateImpl.java:260)
09-25 15:36:32.682  4207  4207 W System.err: 	at android.support.v7.app.AppCompatDelegate.create(AppCompatDelegate.java:182)
09-25 15:36:32.682  4207  4207 W System.err: 	at android.support.v7.app.AppCompatActivity.getDelegate(AppCompatActivity.java:520)
09-25 15:36:32.682  4207  4207 W System.err: 	at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:71)
09-25 15:36:32.682  4207  4207 W System.err: 	at com.xx.androidteam.ui.activity.PluginTargetActivity.onCreate(PluginTargetActivity.kt:9)
09-25 15:36:32.682  4207  4207 W System.err: 	at android.app.Activity.performCreate(Activity.java:6727)
09-25 15:36:32.682  4207  4207 W System.err: 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
09-25 15:36:32.682  4207  4207 W System.err: 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2634)
09-25 15:36:32.682  4207  4207 W System.err: 	... 9 more
09-25 15:36:32.693  4207  4207 W System.err: java.io.IOException: Permission denied
09-25 15:36:32.693  4207  4207 W System.err: 	at java.io.UnixFileSystem.createFileExclusively0(Native Method)
09-25 15:36:32.693  4207  4207 W System.err: 	at java.io.UnixFileSystem.createFileExclusively(UnixFileSystem.java:280)
09-25 15:36:32.693  4207  4207 W System.err: 	at java.io.File.createNewFile(File.java:948)
09-25 15:36:32.693  4207  4207 W System.err: 	at com.xx.androidteam.ui.CrashHandler._dumpExceptionToSDCard(CrashHandler.java:149)
09-25 15:36:32.693  4207  4207 W System.err: 	at com.xx.androidteam.ui.CrashHandler._handleException(CrashHandler.java:117)
09-25 15:36:32.693  4207  4207 W System.err: 	at com.xx.androidteam.ui.CrashHandler.uncaughtException(CrashHandler.java:63)
09-25 15:36:32.693  4207  4207 W System.err: 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1068)
09-25 15:36:32.693  4207  4207 W System.err: 	at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1063)
09-25 15:36:33.145  2324  2407 D MEMGC   : availMem = 1.21 GB, totalMem = 3.50 GB
09-25 15:36:33.146  2324  2407 D MEMGC   : Service_0_updateWidget -- availMem = 1.21 GB, totalRam = 3.50 GB, ratioPercentFormat = 35%
09-25 15:36:34.378  2034  9922 D DeviceControlService: checkOp ------- op = UNLOCK, enabled = true

在AS中仔细查找开始没有找到如何找都无法找到,这里需要注意的是在AS有了git后,如果将build目录加入到了ignore中,在搜索时IDE不会搜索到隐藏目录中(AS 3.5)。因此直接搜索R.java文件也无果,徘徊很久不在IDE中搜索,直接在工程目录中利用其他工具进行搜索。找到了对应的R.java且找到了对应资源id(#0x7f08005a)对应的资源名。

   public static final int abc_vector_test=0x7f08005a;

踩过此坑的也不在少数,这里有几种方式,参见
NotFoundException: File res/drawable/abc_vector_test.xml from drawable resourceID

矢量图相关

主要错误信息:

This app has been built with an incorrect configuration. Please configure your build for VectorDrawableCompat.

与适量图相关,查阅相关文章,appcompat-v7与矢量图不兼容。

解决:
由于我的项目中使用的矢量图较小,且APP运行设备差异性不会特别大差异,因此将原来的矢量图改为使用普通的png图。

PS: 错误信参考RePlugin issue #554

Theme.AppCompat主题问题

主要错误信息:

java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.

显示Activity需要添加Theme.AppCompat主题。但在查看项目manifest中时,可以发现manifest文件内标签内已经添加了AppCompat主题,且为了验证问题,单独给目标Activity添加了单独的AppCompat主题。

但打包运行后依然抛出同样的错误。

java.lang.VerifyError

场景:
首页多个tab中,需要显示其中某个tab内容,其实现是Fragment内嵌套有ViewPager,FragmentPagerAdapter,Fragment显示多个可左右切换的页面。因此属于嵌套的Fragment使用。

在处理完上述的’support-fragment’包剔除工作后,在此处有遇到了类似的问题。

这里遇到的问题错误log如下:

10-09 11:12:11.128 14284 14284 E CrashHandler: java.lang.IllegalStateException: Fatal Exception thrown on Scheduler.Worker thread.
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:59)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at android.os.Handler.handleCallback(Handler.java:758)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at android.os.Handler.dispatchMessage(Handler.java:95)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at android.os.Looper.loop(Looper.java:154)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at android.app.ActivityThread.main(ActivityThread.java:6144)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at java.lang.reflect.Method.invoke(Native Method)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:889)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:779)
10-09 11:12:11.128 14284 14284 E CrashHandler: Caused by: java.lang.VerifyError: Verifier rejected class com.androidteam.adapter.recycleradapter.MultiListNewAdapter: void com.androidteam.adapter.recycleradapter.MultiListNewAdapter._handleDailyComVPChart(com.androidteam.adapter.recyclerhelper.BaseViewHolder, java.util.ArrayList) failed to verify: void com.androidteam.adapter.recycleradapter.MultiListNewAdapter._handleDailyComVPChart(com.androidteam.adapter.recyclerhelper.BaseViewHolder, java.util.ArrayList): [0x1B2] register v10 has type Reference: com.androidteam.ui.Fragments.Chart.TabFragmentPagerAdapter but expected Reference: android.support.v4.view.PagerAdapter (declaration of 'com.androidteam.adapter.recycleradapter.MultiListNewAdapter' appears in /data/user/0/com.mobilepolice/app_p_a/-1607123362.jar)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at com.androidteam.ui.Activity.plugin.FrontPageActivity.loadData(FrontPageActivity.java:123)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at com.androidteam.ui.Fragments.Front.Personal.FrontPagePresent$14$1.onCompleted(FrontPagePresent.java:567)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at rx.observers.SafeSubscriber.onCompleted(SafeSubscriber.java:79)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at rx.internal.operators.OperatorMerge$MergeSubscriber.emitLoop(OperatorMerge.java:656)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at rx.internal.operators.OperatorMerge$MergeSubscriber.emit(OperatorMerge.java:568)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at rx.internal.operators.OperatorMerge$MergeSubscriber.onCompleted(OperatorMerge.java:281)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at rx.internal.operators.OnSubscribeMap$MapSubscriber.onCompleted(OnSubscribeMap.java:97)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at rx.observers.SerializedObserver.onCompleted(SerializedObserver.java:176)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at rx.observers.SerializedSubscriber.onCompleted(SerializedSubscriber.java:64)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at rx.internal.operators.OperatorTakeUntil$1.onCompleted(OperatorTakeUntil.java:58)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at rx.internal.operators.OperatorMerge$MergeSubscriber.emitLoop(OperatorMerge.java:656)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at rx.internal.operators.OperatorMerge$MergeSubscriber.emit(OperatorMerge.java:568)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at rx.internal.operators.OperatorMerge$MergeSubscriber.onCompleted(OperatorMerge.java:281)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at rx.internal.operators.OnSubscribeMap$MapSubscriber.onCompleted(OnSubscribeMap.java:97)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.checkTerminated(OperatorObserveOn.java:281)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:216)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55)
10-09 11:12:11.128 14284 14284 E CrashHandler: 	... 7 more
10-09 11:12:11.467  1633  2289 E LocSvc_eng: E/Calling gnss_sv_status_cb
10-09 11:12:11.617  2034  9922 D DeviceControlService: checkOp ------- op = WIFI, enabled = true

其中主要因此加载后fragment异常退出的错误原因:

Caused by: java.lang.VerifyError: Verifier rejected class com.androidteam.adapter.recycleradapter.MultiListNewAdapter: void com.androidteam.adapter.recycleradapter.MultiListNewAdapter._handleDailyComVPChart(com.androidteam.adapter.recyclerhelper.BaseViewHolder, java.util.ArrayList) failed to verify: void com.androidteam.adapter.recycleradapter.MultiListNewAdapter._handleDailyComVPChart(com.androidteam.adapter.recyclerhelper.BaseViewHolder, java.util.ArrayList): [0x1B2] register v10 has type Reference: com.androidteam.ui.Fragments.Chart.TabFragmentPagerAdapter but expected Reference: android.support.v4.view.PagerAdapter (declaration of 'com.androidteam.adapter.recycleradapter.MultiListNewAdapter' appears in /data/user/0/com.mobilepolice/app_p_a/-1607123362.jar)

抛出java.lang.VerifyError。查阅了RePlugin官方wiki中,大多遇到的是LocalBroadcast的广播问题。而我在这里遇到的是Adapter的类型无法正确找到的错误提示。
可能出现VerifyError错误的原因,有兴趣的大家可以自己搜索。

我也搜索查看了许多其他遇到此类问题的解决方案,均无法满足或者根本不是同类问题。
最终尝试出解决方案的提示来自于VerifyError的继承关系。

VerifyError继承关系

注意其父类是

java.lang.LinkageError

是链接异常(字面含义),通过这个,想到了fragment最开始在插件及宿主均包含 support-fragemnt 包下,在加载Fragment显示时无法找到准确的Fragment类型来继承并实例化显示。

错误log中查看到的是PagerAdapter无法准确找到,因此查看查看源码ViewPager的setAdapter()参数继承关系,使用了FragmentPagerAdapter,其继承了PagerAdapter。

FragmentPagerAdapter继承关系

继承关系中两个类属于不同的包,查看后也可以知道两个类分别在不同的库中。FragmentPagerAdapter在 support-fragemnt 库内,而 PagerAdapter 类在 viewpager 库内。

而重点是在一开始使用的时候就剔除了 support-fragemnt ,仅在编译期参与编译而不参与打包。因此自然想到了将 viewpager 库也剔除。

在宿主工程中查看找到其classes.jar包拷贝出来,改名为 viewpager-v28.jar,拷贝到插件工程的 libs 目录下。类似剔除 fragment.jar 操作,在 build.gradle 文件的 dependencies 块中将其使用 compileOnly 进行编译期依赖。

在这里插入图片描述

build.gradle 修改

// 全局剔除viewpager
configurations {
    if (rootProject.isPlugin) {
        print '插件化,进行support-v4剔除工作'
        all*.exclude group: 'com.android.support', module: 'support-fragment'
        all*.exclude group: 'com.android.support', module: 'viewpager'
    }
}

dependencies {
    implementation files('libs/pinyin4j-2.5.0.jar')
    implementation files('libs/policesdks_20170904.jar')

    if (rootProject.isPlugin) {
        compileOnly files('libs/fragment-v28.jar')
        compileOnly files('libs/viewpager-v28.jar')
       // ...     
    }
    // ......
}

这样我解决了java.lang.VerifyError针对PagerAdapter的的检查检查异常。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

VoidHope

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值