android 应用动态加载机制1,【金九银十

1. 为了让proxy全面接管apk中所有activity的执行,需要为activity定义一个基类BaseActivity,在基类中处理代理相关的事情,同时BaseActivity还对是否使用代理进行了判断,如果不使用代理,那么activity的逻辑仍然按照正常的方式执行,也就是说,这个apk既可以按照执行,也可以由宿主程序来执行。

[java]  view plain  copy

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. package com.ryg.dynamicloadclient;

  2. import android.app.Activity;

  3. import android.content.Intent;

  4. import android.os.Bundle;

  5. import android.util.Log;

  6. import android.view.View;

  7. import android.view.ViewGroup.LayoutParams;

  8. public class BaseActivity extends Activity {

  9. private static final String TAG = “Client-BaseActivity”;

  10. public static final String FROM = “extra.from”;

  11. public static final int FROM_EXTERNAL = 0;

  12. public static final int FROM_INTERNAL = 1;

  13. public static final String EXTRA_DEX_PATH = “extra.dex.path”;

  14. public static final String EXTRA_CLASS = “extra.class”;

  15. public static final String PROXY_VIEW_ACTION = “com.ryg.dynamicloadhost.VIEW”;

  16. public static final String DEX_PATH = “/mnt/sdcard/DynamicLoadHost/plugin.apk”;

  17. protected Activity mProxyActivity;

  18. protected int mFrom = FROM_INTERNAL;

  19. public void setProxy(Activity proxyActivity) {

  20. Log.d(TAG, "setProxy: proxyActivity= " + proxyActivity);

  21. mProxyActivity = proxyActivity;

  22. }

  23. @Override

  24. protected void onCreate(Bundle savedInstanceState) {

  25. if (savedInstanceState != null) {

  26. mFrom = savedInstanceState.getInt(FROM, FROM_INTERNAL);

  27. }

  28. if (mFrom == FROM_INTERNAL) {

  29. super.onCreate(savedInstanceState);

  30. mProxyActivity = this;

  31. }

  32. Log.d(TAG, "onCreate: from= " + mFrom);

  33. }

  34. protected void startActivityByProxy(String className) {

  35. if (mProxyActivity == this) {

  36. Intent intent = new Intent();

  37. intent.setClassName(this, className);

  38. this.startActivity(intent);

  39. } else {

  40. Intent intent = new Intent(PROXY_VIEW_ACTION);

  41. intent.putExtra(EXTRA_DEX_PATH, DEX_PATH);

  42. intent.putExtra(EXTRA_CLASS, className);

  43. mProxyActivity.startActivity(intent);

  44. }

  45. }

  46. @Override

  47. public void setContentView(View view) {

  48. if (mProxyActivity == this) {

  49. super.setContentView(view);

  50. } else {

  51. mProxyActivity.setContentView(view);

  52. }

  53. }

  54. @Override

  55. public void setContentView(View view, LayoutParams params) {

  56. if (mProxyActivity == this) {

  57. super.setContentView(view, params);

  58. } else {

  59. mProxyActivity.setContentView(view, params);

  60. }

  61. }

  62. @Deprecated

  63. @Override

  64. public void setContentView(int layoutResID) {

  65. if (mProxyActivity == this) {

  66. super.setContentView(layoutResID);

  67. } else {

  68. mProxyActivity.setContentView(layoutResID);

  69. }

  70. }

  71. @Override

  72. public void addContentView(View view, LayoutParams params) {

  73. if (mProxyActivity == this) {

  74. super.addContentView(view, params);

  75. } else {

  76. mProxyActivity.addContentView(view, params);

  77. }

  78. }

  79. }

说明:相信大家一看代码就明白了,其中setProxy方法的作用就是为了让宿主程序能够接管自己的执行,一旦被接管以后,其所有的执行均通过proxy,且Context也变成了宿主程序的Context,也许这么说比较形象:宿主程序其实就是个空壳,它只是把其它apk加载到自己的内部去执行,这也就更能理解为什么资源访问变得很困难,你会发现好像访问不到apk中的资源了,的确是这样的,但是目前我还没有很好的方法去解决。

2. 入口activity的实现

