简短的总结是:我如何构建一个APK和单独的库(我指的是某些形式的类集合(理想情况下也是资源),例如JAR,AAR或DEX文件),但不包括那些库中的库. APK; 相反,应用程序在运行时加载它们?
所以我的主要问题是如何构建这样的应用程序(例如Gradle配置).如何指定哪些类进入哪些JAR或DEX文件?我是否为每个想要最终使用的DEX文件创建了一个Android Studio模块?
一个密切相关的问题是Java代码应该如何加载外部库并在运行时访问它们的类.对于后者,我希望通过类加载器从dex文件访问app类时显示的方法可行.
我试着在说明https://developer.android.com/studio/projects/android-library.html,但是这是建立一个APK 不包括依赖库.
我也尝试过Multidex(https://developer.android.com/studio/build/multidex.html),但这似乎并没有让开发人员控制哪些类进入哪个DEX文件,此外,将它们打包成一个APK.AFAICT无法在运行时控制这些DEX文件的加载.
这里有" XY问题 " 的可能性,所以我最好解释一下背景.
我正在为客户构建一个应用程序.它不会通过应用程序商店分发,因此它无法访问正常的更新机制.相反,客户希望应用程序能够通过下载自身的新组件来更新自己,以替换旧组件,而无需手动加载新的APK.这里的主要动机是非技术用户的更新必须容易.如果应用程序可以控制更新过程,它可以使其流畅并引导用户.
此外,该应用程序将用于互联网访问稀缺和昂贵的领域,因此客户希望能够以较小的块(例如2MB)发布应用程序更新,而不是强迫用户重新下载整个应用程序以接收小更新.
如果重要的话,我应该提到的要求的一个方面是,在运行时加载的库应该存在于microSD卡上.这也有助于在没有互联网访问的情况下分发更新.
该应用程序的当前状态是大约50%写入:即,已发布了几个早期版本,但现在需要修改(重组)应用程序以满足上述要求以及其他要求.
android dynamic-class-loaders mobile-application android-gradle-plugin
有人能给我一个很好的资源或者解释一下Class Loaders背后的概念吗?我在类加载器上找到了以下资源http://www.onjava.com/lpt/a/5586但仍然没有帮助.以下问题可能看起来很愚蠢,但试图回答它们总是让我感到困惑.
为什么有这么多种类的装载机?例如:Bootsrap,Comman,Catalina类装载机等,
提前致谢.
请查看以下编辑内容
我正在尝试创建一个JShell实例,它允许我访问,并允许我与它创建的JVM中的对象进行交互.这适用于在编译时可用的类但对于动态加载的类失败.
public class Main {
public static final int A = 1;
public static Main M;
public static void main(String[] args) throws Exception {
M = new Main();
ClassLoader cl = new URLClassLoader(new URL[]{new File("Example.jar").toURL()}, Main.class.getClassLoader());
Class<?> bc = cl.loadClass("com.example.test.Dynamic");//Works
JShell shell = JShell.builder()
.executionEngine(new ExecutionControlProvider() {
@Override
public String name() {
return "direct";
}
@Override
public ExecutionControl generate(ExecutionEnv ee, Map<String, String> map) throws Throwable {
return new DirectExecutionControl();
}
}, null)
.build(); …
Run Code Online (Sandbox Code Playgroud) 我正在开发一个插件系统,插件模块加载如下:
def load_plugins():
plugins=glob.glob("plugins/*.py")
instances=[]
for p in plugins:
try:
name=p.split("/")[-1]
name=name.split(".py")[0]
log.debug("Possible plugin: %s", name)
f, file, desc=imp.find_module(name, ["plugins"])
plugin=imp.load_module('plugins.'+name, f, file, desc)
getattr(plugin, "__init__")(log)
instances=instances+plugin.get_instances()
except Exception as e:
log.info("Failed to load plugin: "+str(p))
log.info("Error: %s " % (e))
log.info(traceback.format_exc(e))
return instances
Run Code Online (Sandbox Code Playgroud)
代码有效,但是对于插件代码中的每个import语句,我都会收到如下警告:
plugins/plugin.py:2: RuntimeWarning: Parent module 'plugins' not found while handling absolute import
import os
Run Code Online (Sandbox Code Playgroud)
没有报告主程序代码的错误,插件工作.
有人可以解释警告意味着什么,我做错了什么.我是否需要单独创建一个空的插件模块并导入它以保持python的快乐?
根据Fred Chung在Android开发者博客上介绍Dalvik中的Custom Class Loading:
Dalvik VM为开发人员提供了执行自定义类加载的工具.应用程序可以从其他位置(如内部存储)或通过网络加载它们,而不是从默认位置加载Dalvik可执行文件("dex").
但是,没有多少开发人员需要进行自定义类加载.但那些按照博客文章中的说明进行操作的人可能会在使用Gradle(Google I/O 2013中引入的Android新构建系统)模仿相同行为时遇到一些问题.
究竟如何调整新构建系统以执行与旧(基于Ant)构建系统相同的中间步骤?
我正在寻找一种通过重写字节代码并重新加载类来动态添加字段到线程的方法,不确定它是否完全可能.欢迎任何指示.我发现了一些关于修改和加载类的信息,我知道JRebel可以无缝地交换你的代码,但不确定这里是否适用相同的方法/工具.
这里的动机是探索理论上更好的替代线程本地对象.如果方法有效,我应该能够用注释替换本地线程,结果应该优于当前的JDK实现.
PS:请救我"所有邪恶言论的根源"
澄清用例:
想象一下,我有一个ThreadLocal类:
class A {
ThreadLocal<Counter> counter;
...
counter.get().inc()
}
Run Code Online (Sandbox Code Playgroud)
我想用注释替换它:
class A {
@ThreadLocal
Counter counter;
...
counter.inc()
}
Run Code Online (Sandbox Code Playgroud)
但是代替上面的代码生成我想改变Thread,这样Thread现在有一个Acounter字段,实际的代码将是:
class A {
// Nothing here, field is now in Thread
...
Thread.currentThread().Acounter.inc()
}
Run Code Online (Sandbox Code Playgroud) java classloader dynamic-class-loaders dynamic-class-creation
是否可以在Java中加载类并"伪造"类的包名称/规范名称?我尝试这样做,显而易见的方式,但我得到一个"类名不匹配"的消息ClassDefNotFoundException
.
我这样做的原因是我正在尝试加载一个在默认包中编写的API,以便我可以直接使用它而不使用反射.代码将在表示包和包名称导入的文件夹结构中针对类进行编译.即:
./com/DefaultPackageClass.class
// ...
import com.DefaultPackageClass;
import java.util.Vector;
// ...
Run Code Online (Sandbox Code Playgroud)
我目前的代码如下:
public Class loadClass(String name) throws ClassNotFoundException {
if(!CLASS_NAME.equals(name))
return super.loadClass(name);
try {
URL myUrl = new URL(fileUrl);
URLConnection connection = myUrl.openConnection();
InputStream input = connection.getInputStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int data = input.read();
while(data != -1){
buffer.write(data);
data = input.read();
}
input.close();
byte[] classData = buffer.toByteArray();
return defineClass(CLASS_NAME,
classData, 0, classData.length);
} catch (MalformedURLException e) {
throw new UndeclaredThrowableException(e);
} catch (IOException e) {
throw …
Run Code Online (Sandbox Code Playgroud) 我已经看过-Xbootclasspath/p:用于动态加载类的路径,请您通过提供示例详细说明并解释.
主要目标是使用我自己的实现覆盖Android系统类(Activity,View等).
http://android-developers.blogspot.com/2011/07/custom-class-loading-in-dalvik.html
实现了自定义类加载的ClassLoader,加载非系统类(自定义类).
但是当我尝试使用我的实现加载Activity时 - 它没有加载,因为ClassLoader已经在其缓存中有这个类:
/**
* Returns the class with the specified name if it has already been loaded
* by the virtual machine or {@code null} if it has not yet been loaded.
*
* @param className
* the name of the class to look for.
* @return the {@code Class} object or {@code null} if the requested class
* has not been loaded.
*/
protected final Class<?> findLoadedClass(String className) {
ClassLoader loader;
if (this == BootClassLoader.getInstance()) …
Run Code Online (Sandbox Code Playgroud) 我们目前正在研究在我们的应用程序中使用OneJar(由于多种原因),但我们的应用程序使用了许多自定义URLClassloader
来加载应用程序扩展.
当捆绑为"OneJar"Jar时,我们会遇到ClassNotFound
异常.有问题的类存在于捆绑的Jar中,我们只是依靠类加载器机制来解析父/子关系.
那是.我们有一个共同interface
的存储在捆绑的Jar中(应该在父类的类加载器上下文中).扩展实现了这一点interface
(允许我们调用扩展)并依赖子类加载器使用父类加载器的资源查找功能的能力.
是否有任何人对此有任何经验或对我们如何解决它有任何启示.
我很想在其它类似机制(捆绑我们的库JAR的到一个JAR资源,不需要使用一切,罐其unjar成一个单一的文件)