Вызов небиблиотечного кода из библиотеки Android - PullRequest
1 голос
/ 25 сентября 2011

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

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

В подпроекте я расширил основную деятельность библиотеки и добавил статический блок инициализации, который использует отражение для изменения значений полей в библиотеке.

public class MyMainActivityProVersion extends MyMainActivity {

    public static final String TAG = Constants.APP_NAME + "/SubClass";

    static {
        try {
            ConstantsHelper.setConstants(Constants.class);
        } catch (Exception e) {
            Log.d(TAG, "--- Constants not initialised! ---");
            e.printStackTrace();
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }
}

В этом коде ConstantsHelper находится в библиотеке, и я предоставляю Constants.class из моего подпроекта. Это инициализирует константы в проекте библиотеки.

Мой подход работает отлично, за исключением одного конкретного случая использования. Если приложение некоторое время не использовалось и оно «остановлено» операционной системой, статические поля в ConstantsHelper забываются.

Константы должны сбрасываться основным действием (как показано выше), но основное действие даже не запускается, потому что ОС возобновляет другое действие. Результатом этого является то, что инициализация констант забыта, и я не могу повторно инициализировать их, потому что возобновленная деятельность находится в библиотеке (которая не знает о подпроекте).

Как я могу «указать» другим действиям в библиотеке вызывать код из подпроектов при возобновлении? В качестве альтернативы, есть ли способ гарантировать, что некоторый код в моем подпроекте вызывается при каждом резюме?

Ответы [ 3 ]

0 голосов
/ 31 октября 2011

Боюсь, я так и не нашел хорошего ответа на этот вопрос.Я, вероятно, продолжу свое ужасное использование рефлексии и выясню какой-нибудь хакерский обходной путь.

Я чувствовал, что должен вернуться и, по крайней мере, указать, что я не решил эту проблему в пользу других, кто приходит кэта страница.

0 голосов
/ 25 июня 2015

Вы можете решить эту проблему, используя ресурсы Android. По сути, определите свои константы в файле значений XML-ресурсов в вашем проекте библиотеки.
Например. "lib project" \ values ​​\ constants.xml

<resources xmlns:tools="http://schemas.android.com/tools">
   <bool name="const_free_version">false</bool>
   <string name="const_a_constant">pippo</bool>
</resources>

Затем в вашем подпроекте вы можете переопределить значения проекта lib, используя другой файл значений XML-ресурсов:
Например. «подпроект» \ values ​​\ constants.xml

<resources xmlns:tools="http://schemas.android.com/tools">
   <bool name="const_free_version">true</bool>
</resources>

В коде вашего проекта lib, когда вы ссылаетесь на R.bool.const_free_version, вы получаете фактическое значение, основанное на константных значениях подпроекта xml.
Обратите внимание, что вам не нужно переопределять все значения, определенные в проекте lib constants.xml, а только те, которые вам нужны, в вашем подпроекте.

0 голосов
/ 25 сентября 2011

Я думаю, что вы "обманываете", пытаясь обмениваться данными между двумя действиями через статических членов. Это работает, когда они находятся в одном или нескольких связанных загрузчиках классов. Здесь я считаю, что Android использует отдельные загрузчики классов для отдельных действий, но дочерние действия находятся в дочерних загрузчиках классов. Так что ViewActivity может видеть родительский загрузчик классов и видеть статику для родителя. Позже я верю, что родитель уходит, и поэтому ваш ребенок перезагружает MyMainActivity локально, когда вы в следующий раз получаете к нему доступ, и он не инициализируется так, как вы хотели. (Ну, если это не так, это что-то очень похожее на это объяснение.)

Я думаю, что есть более надежные альтернативы. Вы можете использовать LicenseChecker API, чтобы решить, используете ли вы бесплатную или платную версию, а не полагаться на детали жизненного цикла действия и загрузчика классов. Это, вероятно, будет лучше, так как защищает вас от других видов несанкционированного использования.

...