llu*_*ero 69 reflection android classloader dalvik android-library
有没有办法让Android应用程序在运行时下载和使用Java库?
这是一个例子:
想象一下,应用程序需要根据输入值进行一些计算.应用程序请求输入这些值,然后检查所需的Classes或Methods是否可用.
如果没有,它将连接到服务器,下载所需的库,并在运行时加载它以使用反射技术调用所需的方法.实施可能会根据各种标准(例如下载库的用户)而发生变化.
Shl*_*blu 91
对不起,我来晚了,问题已经有一个公认的答案,但肯定的,你可以下载并执行外部库.这是我的方式:
我想知道这是否可行,所以我编写了以下课程:
package org.shlublu.android.sandbox;
import android.util.Log;
public class MyClass {
public MyClass() {
Log.d(MyClass.class.getName(), "MyClass: constructor called.");
}
public void doSomething() {
Log.d(MyClass.class.getName(), "MyClass: doSomething() called.");
}
}
Run Code Online (Sandbox Code Playgroud)
我把它打包成一个DEX文件,我保存在设备的SD卡上/sdcard/shlublu.jar.
然后,在MyClass从Eclipse项目中删除并清除它后,我在下面写了"愚蠢的程序" :
public class Main extends Activity {
@SuppressWarnings("unchecked")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
try {
final String libPath = Environment.getExternalStorageDirectory() + "/shlublu.jar";
final File tmpDir = getDir("dex", 0);
final DexClassLoader classloader = new DexClassLoader(libPath, tmpDir.getAbsolutePath(), null, this.getClass().getClassLoader());
final Class<Object> classToLoad = (Class<Object>) classloader.loadClass("org.shlublu.android.sandbox.MyClass");
final Object myInstance = classToLoad.newInstance();
final Method doSomething = classToLoad.getMethod("doSomething");
doSomething.invoke(myInstance);
} catch (Exception e) {
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
它基本上以MyClass这种方式加载类:
创建一个 DexClassLoader
用它来提取类MyClass从"/sdcard/shlublu.jar"
并将此类存储到应用程序的"dex"私有目录(手机的内部存储).
然后,它创建一个实例MyClass并doSomething()在创建的实例上调用.
它工作......我看到MyClass我的LogCat中定义的痕迹:

我试过仿真器2.1和我的物理HTC手机(运行Android 2.2并且没有生根).
这意味着您可以为应用程序创建外部DEX文件以下载和执行它们.在这里它是艰难的方式(丑陋的Object演员,Method.invoke()丑陋的电话......),但必须有可能与Interfaces 玩,使事情更清洁.
哇.我是第一个感到惊讶的人.我在期待一个SecurityException.
一些事实有助于调查更多:
小智 15
Shlublu的anwser非常好.一些小东西虽然有助于初学者:
在库项目清单中确保你有:(
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".NotExecutable"
android:label="@string/app_name">
</activity>
</application>
".NotExecutable"不是保留字.只是我必须在这里放东西)
要制作.dex文件,只需将库项目作为android应用程序运行(用于编译),然后从项目的bin文件夹中找到.apk文件.
其他步骤与Shlublu描述的相同.