前言:
云端架構(gòu)提出一個(gè)邊緣計(jì)算的的概念,就是云端提供一個(gè)或者多個(gè)動(dòng)態(tài)的jar包,里面包含了一些計(jì)算方法,需要Android動(dòng)態(tài)的去加載jar包,獲取其中的方法。
其中包含了2個(gè)難點(diǎn):
1:如何把一個(gè)普通的jar包改為Android可以識(shí)別的jar包。
2:DexClassLoader類實(shí)現(xiàn)Jar的動(dòng)態(tài)加載并通過反射去獲取jar包的方法。
下面我們就說明一下。
1:如何把一個(gè)普通的jar包改為Android可以識(shí)別的jar包
其實(shí)很簡單,使用Android SDK提供的工具(在build-tools目錄下,隨便一個(gè)版本),有些版本的沒有,可以網(wǎng)上下載。利用dx工具,將java的jar包轉(zhuǎn)為Android虛擬機(jī)可以認(rèn)識(shí)的字節(jié)碼,具體來說,就是在此文件夾下執(zhí)行如下的命令:
dx --dex --output=dex.jar Hello.jar
其中,Hello.jar是我們的原jar包,dex.jar是我們用dx工具處理后的jar包,是Android虛擬機(jī)可以識(shí)別的jar文件(注意JDK版本一定要在9之下,否則會(huì)報(bào)錯(cuò)),接下來就可以進(jìn)行第二步操作了,這里,我們需要使用DexClassLoader類實(shí)現(xiàn)Jar的動(dòng)態(tài)加載。
2: DexClassLoader加載Jar的動(dòng)態(tài)加載
1. public String getAlgorithm(String className, String methodName) {
2. File directory = FileUtil.getInternalCacheDirectory(APPConstant.JAR_DIR);
3. File fP = new File(directory.getAbsolutePath());
4. for (File file : fP.listFiles()) {
5. Context context = BaseApplication.getContext();
6. File optimizedDexOutputPath = context.getDir("temp", Context.MODE_PRIVATE);
7. String filePath = file.getAbsolutePath();
8. String optimizedPath = optimizedDexOutputPath.getAbsolutePath();
9. DexClassLoader classLoader = new DexClassLoader(filePath, optimizedPath, null, context.getClassLoader());
10. try {
11. Class iClass = classLoader.loadClass(className);
12. Constructor localConstructor = iClass.getConstructor(new Class[]{});
13. Object obj = localConstructor.newInstance(new Object[]{});
14. Method method = iClass.getDeclaredMethod(methodName, new Class[0]);
15. method.setAccessible(true);
16. String name = (String) method.invoke(obj);
17. Log.w(TAG, "name:" + name);
18. return name;
19. } catch (Exception e) {
20. Log.e(TAG, "解析jar包失?。? + e.getMessage());
21. }
22. }
23. return "";
24. }
獲取jar包所在文件夾里的所有jar包遍歷,通過DexClassLoader 加載所有jar包,再通過反射技術(shù)根據(jù)類名和方法名去調(diào)用對(duì)應(yīng)的方法,這樣就完成了jar包的動(dòng)態(tài)調(diào)用。