插件APK中的activity显示的视图,其实是附着在宿主Activity上的

任大大的这篇文章描述了一个动态加载插件apk视图的步骤:

其中学习到了不少知识,整理一下。
一个重要的问题就是,插件中的activity加载出来的视图其实是附着在宿主activity的视图层次上的,因为加载视图的时候使用的context上下文就是宿主的context,添加视图结构,比如就是添加在了宿主activity的顶层view上的。插件中的activity就是一个普通的java类,没有生命周期,没有视图层次。
所以我们在编写插件apk的时候,activity要显示视图,那就不能按照常规的那种方式了。
这个在文章的最后也做了说明,加载进来的activity并没有替换宿主的activity标题,感觉点击按钮是跳转了,其实就是重新设置界面布局而已。

在插件APK的BaseActivity中保存了代理类的实例,插件各个activity的跳转实际上是代理类在跳转,跳转后的每个activity的视图实际上加载到了各个代理类实例上,所以这个时候代理类的启动模式就是standard( 关于启动模式的理解),只有这个模式才会在整个activity栈中存在多个实例。而且我们可以看到在BaseActivity的startActivityByProxy这个方法中,代理类是通过隐式intent的方式来启动自身实例的:
protected void startActivityByProxy(String className) {
        if (mProxyActivity == this) {
            Intent intent = new Intent();
            intent.setClassName(this, className);
            this.startActivity(intent);
        } else {
            Intent intent = new Intent(PROXY_VIEW_ACTION);//其实这里启动的就是代理ProxyActivity本身,所以在这个activity的注册信息里面要添加这个action
            intent.putExtra(EXTRA_DEX_PATH, DEX_PATH);//必须和宿主里面的路径一致。
            intent.putExtra(EXTRA_CLASS, className);
            mProxyActivity.startActivity(intent);//也就是自己启动自己,启动了一个代理activity后,执行加载插件activity的方法
            //代理activity启动模式为标准模式,这样才能实现多个activity实例。
        }
    }
所以我们的代理类就需要在其manifest的ProxyActivity节点下声明intent-filter,也就是在宿主apk的manifest中来声明。

敲代码实现该实例的时候出现了两个问题,记录一下:
1、在宿主的manifest中声明ProxyActivity的intent-filter的时候,只声明了
<action android:name="com.ryg.dynamicloadhost.VIEW"/>
结果导致在运行的时候,出现了如下错误:
06-26 17:14:57.114 22032-22032/com.txt.mydemo E/AndroidRuntime: FATAL EXCEPTION: main
                                                                android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.ryg.dynamicloadhost.VIEW (has extras) }
                                                                    at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1545)
                                                                    at android.app.Instrumentation.execStartActivity(Instrumentation.java:1416)
                                                                    at android.app.Activity.startActivityForResult(Activity.java:3386)
                                                                    at android.app.Activity.startActivityForResult(Activity.java:3347)
                                                                    at android.app.Activity.startActivity(Activity.java:3557)
                                                                    at android.app.Activity.startActivity(Activity.java:3525)
                                                                    at com.tongxt.dynamic.BaseActivity.startActivityByProxy(BaseActivity.java:57)
                                                                    at com.tongxt.dynamic.MainActivity$1.onClick(MainActivity.java:39)
                                                                    at android.view.View.performClick(View.java:4100)
                                                                    at android.view.View$PerformClick.run(View.java:17016)
                                                                    at android.os.Handler.handleCallback(Handler.java:615)
                                                                    at android.os.Handler.dispatchMessage(Handler.java:92)
                                                                    at android.os.Looper.loop(Looper.java:137)
                                                                    at android.app.ActivityThread.main(ActivityThread.java:4767)
                                                                    at java.lang.reflect.Method.invokeNative(Native Method)
                                                                    at java.lang.reflect.Method.invoke(Method.java:511)
                                                                    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:800)
                                                                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:567)
                                                                    at dalvik.system.NativeStart.main(Native Method)
这是因为我们在intent-filter的时候,必须要同时设置category属性,原因是:每一个通过 startActivity() 方法发出的隐式 Intent 都至少有一个 category,就是 "android.intent.category.DEFAULT",所以只要是想接收一个隐式 Intent 的 Activity 都应该包括 "android.intent.category.DEFAULT" category,不然将导致 Intent 匹配失败。

