Pakowanie plików zasobów systemu Android w dystrybuowalnym pliku Jar

Pracuję nad kodem na Androida wielokrotnego użytku, który chciałbym rozpowszechnić wśród innych programistów do wykorzystania w ich własnych aplikacjach. Kod ma pewne zależności od zasobów (layouts, XML & png drawables), które chciałbym móc włączyć i odwoływać się w ramach jednego pakietu (plik Jar).

Czy jest to możliwe, a jeśli tak, to jaka jest najlepsza metoda na to?

Author: erdemlal, 2010-01-03

9 answers

Nie mam dla Ciebie żadnych optymistycznych wiadomości. Ogólnie rzecz biorąc, nie można dystrybuować własnego pakietu tak łatwo, jak można się tego spodziewać. Głównym problemem jest automatycznie wygenerowany plik R. Pewnie robisz jakieś odniesienia do niego - masz swoje układy i rysunki. Użytkownik biblioteki będzie miał swój własny plik r-zawierający identyfikatory jego zasobów, a nie tych, które udostępnia biblioteka.

W przypadku zasobĂłw drawable moĹźna byĹ ' o je odczytaÄ ‡ w klasyczny sposĂłb, bez pliku R. Ale o ile wiem, jesteś nie można nadmuchać układów z zewnętrznych plików xml.

Więc brzydki hack tutaj będzie dystrybuować bibliotekę wraz ze wszystkimi zasobami, które użytkownik będzie musiał skopiować do swojego folderu "res". Szczerze mówiąc, nie ma dobrego rozwiązania Twojego problemu... przepraszam. Pozdrawiam!

 26
Author: Ramps,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-03 14:10:23

Ponieważ Android automatycznie tworzy klasę R z plikami zasobów w folderze /res, użycie klasy R jako final static jest niemożliwe.

Znalazłem dobre rozwiązanie, aby użyć pliku jar z plikami res. Oto jak to zrobiłem:

  1. W kodzie źródłowym, który zostanie wyeksportowany do pliku jar, nie używaj R zmienna, ponieważ zostanie zastąpiona końcowym adresem pamięci statycznej w czasie kompilacji. Zamiast używać R, stworzyłem własną metoda poniżej:

    public static int getResourceIdByName(String packageName, String className, String name) {
        Class r = null;
        int id = 0;
        try {
            r = Class.forName(packageName + ".R");
    
            Class[] classes = r.getClasses();
            Class desireClass = null;
    
            for (int i = 0; i < classes.length; i++) {
                if (classes[i].getName().split("\\$")[1].equals(className)) {
                    desireClass = classes[i];
    
                    break;
                }
            }
    
            if (desireClass != null) {
                id = desireClass.getField(name).getInt(desireClass);
            }
    
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
    
        return id;
    }
    

    Na przykład, jeśli masz układ o nazwie main.xml, możesz go uzyskać wywołując metodę:

    int id = getResourceIdByName(context.getPackageName(), "layout", "main");
    

    Jeśli masz łańcuch znaków, którego id to "text1", możesz go uzyskać przez wywołanie metody

    int id = getResourceIdByName(context.getPackageName(), "string", "text1");
    

    Ta metoda daje identyfikator zasobu w czasie wykonywania. Używa API reflection, aby uzyskać status R w czasie wykonywania.

    Używając tej metody można uniknąć użycia zmiennej R.

  2. Skopiuj pliki res do celu projekt.

  3. Buduj.

 54
Author: J.J. Kim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-11-13 06:01:42

Layouty:

Twardy kod w źródle Javy


Xml & png:

Skopiuj XML & png do folderu src projektu i pakiet do jar, na przykład

Skopiuj plik. png do src / com / example / test

Załaduj go jako następujące kody Javy:

    InputStream is = YourClassName.class.getClassLoader().getResourceAsStream("com/example/test/a.png");
    if ( null != is )
    {
          Bitmap bmp = BitmapFactory.decodeStream(is);
 19
Author: user558185,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-30 10:56:00

Właśnie odkryłem, że narzędzie aapt W Android SDK umożliwia następującą opcję:

   --non-constant-id
       Make the resources ID non constant. This is required to make an R java class
       that does not contain the final value but is used to make reusable compiled
       libraries that need to access resources.
To brzmi obiecująco, chociaż nie próbowałem tego, więc nie mam pojęcia, czy to działa. Podejrzewam, że ma to na celu obejście problemu poruszonego przez powyższy post @ J. J. Kima.
 4
Author: scorpiodawg,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-04-27 21:57:58

Możesz dynamicznie uzyskać identyfikator zasobu za pomocą metody android.

int preferences = context.getResources().getIdentifier("preferences", "xml", context.getPackageName());

Później twoje zasoby muszą zostać włączone (skopiowane) do twojego nowego projektu.

 3
Author: Konrad Nowicki,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-09-27 11:51:27

Używałem user558185 rozwiązanie, ale tutaj jest prostszy sposób. Jeśli zasoby jest w projekcie biblioteki (dla wtyczki Cordova na przykład), można uzyskać zasoby z context.getResources().getIdentifier(name, className, context.getPackageName());

Dzieje się tak, gdy plik r zasobów projektu bibliotecznego nie jest poprawnie wygenerowany, a Nazwa pakietu R nie jest zgodna z wymaganą przez projekt biblioteki nazwą pakietu.

Użycie jest takie samo jak user558185 answer, ale używa natywnej metody Android.

 1
Author: Hugo Gresse,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:25:02

Witam myślę, że to spóźniona odpowiedź ale i tak tylko co mam poinformować o AAR

Android ARchive - ten plik może przechowywać pliki res I manifest, dzięki czemu drugi programista może po prostu zaimportować aar do swojego projektu i skompilować swój kod.

W ten sposób możemy dostać Manifest merge errors, the fix for it to use replace property in your manifest and this should be checked before distribution.

 1
Author: Vimalanathan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-10 14:46:34

Możesz użyć abstrakcji, aby uzyskać wartości R z klasy implementującej (użytkownik).

protected abstract void getMyLayoutTextBox(int myLayoutTextBox);

Następnie użytkownik musi rozszerzyć klasę (która rozszerza Activity) i zaimplementować tę metodę. W twojej klasie, po prostu wywołujesz getMyLayoutTextBox() i będziesz miał poprawną wartość R dostarczoną przez użytkownika po zaimplementowaniu twojego dystrybuowalnego jar.

Możesz przeczytać więcej o abstrakcji tutaj .

 0
Author: CrackerJack9,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-19 14:12:21

Jeśli używasz Eclipse, przejdź do projektu "Properties->Java Build Path". W zakładce "Source" Dodaj folder res, który chcesz spakować (np.

Doda następujący wiersz do pliku .classpath

Po zakończeniu budowania nowy plik jar będzie zawierał pliki w folderze res/raw/. Możesz uzyskać do nich dostęp jako zasugerował (a) user558185.

 0
Author: june232,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:01:40