[java]  view plain  copy

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. public class MainActivity extends BaseActivity {

  2. private static final String TAG = “Client-MainActivity”;

  3. @Override

  4. protected void onCreate(Bundle savedInstanceState) {

  5. super.onCreate(savedInstanceState);

  6. initView(savedInstanceState);

  7. }

  8. private void initView(Bundle savedInstanceState) {

  9. mProxyActivity.setContentView(generateContentView(mProxyActivity));

  10. }

  11. private View generateContentView(final Context context) {

  12. LinearLayout layout = new LinearLayout(context);

  13. layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,

  14. LayoutParams.MATCH_PARENT));

  15. layout.setBackgroundColor(Color.parseColor(“#F79AB5”));

  16. Button button = new Button(context);

  17. button.setText(“button”);

  18. layout.addView(button, LayoutParams.MATCH_PARENT,

  19. LayoutParams.WRAP_CONTENT);

  20. button.setOnClickListener(new OnClickListener() {

  21. @Override

  22. public void onClick(View v) {

  23. Toast.makeText(context, “you clicked button”,

  24. Toast.LENGTH_SHORT).show();

  25. startActivityByProxy(“com.ryg.dynamicloadclient.TestActivity”);

  26. }

  27. });

  28. return layout;

  29. }

  30. }

说明:由于访问不到apk中的资源了,所以界面是代码写的,而不是写在xml中,因为xml读不到了,这也是个大问题。注意到主界面中有一个button,点击后跳到了另一个activity,这个时候是不能直接调用系统的startActivity方法的,而是必须通过宿主程序中的proxy来执行,原因很简单,首先apk本书没有Context,所以它无法调起activity,另外由于这个子activity是apk中的,通过宿主程序直接调用它也是不行的,因为它对宿主程序来说是不可见的,所以只能通过proxy来调用,是不是感觉很麻烦?但是,你还有更好的办法吗?

3. 子activity的实现

[java]  view plain  copy

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. package com.ryg.dynamicloadclient;

  2. import android.graphics.Color;

  3. import android.os.Bundle;

  4. import android.view.ViewGroup.LayoutParams;

  5. import android.widget.Button;

  6. public class TestActivity extends BaseActivity{

  7. @Override

  8. protected void onCreate(Bundle savedInstanceState) {

  9. super.onCreate(savedInstanceState);

  10. Button button = new Button(mProxyActivity);

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
img

分享读者

作者2013年java转到Android开发,在小厂待过,也去过华为,OPPO等大厂待过,18年四月份进了阿里一直到现在。

被人面试过,也面试过很多人。深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长,而且极易碰到天花板技术停滞不前!

我们整理了一份阿里P7级别的Android架构师全套学习资料,特别适合有3-5年以上经验的小伙伴深入学习提升。

主要包括腾讯,以及字节跳动,阿里,华为,小米,等一线互联网公司主流架构技术。如果你有需要,尽管拿走好了。

腾讯T3架构师学习专题资料

如果你觉得自己学习效率低,缺乏正确的指导,可以点击加入资源丰富,学习氛围浓厚的技术圈一起学习交流吧

群内有许多来自一线的技术大牛,也有在小厂或外包公司奋斗的码农,我们致力打造一个平等,高质量的Android交流圈子,不一定能短期就让每个人的技术突飞猛进,但从长远来说,眼光,格局,长远发展的方向才是最重要的。

35岁中年危机大多是因为被短期的利益牵着走,过早压榨掉了价值,如果能一开始就树立一个正确的长远的职业规划。35岁后的你只会比周围的人更值钱。

华为,小米,等一线互联网公司主流架构技术。如果你有需要,尽管拿走好了。

[外链图片转存中…(img-waF6WjPE-1711296867801)]

如果你觉得自己学习效率低,缺乏正确的指导,可以点击加入资源丰富,学习氛围浓厚的技术圈一起学习交流吧

群内有许多来自一线的技术大牛,也有在小厂或外包公司奋斗的码农,我们致力打造一个平等,高质量的Android交流圈子,不一定能短期就让每个人的技术突飞猛进,但从长远来说,眼光,格局,长远发展的方向才是最重要的。

35岁中年危机大多是因为被短期的利益牵着走,过早压榨掉了价值,如果能一开始就树立一个正确的长远的职业规划。35岁后的你只会比周围的人更值钱。

  • 14
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值