8

Mam dziwny problem.Która część Androida jest odpowiedzialna za wybór prawidłowego profilu zasobów?

Zanim wpadniesz na pomysł, by rzucić się na mnie, pracuję nad niestandardową galaretką. W związku z tym "zwykłe ładne podejście" może nie działać tutaj i trzeba wykonać brudne obejścia.

Mam APK, który zawiera następujące aktywa:

layout 
layout-mdpi 
layout-land 
layout-large-mdpi 
layout-large-land-mdpi 
layout-large-hdpi 
layout-large-xhdpi 

i niektóre inne kodu metryki wrócił to:

D/AppDemo(2091): measured width: 1920 PE width: 1920 scaleFactor = 1.0 
D/AppDemo(2091): [ANDROID] measured width: 1920 measured height: 1080 
D/AppDemo(2091): [ANDROID] scale for resources: 2.0 xdpi: 320.0 ydpi: 320.0 
D/AppDemo(2091): [ANDROID] screen density: xhdpi 
D/AppDemo(2091): [ANDROID] screen size: large 
D/AppDemo(2091): [ANDROID] using layout: layout-mdpi 

Więc patrząc na metryki, dlaczego nie jest istotą layout-large-xhdpi załadowany?

Proszę, powiedz mi, gdzie mogę to sprawdzić. Naprawdę muszę znaleźć sposób zmuszenia układu/zasobu/AssetManager do załadowania określonego układu.

Zdaję sobie sprawę, że najpopularniejszym komentarzem w tym temacie jest "nie potrzebujesz/dlaczego masz layout-xhdpi, powinieneś mieć drawable-xhdpi i layout-large", ale musisz ze mną.

Chciałbym bardzo docenić nawet małe wskazówki, gdzie patrzeć i na co zwracać uwagę. Do tej pory, AssetManager wydaje się być miejscem do rozpoczęcia kopania/rejestrowania.

Kiedy pomijam layout-mdpi, aplikacja zawiesza się na mnie, z brakującymi zasobami. Błąd wydaje się, że mimo że kod zwraca xhdpi, zakłada on, że gdzie indziej jest mdpi. Muszę to znaleźć i naprawić, aby moje aplikacje wyglądały tak dobrze, jak na ICS :)

Rozumiem, który układ jest ładowany w prosty sposób - wszystkie układy główne mają element android:tag, a kiedy setContentView(R.layout.main_layout) Chwytam znacznik na głównym elemencie i wiem, który folder został załadowany. Oprócz wizualnej informacji zwrotnej, będzie to musiało ostatecznie pasować do konfiguracji mojego urządzenia.

Z góry dziękuję.

+2

Chociaż nie łowisz za * nie potrzebujesz * odpowiedzi, uważam, że przybliżone wytłumaczenie twojego ostatecznego celu może pomóc nam wymyślić sposoby uzyskania tego, czego potrzebujesz, bez przechodzenia trudnej trasy. – Phil

+0

@Phil: Ok, problemem jest to, że z powodu rozbieżności gdzieś, wszystkie aplikacje pokazują tylko lewy górny kwartał na całym ekranie. Zamiast być mniejszym (jeśli skalowanie działało poprawnie) są znacznie większe. W każdym razie zostałem przeniesiony z tego, więc jest koniec tego. – Shark

Odpowiedz

3

Interesujący problem. Spojrzałem, ale wszystko idzie trochę w dół króliczej dziury.Brak odpowiedzi jako takiej, ale może moja analiza ustawi Cię we właściwym kierunku.

Spojrzałem na to, co stało się z setContentView. Oczywiście w tym momencie mówimy w kategoriach referencji układu graficznego gęstości (np. R.layout.main_layout), a później zostanie on przekształcony w odniesienie do określonego pliku w pliku APK. Kiedy i gdzie jest twoje pytanie.

Użyłem kwalifikatorów krajobrazu/portretu, aby zmienić jakość w środowisku wykonawczym, a do debuggera użyłem źródła Androida.

Oto przepływ, zaczynając w ten sposób.

  1. Resources.getLayout (int)
  2. Resources.loadXmlResourceParser (Int łańcuch)
  3. Resources.getValue (int TypedValue, logiczna)
  4. AssetManager.getResourceValue (int int TypedValue, logiczna)
  5. StringBlock.get (int)
  6. StringBlock.nativeGetString (int int)

Pracujmy wstecz.

Krok 6 to metoda natywna (C), która zwraca kwalifikowaną referencję, np. /res/layout-land/yourview.xml. Jego parametr jest jednak wskaźnikiem i zmienia się w zależności od tego, czy mamy krajobraz, czy portret.

