插件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
- 插件APK中的activity显示的视图,其实是附着在宿主Activity上的
- 在activity的title上显示进度条
- 怎么判断当前activity上显示的是哪个fragment?
- 其实View并不是直接跟Activity关联起来的
- popupwindow在activity上显示
- 获取屏幕上正在显示的activity
- 获取屏幕上正在显示的activity
- 获取屏幕上正在显示的activity
- Activity task问题(一)现象:Activity task栈顺序,而非Activity在task中的顺序,是和最后启动的Activity有关的
- 《如何在一个Activity的一部分中显示其他Activity》
- Android 在一个Activity的一部分中显示其他Activity
- 悬浮在activity上的activity半透明对话框
- 关于在宿主activity中设置按钮,动态控制viewPager中的字体的大小的设置,在答题项目中遇到,在此做记录,方便日后学习,改进。
- Dialog显示在Activity不同的位置
- Dialog显示在Activity不同的位置
- Activity在屏幕当中显示的方向
- Android显示框架:Activity应用视图的创建流程
- Android显示框架:Activity应用视图的渲染流程
- js 把一个数组分割成 n 个一组
- <java EE 项目:Attendance> 从一个简单项目看java web 开发的整体布局
- gulp--gulp-autoprefixer
- 总结“生成账单”功能的要点
- AngularJS注意事项
- 插件APK中的activity显示的视图,其实是附着在宿主Activity上的
- Ubuntu 16.04下搭建Web服务器
- surface Shader——主贴图、法线贴图、边缘颜色
- 我自己的android studio代码混淆打包参考
- mvc5新特性RouteAttribute特征路由
- LintCode_464_整数排序||
- 枚举应用
- Jocky混淆JAVA代码(保护你的JAVA项目)
- ManagementFactory api