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

来源:互联网 发布:下载淘宝网天猫商城 编辑:程序博客网 时间:2024/05/17 03:26
任大大的这篇文章描述了一个动态加载插件apk视图的步骤:
http://blog.csdn.net/singwhatiwanna/article/details/22597587

其中学习到了不少知识,整理一下。
一个重要的问题就是,插件中的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.apk06-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.MainActivity06-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 #1106-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):0x5b4e800006-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;' failed06-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;' failed06-26 16:51:07.121 8111-8111/com.txt.mydemo W/System.err: java.lang.ClassNotFoundException: com.tongxt.dynamic.MainActivity06-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