是否可以在运行时从 Android 应用程序动态加载库? [英] Is it possible to dynamically load a library at runtime from an Android application?

查看:39
本文介绍了是否可以在运行时从 Android 应用程序动态加载库?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有什么办法可以让Android应用程序在运行时下载和使用Java库?

Is there any way to make an Android application to download and use a Java library at runtime?

这是一个例子:

想象一下,应用程序需要根据输入值进行一些计算.应用程序要求提供这些输入值,然后检查所需的 ClasseMethod 是否可用.

Imagine that the application needs to make some calculations depending on the input values. The application asks for these input values and then checks if the required Classes or Methods are available.

如果没有,它会连接到服务器,下载所需的库,并在运行时加载它以使用反射技术调用所需的方法.实现可能会根据各种标准(例如下载库的用户)而变化.

If not, it connects to a server, downloads the needed library, and loads it at runtime to calls the required methods using reflection techniques. The implementation could change depending on various criteria such as the user who is downloading the library.

推荐答案

抱歉,我迟到了,问题已经被接受了,但是是的,您可以下载并执行外部库.这是我的做法:

Sorry, I'm late and the question has already an accepted answer, but yes, you can download and execute external libraries. Here is the way I did:

我想知道这是否可行,所以我编写了以下类:

I was wondering whether this was feasible so I wrote the following class:

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.");
    }
}

然后我将它打包成一个 DEX 文件,作为 /sdcard/shlublu.jar 保存在我设备的 SD 卡上.

And I packaged it in a DEX file that I saved on my device's SD card as /sdcard/shlublu.jar.

然后我在从我的 Eclipse 项目中删除 MyClass 并清理它之后编写了下面的愚蠢的程序":

Then I wrote the "stupid program" below, after having removed MyClass from my Eclipse project and cleaned it:

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();
        }
    }
}

它基本上以这种方式加载 MyClass 类:

It basically loads the class MyClass that way:

使用它从"/sdcard/shlublu.jar"

并将这个类存储到应用程序的"dex"私有目录(手机内部存储).

and store this class to the application's "dex" private directory (internal storage of the phone).

然后,它创建一个 MyClass 的实例,并在创建的实例上调用 doSomething().

Then, it creates an instance of MyClass and invokes doSomething() on the created instance.

它有效......我在我的 LogCat 中看到了 MyClass 中定义的跟踪:

And it works... I see the traces defined in MyClass in my LogCat:

我已经在模拟器 2.1 和我的实体 HTC 手机(运行 Android 2.2 并且没有 root)上尝试过.

I've tried on both an emulator 2.1 and on my physical HTC cellphone (which is running Android 2.2 and which is NOT rooted).

这意味着您可以为应用程序创建外部 DEX 文件以下载和执行它们.这里的方法很困难(丑陋的 Object 强制转换,Method.invoke() 丑陋的调用...),但它必须可以使用 Interfaces 使东西更干净.

This means you can create external DEX files for the application to download and execute them. Here it was made the hard way (ugly Object casts, Method.invoke() ugly calls...), but it must be possible to play with Interfaces to make something cleaner.

哇.我是第一个惊讶的.我期待 SecurityException.

Wow. I'm the first surprised. I was expecting a SecurityException.

一些有助于调查更多的事实:

Some facts to help investigating more:

  • 我的 DEX shlublu.jar 已签名,但我的应用程序未签名
  • 我的应用是通过 Eclipse/USB 连接执行的.所以这是一个在DEBUG模式下编译的未签名APK

这篇关于是否可以在运行时从 Android 应用程序动态加载库?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