Как добавить динамическую библиотеку в Android? - PullRequest
12 голосов
/ 12 июня 2010

Я хочу добавить не Android общую библиотеку в Android, чтобы каждое приложение на устройстве могло использовать ее.Я имею в виду использование упакованных классов как основной библиотеки, как если бы они присутствовали в самом приложении.

Я изучил исходный код Android, чтобы найти способ добавить новый путь к приложению ClassLoader, и выяснил,что он создается во время запуска, и нет возможности изменить пути позже.Я могу использовать свой собственный ClassLoader, но все, что я получу после загрузки класса, будет ссылка на объект Class.Таким образом, я буду вынужден работать через механизм отражения, который работает медленнее, чем собственная система выполнения.

Есть ли способ организовать общую библиотеку на Android?

Обновление: просто чтобы прояснить это, мне не нужно взаимодействие между приложениями.Мне нужны классы, которые я могу использовать в любом приложении.Кроме того, статические библиотеки не совсем соответствуют моим потребностям, потому что это приведет к расширению приложений.

Ответы [ 4 ]

10 голосов
/ 04 сентября 2012

Существует два трюка для создания библиотеки динамической загрузки в Android

  1. используйте sharedUserId в AndroidManifest для ваших приложений и проекта библиотеки

  2. используйте dalvik.system.DexClassLoader для загрузки библиотеки

Код библиотеки:

Он содержит только код Java без особых точек входа для Android. AndroidManifest.xml просто содержит этот android:sharedUserId атрибут

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testlib"
    android:sharedUserId="com.example.testlib"
    android:versionCode="1"
    android:versionName="1.0">

    <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="15" />

    <application android:label="@string/app_name"
        android:icon="@drawable/ic_launcher"
        android:theme="@style/AppTheme">

    </application>

</manifest>

TestCore.java

package com.example.testlib;

public class TestCore implements ITestCore{
    private int count = 0;
    public String testString(String arg) {
        String res = arg + " " + count;
        count++;
        return res;
    }
}

Пример кода приложения

Приложение, которое использует библиотеку. Вот только AndroidManifest.xml и TestApplication.java, которые делают свое дело. Все остальные сотрудники, работающие с приложениями, работают как обычно.

AndroidManifest.xml

Будьте осторожны, чтобы использовать то же значение android: sharedUserId в AndroidManifest.xml как библиотечное

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.testapp"
    android:sharedUserId="com.example.testlib"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:name=".TestApplication" >
        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value="android.app.Activity" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
                <category android:name="android.intent.category.DEFAULT"/>
                </intent-filter>
        </activity>
    </application>

</manifest>

ITestCore.java

Интерфейс библиотеки должен быть объявлен в приложении, чтобы избежать использования отражения

package com.example.testlib;

public interface ITestCore {
    String testString(String arg);
}

TestApplication.java

В обработчике applicationCreate приложения происходит реальная работа

package com.example.testapp;

import com.example.testlib.ITestCore;
import dalvik.system.DexClassLoader;
import android.app.Application;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.util.Log;

public class TestApplication extends Application {
    ClassLoader libClassLoader;

    @Override
    public void onCreate() {
        PackageManager pm = getPackageManager();
        String libSrcPath = null;
        for (ApplicationInfo app : pm.getInstalledApplications(0)) {
            if (app.packageName.equals("com.rhomobile.testlibrary")) {
                libSrcPath = app.sourceDir;
                Log.d("TestApplication", ">>>>>>>>>>>>>>> package: " + app.packageName + ", sourceDir: " + app.sourceDir);
            }
        }
        try {
            libClassLoader = new DexClassLoader(libSrcPath, getDir("dex", 0).getAbsolutePath(), null, getClassLoader());
            Class<?> clazz = libClassLoader.loadClass("com.rhomobile.testlib.TestCore");            
            try {
                ITestCore core = (ITestCore)clazz.newInstance();
                String str = core.testString("TestApplication 1:");
                Log.i("TestApplication", ">>>>>>>>>>>>>>> output: " + str);
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        } catch (ClassNotFoundException e) {
            Log.e("TestApplication", libClassLoader.toString());
            e.printStackTrace();
        }
    }
}
3 голосов
/ 28 июля 2011

Недавний пост в блоге Android объясняет, что именно мне нужно:

Dalvik VM предоставляет разработчикам средства для загрузки пользовательских классов. Вместо загрузки исполняемых файлов Dalvik («dex») из расположения по умолчанию приложение может загружать их из альтернативных расположений, например из внутреннего хранилища или по сети.

Ключ должен использовать DexClassLoader для загрузки необходимой библиотеки. После этого к коду можно получить доступ либо через интерфейсы, либо с помощью отражения.

2 голосов
/ 13 июня 2010

Для статических библиотек многократно используемых классов вы можете использовать проекты библиотек . Для безопасного динамического взаимодействия с другими приложениями вы можете привязать к сервису .

0 голосов
/ 13 июня 2010

Даже если вы получаете объект Class, модель безопасности (связыватель) в Android запрещает приложениям читать в каталоге другого приложения.

Лучшее, что вы можете сделать на телефоне без полномочий root, - это создавать библиотеки через Intents.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...