Aby zobaczyć, skąd się to wzięło, musimy powrócić do kroku 4. Indeks jest polem w wariancie TypedValue, ale nie jest wstępnie ustawiony prawidłowo, gdy jest przekazywany do tej metody.

Krok 4 wywołuje inną natywną metodę, AssetManager.loadResourceValue(), która zmienia przekazaną wartość TypedValue i odpowiednio ustawia indeks.

Może możesz zacząć przeglądać literę C i zobaczyć, jak sobie radzisz.

+0

W szczególności możesz zacząć od [ResourceTypes.cpp] (http://code.metager.de/source/xref/android/4.1.1/frameworks/base/libs/androidfw/ResourceTypes.cpp#getResource), w którym można zobaczyć elementy konfiguracji związane z gęstością, ale szybko staje się zbyt skomplikowane, jak na mój gust. –

+0

ResourceTypes wygląda interesująco i wydaje się uderzać najbliżej domu, gratulacje za wygraną :) – Shark

+0

Dzięki. Możesz zauważyć, że istnieje metoda "isBetterThan", która porównuje kandydujące konfiguracje i prawdopodobnie zawiera logikę, której szukasz. Nie posunąłem się nawet do sprawdzenia, skąd pochodzą ci kandydaci. –

1

Nie wiem, czy mam rację, budujesz niestandardowy AndroidOS i chcesz, aby ten niestandardowy AndroidOS zawsze ładował ten sam zasób układu, w twoim przypadku - duży-xhdpi?

Jeśli tak, myślę, że dostosowałeś Configuration Class. Jeśli chcesz to szybko i brudno, możesz przesłonić int-Constants na linii 72 i poniżej.

Beton zmiana:

.... 
100  public static final int SCREENLAYOUT_SIZE_LARGE = 0x03; 
108  public static final int SCREENLAYOUT_SIZE_XLARGE = 0x04; 

do:

.... 
100  public static final int SCREENLAYOUT_SIZE_LARGE = 0x04; 
108  public static final int SCREENLAYOUT_SIZE_XLARGE = 0x04; 

inny sposób mogłoby być zastępują konstruktora i setToDefaults() - metoda, dlatego zawsze ładuje sam screenlayout.

Nie wypróbowałem tego, nie wiem, czy to działa, i nie mam żadnych wiarygodnych i/lub oficjalnych źródeł (wykluczony oficjalny kod Androida), ale mam nadzieję, że mógłbym ci pomóc.

+0

Proszę spojrzeć na zebrane dane. Te zostały zebrane przy użyciu klasy konfiguracji i pasują do mojego urządzenia. Rejestruje dobry ekran i odpowiednią gęstość, ale wybiera nieprawidłowy folder układu. Szukam szybkiej, brudnej poprawki do selektora stron. – Shark

4

Na rynku jest tyle urządzeń zhakowanych, takich jak Micromax Funbook, które mają duży rozmiar ekranu, ale używają zasobów mdpi, wierzą mi, że pracowałem z nimi i to było bardzo frustrujące.

Jak wspomniano aplikacja działa świetnie z każdym innym urządzeniem to po prostu nie działa z tym praticular tabletce może trzeba wdrożyć taki trochę rozwiązanie zamieszczone tutaj

http://android-developers.blogspot.in/2011/07/new-tools-for-managing-screen-sizes.html

Musisz przeczytać ostatni segment na ta strona z pewnością pomoże.

Podsumowując, sugerowane podejście polega na stworzeniu osobnego układu z inną nazwą przy użyciu różnych zasobów.

Kierujesz procesem zbierania zasobów, a nie systemem. co może być czasochłonne, ale na pewno pomoże.

public class MyActivity extends Activity { 
    @Override protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(); 

     Configuration config = getResources().getConfiguration(); 
     if (config.smallestScreenWidthDp >= 600) { 
      setContentView(R.layout.main_activity_tablet); 
     } else { 
      setContentView(R.layout.main_activity); 
     } 
    } 
} 
+0

Problem polega na tym, że moje foldery układu to layout-sw600dp i layout-sw1000dp, ale żaden z nich nie jest "fire". Coś jest pomieszane, ale problem jest poza moimi rękami, więc wydaje się. Ale widzę tu stosowane podejście, posiadanie zunifikowanego folderu układu i wybieranie właściwego ręcznie. Widzę. – Shark

+0

Ale te 'res/layout-xlarge/main_activity.xml # Dla tabletów sprzed 3.2" 'res/layout-sw600dp/main_activity.xml # Dla tabletów 3.2 i nowszych' po prostu nie działają i nie są wybierane. – Shark

Powiązane problemy