android实现代码的动态加载

本文介绍了如何在Android应用中实现代码的动态加载,以应对功能频繁变动的问题。通过将变化的代码逻辑放到服务器,以Dex文件形式进行下载和动态加载,避免频繁更新APP。详细步骤包括制作Dex文件、从服务器下载并加载,同时讨论了可能的安全隐患及优化方案。
摘要由CSDN通过智能技术生成
在开发过程往往会遇到下面这种情况:
    我们App某些功能会经常变更,正常情况下我们需要根据功能变更来升级APP。但是这样会平凡的升级APP,造成很差的用户体验。

引出:前段时间项目中有这样一个需求:下载到本地的视频需要在播放时加载字幕,但是某些视频我们的服务器中不存在字幕,怎么办呢? 
后来发现某个网页能通过影片名查询到相应的字幕,并下载下来。但是问题是,我们的app不能拿到相应的接口,接下来又该怎么办呢?
后来通过一些逆向开发手段,捕获到了字幕的下载路径,但是他是HTML的页面以Table标签的方式展示出来的,这样我们就可以通过java代码动态的解析这些html的标签,拿到字幕下载地址,并进行下载到我们的服务器上。但是后来更坑的事情出现了,某一天我们的app的在搜索字幕时,瘫痪了,怎么回事呢?原来发现字幕提供网站返回的html的形式发生了变化,导致解析异常。怎么办呢?答案是:修改解析html的解析代码。重新让用户更新新的app。可是问题来了,如果这个字幕网站经常变更,我们每次都让用户更新app么?  那这样的话就只能一个字形容了:“坑”。

相信大家有类似的经历,遇到这种情况怎么办呢? 这让我突然想到了Web App的原理,从这个原理总结到了一个办法,那就是把变化的交给服务器,不变的交给app.那到底怎么做呢?让我慢慢到来~~~
 
首先在我们这里变化的是字幕网站中返回的html,不变的是结果要对字幕下载解决的处理。那么我们能不能将变化的html的解析逻辑放到服务器呢,每次启动app的时候就从服务器将解析html的逻辑从服务器下载下来,动态的打包到我们的app,并实例化对象,调用解析html方法。如果字幕库网站发生变化时,动态更新我们服务器上的解析代码,并重新下载相应的解析代码,就能实现不变应万变。
下面是图形流程:


一句话总结上面的流程: 当字幕库变化时,我们只需要立即更新服务器的相应工具类的实现逻辑,并通知app端动态的下载这个工具类,这样我们就可以在不跟新app的情况下,也能响应字幕库的变化。


好,到此结束,我们应该怎么具体来实现这个流程呢?
我分两个步骤来实现:一就是:制作Dex文件,二就是:从服务器下载Dex文件并动态加载打包到我们的app中。


制作Dex文件:
提到Dex文件,可能部分人不太理解为什么弄个Dex文件呢?为什么不直接写一个java类文件呢?原因很简单,因为如果在用户下载java源文件情况下,用户手机需要去编译这个java源文件,并生产字节码class文件。可是用户的手机是不装有编译环境的,因此必须是编译后的文件才能被识别。
那么Dex文件又是什么呢?  我们都知道在我们要运行java程序时,必须要编译成class的字节码文件才能被jvm虚拟机识别。可是在我们的安卓手机上运行的是Dalvik虚拟机,他不能直接处理class的字节码文件,必须是class字节码文件经过优化后的Dex文件。我们可以认为Dex文件就是class文件经过优化后生成。

制作Dex文件步骤:
(1)制作java源文件

(2)生成jar文件




经过上面的步骤后我的桌面上就生成了test.jar文件,我们也可打开这个jar文件:

发现里面就是我们的class字节码文件。接下来我们就是要处理class的字节码文件,生成Dex文件了。

(3)生产Dex文件
生成Dex文件需要使用到dx工具,这个工具在哪里有呢?  答案是:我们的android开发的sdk中。打开我们的sdk,进入到如下目录

将上一步生成的jar文件拷贝到当前的dx工具目录下,打开cmd电脑终端进入到当前目录,使用下面的命令就能生成Dex文件了.

dx --dex --output=yjt.jar test.jar

然后就会在当前目录生成一个yjt.jar的文件,此时在打开可以看到里面就已经省成了一个dex文件了

到此,我们的dex文件已经完成。只需要上传到服务器既可。

从服务器下载Dex文件并动态加载打包到我们的app中
由于这里是从服务器下载,需要服务器提供接口,因此我们就不从服务器下载了,我直接将我们的最后生成的dex文件放到手机的sd卡中。然后从sd卡中动态加载进我们的app中。
我就将生成的dex文件放到sd卡的目录下,接下来掩饰如何加载。
(1)先模拟创建我们的APP应用
界面:

(2)下面就是要加载Dex文件了
这里设计到两个知识点:类加载器和反射
类加载器:主要有两个PatchClassLoader和DexClassLoader,两个类的作用都是将classes加载进内存,区别在于PatchClassLoader只能加载我们app已经打包好已安装的类文件。而DexClassLoader是可以加载sd卡上的外部类文件。因此在这里选择DexClassLoader。
反射的主要用途,就是将类文件加载进内存时,需要实例化当前的类对象,并调用相应的方法。
直接上代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package  com.yjt;
 
import  java.io.File;
import  java.lang.reflect.Method;
 
import  dalvik.system.DexClassLoader;
 
import  android.os.Bundle;
import  android.os.Environment;
import  android.app.Activity;
import  android.content.Context;
import  android.view.Menu;
import  android.view.View;
import  android.view.View.OnClickListener;
import  android.widget.Button;
import  android.widget.Toast;
 
public  class  MainActivity  extends  Activity  implements  OnClickListener
{
     private  Button load, invoke;
 
     private  boolean 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值