2、在定义ProxyActivity和BaseActivity的时候,使用继承了AppCompatActivity,导致在华为D1手机(android4.1.1,系统api是16)上出现了如下错误:
06-26 16:51:07.082 8111-8111/com.txt.mydemo I/ProxyActivity: mClass=null mDexPath=/storage/sdcard0/dynamic-debug.apk
06-26 16:51:07.098 8111-8111/com.txt.mydemo I/PackageParser: add hwframework.jar as a optional shared library.
06-26 16:51:07.098 8111-8111/com.txt.mydemo D/ProxyActivity: start launchTargetActivity, className=com.tongxt.dynamic.MainActivity
06-26 16:51:07.098 8111-8111/com.txt.mydemo W/PackageParser: Unknown element under <manifest>: meta-data at /storage/sdcard0/dynamic-debug.apk Binary XML file line #11
06-26 16:51:07.121 8111-8111/com.txt.mydemo W/dalvikvm: Class resolved by unexpected DEX: Lcom/tongxt/dynamic/BaseActivity;(0x45036718):0x5c451000 ref [Landroid/support/v7/app/AppCompatActivity;] Landroid/support/v7/app/AppCompatActivity;(0x42b55a08):0x5b4e8000
06-26 16:51:07.121 8111-8111/com.txt.mydemo W/dalvikvm: (Lcom/tongxt/dynamic/BaseActivity; had used a different Landroid/support/v7/app/AppCompatActivity; during pre-verification)
06-26 16:51:07.121 8111-8111/com.txt.mydemo W/dalvikvm: Unable to resolve superclass of Lcom/tongxt/dynamic/BaseActivity; (1619)
06-26 16:51:07.121 8111-8111/com.txt.mydemo W/dalvikvm: Link of class 'Lcom/tongxt/dynamic/BaseActivity;' failed
06-26 16:51:07.121 8111-8111/com.txt.mydemo W/dalvikvm: Unable to resolve superclass of Lcom/tongxt/dynamic/MainActivity; (2152)
06-26 16:51:07.121 8111-8111/com.txt.mydemo W/dalvikvm: Link of class 'Lcom/tongxt/dynamic/MainActivity;' failed
06-26 16:51:07.121 8111-8111/com.txt.mydemo W/System.err: java.lang.ClassNotFoundException: com.tongxt.dynamic.MainActivity
06-26 16:51:07.121 8111-8111/com.txt.mydemo W/System.err:     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
06-26 16:51:07.121 8111-8111/com.txt.mydemo W/System.err:     at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
06-26 16:51:07.121 8111-8111/com.txt.mydemo W/System.err:     at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
06-26 16:51:07.121 8111-8111/com.txt.mydemo W/System.err:     at com.txt.plugin.ProxyActivity.launchTargetActivity(ProxyActivity.java:63)
06-26 16:51:07.121 8111-8111/com.txt.mydemo W/System.err:     at com.txt.plugin.ProxyActivity.launchTargetActivity(ProxyActivity.java:53)
06-26 16:51:07.121 8111-8111/com.txt.mydemo W/System.err:     at com.txt.plugin.ProxyActivity.onCreate(ProxyActivity.java:40)
06-26 16:51:07.121 8111-8111/com.txt.mydemo W/System.err:     at android.app.Activity.performCreate(Activity.java:5043)
06-26 16:51:07.129 8111-8111/com.txt.mydemo W/System.err:     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
06-26 16:51:07.129 8111-8111/com.txt.mydemo W/System.err:     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2033)
06-26 16:51:07.129 8111-8111/com.txt.mydemo W/System.err:     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2094)
06-26 16:51:07.129 8111-8111/com.txt.mydemo W/System.err:     at android.app.ActivityThread.access$600(ActivityThread.java:134)
06-26 16:51:07.129 8111-8111/com.txt.mydemo W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1202)
06-26 16:51:07.129 8111-8111/com.txt.mydemo W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:99)
06-26 16:51:07.129 8111-8111/com.txt.mydemo W/System.err:     at android.os.Looper.loop(Looper.java:137)
06-26 16:51:07.129 8111-8111/com.txt.mydemo W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:4767)
06-26 16:51:07.129 8111-8111/com.txt.mydemo W/System.err:     at java.lang.reflect.Method.invokeNative(Native Method)
06-26 16:51:07.129 8111-8111/com.txt.mydemo W/System.err:     at java.lang.reflect.Method.invoke(Method.java:511)
06-26 16:51:07.129 8111-8111/com.txt.mydemo W/System.err:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:800)
06-26 16:51:07.129 8111-8111/com.txt.mydemo W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:567)
06-26 16:51:07.137 8111-8111/com.txt.mydemo W/System.err:     at dalvik.system.NativeStart.main(Native Method)
应该是华为的rom做了定制化修改,没有把AppCompatActivity这个类包含进来吧。把这两个类继承自Activity后就没出现问题了。



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值