На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Hsilgos
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
> Android. Динамическая подгрузка и выполнение кода из внешнего jar-файла , Не получается использовать интерфейсы - конфликтуют:(
    Всем привет!

    Когда-то тут на заре знакомства с Android создавал тему про обновление программы во время ее собственного сеанса: http://forum.sources.ru/index.php?showtopic=357965. Тогда мне не сказали почти ничего нового, посоветовав не слезать с Google Play и его опции автоматического обновления. Но мы с шефом не хотим зацикливаться только на этом сервисе, скорее всего, будем распространять приложение из других источников, например, создадим раздел на корпоративном сайте, посвященный программе. А для других источников автоматическое обновление уже не будет работать. В связи с этим серьезно рассматриваем тему автоматического обновления программного кода и ресурсов программы внутри ее сеанса, при наличии новой версии на сайте.

    Вечерком я наткнулся на любопытную статейку в блогах на Android Developers: Android Developers Blog: Custom Class Loading in Dalvik. В ней говорилось о том, как динамически подгружать классы, не связанные статически с основной программой, в качестве источника использовался раздел assets (гм, еще не приходилось с такими ресурсами работать, использовал res/raw, не знаю, в чем различие). Классы могут быть подгружены стандартным класс-лоадером только с диска (вроде я прав?), поэтому перед загрузкой файл с ними записывался во внутреннее хранилище. В статье приведен программный код, но законченного программного примера-проекта нет.

    Сегодня, доделав некоторые намеченные фишки по интерфейсу программы, я решил на отдельном проекте попробовать в несколько другом виде реализовать динамическую загрузку класса и выполнение программного код из него. Для простоты решил разместить подгружаемую библиотеку на SD-карте. Часа два боролся с разными проблемами, не буду детализровать, помогли вот эти две странички на StackOverflow: http://stackoverflow.com/questions/3022454...-android-dalvik и http://stackoverflow.com/questions/6857807...d-applicat?rq=1. В итоге получилось подгрузить с диска класс, создать объект и вызвать его метод. В коде этого метода просто выводился AlertDialog типа Hello World.

    Однако, для вызова этого метода пришлось использовать механизмы Java Reflect Api. В случае сложного интерфейса между загрузчиком и подгружаемыми модулями, в том числе межмодульного взаимодействия это уже не самое лучшее решение. Удобнее бы было разработать ряд Java-интерфейсов, известных и в подгружаемом коде, и в загрузчике, в последнем при создании объектов подгружаемых классов приводить их к типам этих интерфейсов, а в библиотеки сами классы от этих интерфейсов на следовать. Но так у меня сделать не получилось Dalvik VM открыто протестует, встречая объявление одного и того же интерфейса и в загрузчике, и в полгружаемом коде. Как мне это обойти?

    Приведу пример. В качестве примера я выбрал динамическую прдгрузку классов, решающих задачки с projecteuler.net. Каждая задачка - имплементация такого интерфейса:

    ExpandedWrap disabled
      interface Problem
      {
          void solve(Activity activity);
      }


    Конкретный класс-реализацию приводить не буду, допустим, она просто выводит сообщение с помощью AlertDialog, опираясь на аргумент activity. Вот такой у меня получился код для загрузчика:

    ExpandedWrap disabled
      public void onCreate(Bundle savedInstanceState)
          {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.activity_main);
              
              final String SECONDARY_DEX_NAME = "problems.jar";
              
              File dexInternalStoragePath = new File(Environment.getExternalStorageDirectory().getPath() + "/euler",
                      SECONDARY_DEX_NAME);
              Log.i("euler", dexInternalStoragePath.exists() ? "Файл существует" : "Файл не найден");
              
              // Внутреннее хранилище для потимизированных класс-файлов
              final File optimizedDexOutputPath = getDir("outdex", Context.MODE_PRIVATE);
       
              DexClassLoader cl = new DexClassLoader(dexInternalStoragePath.getAbsolutePath(),
                                                     optimizedDexOutputPath.getAbsolutePath(),
                                                     null,
                                                     getClassLoader());
              Class<?> problemClass = null;
              try
              {
                  problemClass = cl.loadClass("ru.homez.euler.Problem1");
                  
                  Problem problem = (Problem)problemClass.newInstance();
                  problem.solve(this);
                  
                  /*
                  Object problem = problemClass.newInstance();
                  final Method solve = problemClass.getMethod("solve", Activity.class);      
                  solve.invoke(problem, this);
                  */
              }
              catch (Exception e)
              {
                  e.printStackTrace();
              }
          }


    Здесь внутри комментария показан альтернативный вариант с помощью Java Reflect API. А этот код генерит у меня такое исключение на loadClass:
    ExpandedWrap disabled
      07-14 23:48:53.763: E/AndroidRuntime(25619): java.lang.IllegalAccessError: Class ref in pre-verified class resolved to unexpected implementation


    Где-то вычитал, что это из-за конфликта повторно определенных классов/интерфейсах. А у меня ж интерфейс Problem определен в обоих проектах. Как быть?
      Проблему решил. Из подгружаемого библиотечного jar-файла нужно удалить этот интерфейс. А в загрузчике нужно его определить со спецификатором public, так как иначе загрузчик классов DexClassLoader просто его не увидит.

      Но появился другой вопрос: есть ли возможность каким-нибудь образом подгружать "сырые" class-файлы, без обертки в jar? Просто вот хочу доделать этот пример, создать на своем личном файле хранилище для классов, решающих задачи с projecteuler.net, придумать какой-то скрипт, который будет возвращать их текущие версии, и если в программе для каких-то классов используются более старые версии, то подгружать новые во внутреннее хранилище, а оттуда при необходимости в сеанс программы (если я захочу решить получить решение какой-то определенной задачи). Но на этом сайте у меня уже 169 решенных задач, создавать для каждой свой проект в Eclipse и чтобы каждая была обернута в jar - это безумие.
        Гм, ну ведь можно все задачки держать в одном библиотечном проекте. А потом вытаскивать class-файлы из получающегося jar и перепаковывать их в персональные jar-файлы, докомплектовывая каждый своим classes.dex. Так как все это можно делать консольными командами, то когда число задач возрастет, можно написать батник, который будет это делать автоматически.

        P.S. Пишу тут сам для себя:)
          Цитата Homez @
          Но мы с шефом не хотим зацикливаться только на этом сервисе, скорее всего, будем распространять приложение из других источников, например, создадим раздел на корпоративном сайте, посвященный программе.

          У вас реально будет 0 (ноль) закачек, так что не партесь. Линк на гугл плей и вуаля.
            Почему 0?

            Добавлено
            Дело в том, что еще нужно будет написать Android-приложене для водителей сервиса со статусо индивидульного предпринимателя. Там уже нет смысла выкладывать на Google Play, так как приложение это будет уже не для широкого круга лиц. И что тогда?

            Добавлено
            Эмик Ферман
            Недоказанное утверждение. На сайт нашей фирмы ежедневно заходит 500 человек. Есть постоянные клиенты. Наверняка среди них есть пользователи Android. Так почему бы не выкладывть apk прямо на нашем сайте? Ну разумеется, лучше давать и линк на Google Play. Но мне не кажется, что закачек будет уж так и 0. Допустим, не так и много, но точно не 0. Немного и 0 - это разные вещи.
              Цитата Homez @
              Там уже нет смысла выкладывать на Google Play, так как приложение это будет уже не для широкого круга лиц. И что тогда?

              Тем кому надо - скачают. А тем кому не надо - не скачают. Вот и всё. На маркете сейчас более 600 000 приложений, так что +1 погоду не сделает.

              Цитата Homez @
              Так почему бы не выкладывть apk прямо на нашем сайте?

              Потому что им надо делать adb install -R taxi.apk каждый раз, следить за версиями и т.д.
                Цитата Эмик Ферман @
                Тем кому надо - скачают. А тем кому не надо - не скачают. Вот и всё. На маркете сейчас более 600 000 приложений, так что +1 погоду не сделает.
                Совсем не резон. Те водители, которые должны работать с нашим сервисом, получается, должны скачивать прогу с Google Play? Это же все равно, что я сделаю прогу на заказ и выложу ее на Яндекс-Маркете, а заказчик пусть оттуда и качает.

                +1 погоду не сделает? А без этого приложения водитель не сможет работать с нашим сервисом!

                Цитата Эмик Ферман @
                Потому что им надо делать adb install -R taxi.apk каждый раз, следить за версиями и т.д.

                Гм, а почему просто не скачать apk на SD-карту и поставить оттуда? Зачем такие сложности через adb? Я вроде ни разу так ничего не ставил.

                Если же я сделаю автообновление внутри сеанса программы, то ничего следить и не нужно будет клиенту. Достаточно написать очень продуманный, функциональный загрузчик.
                  Цитата Homez @
                  Те водители, которые должны работать с нашим сервисом, получается, должны скачивать прогу с Google Play?

                  А что в этом такого? Это просто и удобно. Не нужно дров, шнурков и знания adb. Водилы далеки от этого.
                  Цитата Homez @
                  Гм, а почему просто не скачать apk на SD-карту и поставить оттуда? Зачем такие сложности через adb? Я вроде ни разу так ничего не ставил.

                  Это всеравно гимор.

                  Добавлено
                  Более того, а ка ты собираешся креш репорты получать? Или ты хотя бы flurry прикрутил?
                    Цитата Эмик Ферман @
                    Более того, а ка ты собираешся креш репорты получать? Или ты хотя бы flurry прикрутил?
                    Гм, не понимаю, о чем ты.

                    Добавлено
                    Цитата Эмик Ферман @
                    А что в этом такого? Это просто и удобно. Не нужно дров, шнурков и знания adb. Водилы далеки от этого.

                    Приложение может ставиться, когда водитель приезжает в офис заключить договор. Обычная практика. Так у нас обстоят дела с водительским клиентом системы ТаксиМастер - он и под Windows Mobile, и под Android есть.

                    Добавлено
                    Цитата Homez @
                    Это всеравно гимор.
                    Что-то я такого не заметил.
                      Цитата Homez @
                      Гм, не понимаю, о чем ты.

                      Ну вот завалилось у тебя приложение на железке клиента. Как ты увидишь стек трейс креша? Голубиной почтой?
                      Цитата Homez @
                      Приложение может ставиться, когда водитель приезжает в офис заключить договор. Обычная практика. Так у нас обстоят дела с водительским клиентом системы ТаксиМастер - он и под Windows Mobile, и под Android есть.

                      Если кому то надо ваше приложение, то его из телефона вытянут за 10 минут. А если 10 водил, то всем 10м приезжать?
                      Цитата Homez @
                      Что-то я такого не заметил.

                      С опытом придёт :tong:
                        Цитата Эмик Ферман @
                        Если кому то надо ваше приложение, то его из телефона вытянут за 10 минут. А если 10 водил, то всем 10м приезжать?

                        Это не мера предосторожности. Обычная практика. Клиент ТаксиМастера ставится платный, шеф даже берет его стоимость с водителя. Если водила хороший, работящий, то потом это окупит. Со всеми водителями пока договор совершается в офисе, так что почему бы и не ставить сразу на телефон программу.

                        Возможно, в будущем будем заключать и "удаленные" договора, когда личное присутствие водителя в офисе может не понадобиться. Но я все равно не вижу причин направлять всех на Google Play. Приложение будет специализированное, ни к чему ему будет валяться на паблике в открытом доступе. Хотя мы с шефом такие моменты не обсуждали, его еще и написать надо, это приложение для водителей, пока есть только очень скромные зачатки.

                        А если приложение вообще "закрытое", но требуется удаленным клиентам? Его тоже выкладывать на Google Play? А если я на заказ напишу приложение для планшетов, например, для какой-нибудь образовательной организации, для проведения тестирования? Его тоже туда выкладывать?

                        У меня начинает складываться впечатление, будто вы являетесь Google Android Advocate, поэтому так и агитируете за Google Play.

                        По поводу краш-репортов. Я пошукал немного на эту тему. Говорят, что стандартный функционал Android, который обеспечивает краш-репорты через сервис Google Play, довольно скромный, и для реального анализа проблем его использовать затруднительно. Существуют альтернативы, предоставляющие больше возможностей, и как я понял, они к Google Play не привязаны.

                        Добавлю, что, честно, про краш-репорты я вообще пока ничего и не думал, и вот только сегодня узнал, в первую очередь от тебя, Эмик Ферман, что на Android есть для этого сервисы. Но я уже почти закончил работу над первой версией программы, на будущей неделе ее бы уже пора выпускать. Поэтому такая серьезная доработка, если решим с шефом, что она нужна, останется для следующих релизов.

                        Добавлено
                        Цитата Эмик Ферман @
                        С опытом придёт :tong:

                        Ага, следуя тебе, по мере набора опыта мне будет все труднее и труднее ставить программы на устройство Android не с сервиса Google Play. У меня шеф не программист, не технарь, но ему не составляет проблемы поставить очередную версию программы, присланную ему мной по электронной почте.

                        Добавлено
                        Тема-то вовсе изначально не про то, использовать ли Googlу Play или нет. Тема про динамическую загрузку классов в сеансе приложения Android. Это может понадобиться не только собственно для ообновления. Например, так мы сможем обеспечить модульность, когда для использования каких-то дополнительных возможностей клиент просто может прямо в приложении инициировать загрузку дополнительного модуля и начать им пользоваться. Например, это карты. Кому-то может это и не надо, так зачем под завязку забивать apk классами и ресурсами? Если человеку надо, он всегда сможет такие дополнительные модули докачать, а не делать сразу загрузку всего-всего в одном apk в несколько сотен килобайт.
                          Цитата Homez @
                          Клиент ТаксиМастера ставится платный, шеф даже берет его стоимость с водителя. Если водила хороший, работящий, то потом это окупит. Со всеми водителями пока договор совершается в офисе, так что почему бы и не ставить сразу на телефон программу.

                          А что мешает водиле стянуть софтину с телефона и отдать её другому водиле? Зачем второму платить?
                          Цитата Homez @
                          По поводу краш-репортов. Я пошукал немного на эту тему. Говорят, что стандартный функционал Android, который обеспечивает краш-репорты через сервис Google Play, довольно скромный, и для реального анализа проблем его использовать затруднительно. Существуют альтернативы, предоставляющие больше возможностей, и как я понял, они к Google Play не привязаны.
                          Добавлю, что, честно, про краш-репорты я вообще пока ничего и не думал, и вот только сегодня узнал, в первую очередь от тебя, Эмик Ферман, что на Android есть для этого сервисы. Но я уже почти закончил работу над первой версией программы, на будущей неделе ее бы уже пора выпускать. Поэтому такая серьезная доработка, если решим с шефом, что она нужна, останется для следующих релизов.

                          Ололо! А что же там скромного? Есть стек трейс, есть девайс, что еще надо?

                          Цитата Homez @
                          Добавлю, что, честно, про краш-репорты я вообще пока ничего и не думал, и вот только сегодня узнал, в первую очередь от тебя, Эмик Ферман, что на Android есть для этого сервисы. Но я уже почти закончил работу над первой версией программы, на будущей неделе ее бы уже пора выпускать. Поэтому такая серьезная доработка, если решим с шефом, что она нужна, останется для следующих релизов.

                          Так вот с гугл плей или той же флури креш репорты работают из коробки, тоесть сложности НОЛЬ. С другой стороны, если у клиента проблема, как ты узнаешь что случилось? Да ты багу просто не повторишь, если она случилась из за того, что клиент въехал в туннель и у него там связь упала :)

                          Опять же, как узнать что в твоей апе есть функционал, который не использует клиент? Как узнать что наиболее используемо?
                          Цитата Homez @
                          Ага, следуя тебе, по мере набора опыта мне будет все труднее и труднее ставить программы на устройство Android не с сервиса Google Play. У меня шеф не программист, не технарь, но ему не составляет проблемы поставить очередную версию программы, присланную ему мной по электронной почте.

                          Для того чтобы поставить апу не с маркета, надо знать, как минимум, где поставить галку в сеттингах ;)
                            Цитата Эмик Ферман @
                            А что мешает водиле стянуть софтину с телефона и отдать её другому водиле? Зачем второму платить?

                            Я в эти детали не вдавался. Очевидно, какая-то защита есть. Это к ребятам из Ижевска. Деньги за установку все равно в итоге идут им.

                            Цитата Эмик Ферман @
                            Для того чтобы поставить апу не с маркета, надо знать, как минимум, где поставить галку в сеттингах ;)

                            Ну на Google Play же мы будем выкладывать. Кто все любит брать там - пжалста. Но что же, незаконно выложить версию программы на сайте? Кто знает, где какие галки надо ставить в сеттингах, тот и поставит. А остальные смогут воспользоваться Google Play.
                              Цитата Homez @
                              Я в эти детали не вдавался. Очевидно, какая-то защита есть. Это к ребятам из Ижевска. Деньги за установку все равно в итоге идут им.

                              Защиты нет - инфа 146%.
                              Цитата Homez @
                              Ну на Google Play же мы будем выкладывать. Кто все любит брать там - пжалста. Но что же, незаконно выложить версию программы на сайте? Кто знает, где какие галки надо ставить в сеттингах, тот и поставит. А остальные смогут воспользоваться Google Play.

                              Ага, только НИКАКИХ репортов с того софта вы не получите. А репорты - это самое дорогое что может быть.
                                Цитата Эмик Ферман @
                                Защиты нет - инфа 146%

                                Ты знаешь эту программу?

                                Цитата Эмик Ферман @
                                Ага, только НИКАКИХ репортов с того софта вы не получите. А репорты - это самое дорогое что может быть.

                                Откуда такая уверенность?
                                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                0 пользователей:


                                Рейтинг@Mail.ru
                                [ Script execution time: 0,0480 ]   [ 15 queries used ]   [ Generated: 3.05.24, 19:56 GMT ]