sql >> Databáze >  >> RDS >> SQLite

IntentService zamrzá uživatelské rozhraní mé aplikace

Jste si naprosto jisti, že jde o IntentService? to je hlavní příčina zamrznutí uživatelského rozhraní? Služby Intent jsou speciálně navrženy tak, aby se spouštěly v pracovních vláknech za účelem snížení zátěže zpracování z hlavního (UI) vlákna, přičemž jedním z hlavních důvodů je pomoci zabránit Uživatelské rozhraní zamrzne.

Možná zkuste začít s laděním na úrovni uživatelského rozhraní. Konkrétně to, co poskytuje ResultReceiver na IntentService když jej spustíte, a co uděláte v onReceiveResult metoda zpětného volání v této instanci příjemce?

Kromě toho pro činnost, při které dochází k zamrzání, zkontrolujte, jaké operace provádíte. Načítání velkého množství dat z databáze v hlavním vláknu (tj. bez použití Loader nebo něco podobného k přesunutí zpracování na pracovní vlákno) je běžnou příčinou zamrznutí uživatelského rozhraní, alespoň podle mých dosavadních zkušeností.

Aktualizovat

Myslím, že jsem přišel na to, v čem je problém. Existují dva hlavní problémy, oba pramení z toho, jak používáte Volley. Když přidáte požadavek do fronty Volley, bude proveden asynchronně. To znamená, že queue metoda se okamžitě vrátí. Ve vašem kódu služby záměru to znamená, že služba okamžitě sdělí ResultReceiver že dokončilo zpracování, když vlastně jediné, co udělal, je zařadit požadavek do fronty. Všech pět intent služeb to udělá, což znamená, že MainActivity bude zadáno velmi rychle. Toto je první problém.

Druhý problém vysvětluje zamrznutí, ke kterému dochází. Přestože Volley provádí požadavky na pracovních vláknech, vrací analyzované odpovědi na požadavky v hlavním vlákně – viz dokumentace zde. To znamená, že veškeré zpracování odpovědí, které provádíte ve službě intent (vkládání dat do databáze atd.), se ve skutečnosti děje v hlavním (UI) vláknu. To vysvětluje zamrznutí.

Zde pravděpodobně budete chtít přepnout na používání Volley's RequestFuture namísto. To v podstatě změní asynchronní požadavek na synchronní tím, že vám umožní blokovat, dokud požadavek neskončí. Chcete-li to provést, vytvořte budoucnost odpovídajícího typu (JSONObject ve vašem případě) a nastavte jej jako posluchače i jako posluchače chyb pro požadavek. Poté zařaďte požadavek do fronty jako nyní a ihned poté zavolejte get metoda do budoucna. Tato metoda se zablokuje, dokud nebude zpracování odpovědi dokončeno. Je v pořádku to udělat ve službě intent, protože běží na pracovním vláknu, ne na vláknu uživatelského rozhraní.

Pokud požadavek uspěje, vrátíte data a můžete spustit veškerou logiku, která je aktuálně ve vašem Response.Listener implementace. Pokud dojde k chybě (tj. požadavek z nějakého důvodu selže), budoucí požadavek vyvolá výjimku, kterou můžete zpracovat a podniknout příslušné kroky.

Použití futures požadavků je docela odlišný přístup k používání posluchačů a možná budete muset trochu změnit svůj kód, aby to fungovalo, ale mělo by to vyřešit problémy, které vidíte.

Doufám, že to pomůže, a upřímně se omlouvám, že jsem chybu nezachytil dříve.



  1. Jak filtrovat výsledky dotazů v PostgreSQL

  2. Jak vložit do stejné tabulky v MySQL?

  3. SQL Server:ekvivalent kaskády drop tabulky?

  4. Jak odinstalujete MySQL z Mac OS X?