Różnica między katalogami / res i / asset

266

Wiem, że pliki w reskatalogu są dostępne, R.classpodczas gdy zasoby zachowują się jak system plików, ale ogólnie chciałbym wiedzieć, kiedy najlepiej używać jednego i drugiego.
Czy ktoś może mi pomóc w poznaniu prawdziwych różnic między zasobami a zasobami?

Cris
źródło

Odpowiedzi:

284

Dzięki zasobom jest wbudowana obsługa zapewniania alternatyw dla różnych języków, wersji systemu operacyjnego, orientacji ekranu itp., Jak opisano tutaj . Żadna z tych opcji nie jest dostępna z aktywami. Ponadto wiele części interfejsu API obsługuje użycie identyfikatorów zasobów. Wreszcie, nazwy zasobów są zamieniane na stałe nazwy pól, które są sprawdzane podczas kompilacji, więc jest mniej szansy na rozbieżności między kodem a samymi zasobami. Nic z tego nie dotyczy aktywów.

Dlaczego więc w ogóle ma folder zasobów? Jeśli chcesz obliczyć zasób, którego chcesz użyć w czasie wykonywania, jest to dość łatwe. W przypadku zasobów musisz zadeklarować listę wszystkich identyfikatorów zasobów, których można użyć, i obliczyć indeks na liście. (Jest to dość niewygodne i stwarza możliwości wystąpienia błędu, jeśli zestaw zasobów zmienia się w cyklu programowania). (EDYCJA: można pobrać identyfikator zasobu według nazwy getIdentifier, ale traci to zalety sprawdzania czasu kompilacji.) Zasoby mogą być również zorganizowane w hierarchię folderów, która nie jest obsługiwana przez zasoby. To inny sposób zarządzania danymi. Chociaż zasoby pokrywają większość przypadków, zasoby są sporadycznie wykorzystywane.

Jeszcze jedna różnica: zasoby zdefiniowane w projekcie bibliotecznym są automatycznie importowane do projektów aplikacji zależnych od biblioteki. W przypadku zasobów tak się nie dzieje; pliki zasobów muszą znajdować się w katalogu zasobów projektów aplikacji. [EDYCJA: W przypadku nowego systemu kompilacji opartego na systemie Gradle (używanego z Android Studio) nie jest to już prawdą. Katalogi zasobów dla projektów bibliotecznych są spakowane do plików .aar, więc zasoby zdefiniowane w projektach bibliotecznych są scalane w projekty aplikacji (więc nie muszą znajdować się w katalogu aplikacji, /assetsjeśli znajdują się w bibliotece, do której się odwołuje).]

EDYCJA: Jeszcze jedna różnica pojawia się, jeśli chcesz spakować niestandardową czcionkę z aplikacją. Istnieją wywołania API do utworzenia Typefacepliku czcionki zapisanego w systemie plików lub w assets/katalogu aplikacji . Ale nie ma interfejsu API do utworzenia Typefacez pliku czcionek przechowywanego w res/katalogu (lub z pliku InputStream, który pozwoliłby na użycie res/katalogu). [ UWAGA: W Androidzie O (teraz dostępnym w wersji alfa) będziesz mógł dołączać niestandardowe czcionki jako zasoby. Zobacz opis tej od dawna spóźnionej funkcji. Jednak dopóki minimalny poziom interfejsu API wynosi 25 lub mniej, będziesz musiał trzymać niestandardowe czcionki jako zasoby, a nie zasoby.]

Ted Hopp
źródło
1
resoznacza zasoby, to co assetsoznacza?
Vivek Warde,
40
@vwvwvwvwvwvwvwvwvw - Um ... to nic nie znaczy; oznacza po prostu „aktywa” (jak w liczbie mnogiej w angielskim słowie „ zasób : rzecz użyteczna lub wartościowa” ).
Ted Hopp
1
Czy można zapisywać do plików w raw/katalogu?
Książę
6
@Prince - Nie. Wszystko w /reskatalogach i / / resources jest tylko do odczytu, ponieważ są one spakowane w pliku apk.
Ted Hopp
czy możemy umieścić plik APK w folderze zasobów, a kiedy użytkownik kliknie ten interfejs, zainstaluj ten plik APK?
Vivek Mishra,
63

Oba są dość podobne. Prawdziwa główna różnica między nimi polega na tym, że w reskatalogu każdy plik ma wstępnie skompilowaną wersję, do ID której można łatwo uzyskać dostęp R.id.[res id]. Jest to przydatne, aby szybko i łatwo uzyskać dostęp do obrazów, dźwięków, ikon ...

assetsKatalog jest bardziej podobny do systemu plików i zapewnia większą swobodę, aby umieścić dowolny plik, który chcesz tam. Następnie możesz uzyskać dostęp do każdego pliku w tym systemie, tak jak podczas uzyskiwania dostępu do dowolnego pliku w dowolnym systemie plików za pośrednictwem Java. Ten katalog jest przydatny do takich rzeczy, jak szczegóły gry, słowniki, itp. Mam nadzieję, że to pomaga.

DRiFTy
źródło
5
Jeśli chcemy dodać elementy zewnętrzne w naszej aplikacji, umieszczamy je w folderze zasobów.
Tushar Pandey
1
@TusharPandey Teraz nie musimy umieszczać czcionek w Assetsfolderze, system Android zawiera teraz fontskatalog i możemy tam umieścić niestandardowy plik czcionek lub możemy pobrać dla nas studio Android.
CopsOnRoad
@Jack, to dla Oreo.
Tushar Pandey,
1
@TusharPandey Został dodany w Oreo, ale został przeniesiony z powrotem do Biblioteki obsługi systemu Android z powrotem do poziomu API 16.
CopsOnRoad
36

Wiem, że to jest stare, ale dla jasności, każde z nich znajduje się w oficjalnej dokumentacji Androida:

z http://developer.android.com/tools/projects/index.html

assets/

To jest puste. Możesz go użyć do przechowywania surowych plików zasobów. Pliki, które zapisujesz tutaj, są kompilowane w istniejącym pliku .apk, a oryginalna nazwa pliku zostaje zachowana. Możesz poruszać się po tym katalogu w taki sam sposób, jak w typowym systemie plików za pomocą identyfikatorów URI i odczytywać pliki jako strumień bajtów za pomocą AssetManager. Na przykład jest to dobra lokalizacja dla tekstur i danych gry.

res/raw/

Dla dowolnych plików surowych zasobów. Zapisywanie plików zasobów tutaj zamiast w katalogu asset / różni się tylko sposobem dostępu do nich. Pliki te są przetwarzane przez aapt i należy się do nich odwoływać z aplikacji przy użyciu identyfikatora zasobu w klasie R. Na przykład jest to dobre miejsce dla multimediów, takich jak pliki MP3 lub Ogg.

AntonyMC
źródło
4
Myślę, że to faktycznie myli problem - zarówno tekstury, jak i pliki ogg są dużymi globami danych, które podajesz do interfejsu API użytkownika (openGL / MediaPlayer) ... dlaczego mieliby tutaj dyskryminować?
9

Oto kilka kluczowych punktów:

  1. Pliki Raw muszą mieć nazwy, które są prawidłowymi identyfikatorami Java, podczas gdy pliki w Zasobach nie mają ograniczeń lokalizacji i nazw. Innymi słowy, można je pogrupować w dowolne katalogi, jakie chcemy
  2. Pliki RAW Łatwo jest odwoływać się z Javy, jak również z XML (tzn. Można odwoływać plik w formacie RAW z manifestu lub innego pliku XML).
  3. Zapisywanie plików zasobów tutaj zamiast w katalogu Zasoby / różni się tylko sposobem dostępu do nich, zgodnie z dokumentacją tutaj http://developer.android.com/tools/projects/index.html .
  4. Zasoby zdefiniowane w projekcie bibliotecznym są automatycznie importowane do projektów aplikacji zależnych od biblioteki. W przypadku zasobów tak się nie dzieje; pliki zasobów muszą znajdować się w katalogu zasobów projektów aplikacji
  5. Katalog zasobów przypomina system plików, który zapewnia większą swobodę w umieszczaniu w nim dowolnych plików. Następnie możesz uzyskać dostęp do każdego pliku w tym systemie, tak jak podczas uzyskiwania dostępu do dowolnego pliku w dowolnym systemie plików za pośrednictwem Java. jak pliki danych gry, czcionki, tekstury itp.
  6. W przeciwieństwie do zasobów, zasoby można uporządkować w podfoldery w katalogu zasobów. Jednak jedyne, co można zrobić z zasobem, to uzyskanie strumienia wejściowego. W związku z tym przechowywanie ciągów lub map bitowych w zasobach nie ma większego sensu, ale można przechowywać dane w niestandardowym formacie, takie jak słowniki korekty wejściowej lub mapy gier.
  7. Raw może dać ci kontrolę czasu kompilacji, generując plik R.java. Jeśli jednak chcesz skopiować bazę danych do prywatnego katalogu, możesz użyć zasobów stworzonych do przesyłania strumieniowego.

Wniosek

  1. Android API zawiera bardzo wygodną platformę zasobów, która jest również zoptymalizowana pod kątem typowych przypadków użycia dla różnych aplikacji mobilnych. Powinieneś opanować zasoby i starać się ich używać w miarę możliwości.
  2. Jeśli jednak potrzebujesz większej elastyczności w specjalnym przypadku, Zasoby są dostępne, aby zapewnić interfejs API niższego poziomu, który pozwala organizować i przetwarzać zasoby z większą swobodą.
Shubhang Malviya
źródło
Zgodnie z przyjętą odpowiedzią punkt 4 nie jest już prawdziwy, w przypadku projektów wykorzystujących system kompilacji Gradle; zasoby z bibliotek są pakowane w kolekcję zasobów projektu aplikacji.
Venryx
4

Jeśli chcesz je odesłać gdzieś w kodzie Java, umieść swoje pliki w katalogu „res”.

Wszystkie pliki w folderze res zostaną zindeksowane w pliku R, co znacznie przyspiesza (i znacznie ułatwia!) Ich ładowanie.

L.Butz
źródło
6
Możesz również uzyskać dostęp do plików w zasobach z Javy
Heiko Rupp
2
Tak, ale nie są indeksowane -> Wolniej, co jest prawdziwym problemem w rozwoju aplikacji mobilnych.
L.Butz
więc czym różni się między res / raw a zasobem? Czy res / raw również będą indeksowane?
odlotowy
Sprawdź post z @TedHopp - przynosi odpowiedź bardzo jasno.
L.Butz,
1

Używaj zasobów takich jak system plików, aby zrzucać wszelkiego rodzaju pliki. I użyj res do przechowywania tego, do czego jest przeznaczony, układów, obrazów, wartości.

Bajji
źródło
0

Ted Hopp odpowiedział na to całkiem ładnie. Używam res / raw do moich plików tekstur i modułów cieniujących OpenGL. Myślałem o przeniesieniu ich do katalogu zasobów, aby zapewnić hierarchiczną organizację.

Ten wątek przekonał mnie, żebym tego nie robił. Po pierwsze, ponieważ lubię używać unikalnego identyfikatora zasobu. Po drugie, ponieważ bardzo łatwo jest użyć InputStream / openRawResource lub BitmapFactory do odczytu w pliku. Po trzecie, ponieważ bardzo przydatne jest korzystanie z przenośnej biblioteki.

dturvene
źródło
1
Punkt 2 obsługi InputStreams i BitmapFactory dotyczy zarówno zasobów, jak i zasobów (patrz tutaj: stackoverflow.com/a/8501428/2441655 ). Punkt 3 nie ma już zastosowania. (patrz zaakceptowana odpowiedź)
Venryx
-5

Zasoby umożliwiają dołączanie do aplikacji dowolnych plików, takich jak tekst, xml, czcionki, muzyka i wideo. Jeśli spróbujesz dołączyć te pliki jako „zasoby”, Android przetworzy je na swój system zasobów i nie będziesz w stanie uzyskać surowych danych. Jeśli chcesz uzyskać dostęp do danych nietkniętych, Zasoby są jednym ze sposobów, aby to zrobić.

KCRaju
źródło
5
To jest niepoprawne. Jeśli wstawisz dane res/raw, możesz uzyskać surowe dane za pomocą openRawResource(resourceName).
Ted Hopp,
Mam bibliotekę tekstur i plików cieniujących OpenGles w bibliotece. I MUSI używać res / raw do ich przechowywania. Do ich odczytu używam InputStream i BitmapFactory. Dodam to jako niezależny komentarz.
dturvene
Wygląda na skopiowane z dokumentów Microsoft Xamarin. Podaj źródło podczas kopiowania tekstu. docs.microsoft.com/en-us/xamarin/android/app-fundamentals/…
Sjoerd Pottuit