2010-08-07 5 views
20

Sto sperimentando l'utilizzo di una WebView per visualizzare il contenuto Flash all'interno della mia attività. Tutto funziona perfettamente, ma quando l'utente preme la home key per mettere l'attività in sottofondo, il contenuto Flash continua a funzionare (il suono continua a suonare, ecc.)Come faccio a sospendere il contenuto Flash in una WebView Android quando la mia attività non è visibile?

Ho notato che sia il browser Android di serie che Dolphin Browser sembra evitare questo problema e sospendere correttamente il contenuto Flash quando l'attività di navigazione viene messa in background.

Idealmente vorrei una soluzione che uccide il WebView completamente se l'attività sta finendo, ma le pause altrimenti (in pratica copiando il comportamento predefinito del browser)

Ecco un semplice test ho messo insieme che carica un gioco su Kongregate che ha una musica di sottofondo:

public class BrowserTest extends Activity { 
    private WebView mWebView; 

     @Override 
     protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 

      mWebView = new WebView(this); 
      mWebView.getSettings().setJavaScriptEnabled(true); 
      mWebView.getSettings().setPluginsEnabled(true); 

      mWebView.loadUrl("http://m.kongregate.com/games/Jiggmin/the-game-of-disorientation-mobile"); 
      setContentView(mWebView); 
     } 

     @Override 
     protected void onPause(){ 
      super.onPause(); 

      mWebView.pauseTimers(); 
      if(isFinishing()){ 
       mWebView.loadUrl("about:blank"); 
       setContentView(new FrameLayout(this)); 
      } 
     } 

     @Override 
     protected void onResume(){ 
      super.onResume(); 
      mWebView.resumeTimers(); 
     } 
    } 

ho preso uno sguardo al più tardi fonte per lo stock del browser, e sembra di fare qualcosa di simile (chiamando pauseTimers/resumeTimers), anche se temo il codice che ho ho visto che non è aggiornato, perché chiama funzioni che non sembrano esistere e.

Ho verificato che la chiamata a pauseTimers sta funzionando testando con un semplice setInterval di JavaScript che aggiorna un contatore. C'è qualcos'altro ovvio che dovrei provare riguardo alla gestione di Window o View?

La documentazione per il Flash player cellulare dice:

Flash Player sarà anche mettere in pausa automaticamente la riproduzione SWF non è in vista o l'applicazione in primo piano, per esempio quando si riceve una chiamata o di allarme si spegne, a ridurre l'utilizzo della CPU, l'utilizzo della batteria e l'utilizzo della memoria.

Questo sembra funzionare perfettamente sia nel browser di serie che in Dolphin Browser, ma non nella mia app. Qualsiasi idea/soluzione sarebbe molto apprezzata!

Aggiornamento: Ecco la funzione che abbiamo aggiunto alla nostra attività per farlo funzionare. Noi lo chiamiamo con "onPause" nella funzione onPause della propria attività e "onResume" nella funzione onResume della propria attività:

private void callHiddenWebViewMethod(String name){ 
    if(mWebView != null){ 
     try { 
      Method method = WebView.class.getMethod(name); 
      method.invoke(mWebView); 
     } catch (NoSuchMethodException e) { 
      Log.error("No such method: " + name, e); 
     } catch (IllegalAccessException e) { 
      Log.error("Illegal Access: " + name, e); 
     } catch (InvocationTargetException e) { 
      Log.error("Invocation Target Exception: " + name, e); 
     } 
    } 
} 
+0

Come si chiama questo? Hai uno snippet di codice sull'utilizzo? –

+1

Non è necessario utilizzare la reflection dal livello API 11. È sufficiente chiamare i metodi public onPause() e onResume() di WebView. – cprcrack

risposta

8

Non vedo dove si vede che BrowserActivity o qualcosa sta chiamando pauseTimers(). Vedo dove onPause() per BrowserActivity indirizza a onPause() di WebView. Tuttavia, onPause() di WebView ha l'annotazione @hide e quindi non fa parte dell'SDK. A braccio, sembrerebbe come onPause() è ciò che si vuole, dato il commento:

chiamata questo per mettere in pausa alcun extra elaborazione associata con questa visione e il suo associato DOM/plugins/javascript/etc . Per esempio , se la vista è presa fuori schermo, questo potrebbe essere chiamato a ridurre il traffico CPU e/o rete inutile. Quando la vista è nuovamente "attiva", chiama onResume().

Prendere nota del riferimento a "plug-in", che non è menzionato nella documentazione pauseTimers().

Vorrei provare a utilizzare il reflection per vedere se onPause() (e successivamente onResume(), quando si desidera che il materiale venga riavviato) fa quello che ti serve. In tal caso, pubblica un problema a b.android.com a riguardo, chiedendo loro di aggiungere questi metodi (o equivalenti) all'SDK. Il tuo requisito sembra essere comune e una soluzione che superi l'SDK non è una buona soluzione.

+1

La chiamata a pauseTimers è all'interno del metodo pauseWebViewTimers dell'attività del browser. Non avevo familiarità con l'annotazione @ hide, ecco perché ho pensato che forse stavo navigando su una sorta di codice vecchio/diverso. Penso che il tuo suggerimento di tentare di chiamare onPause/onResume usando il reflection sia fantastico, ti farò sapere come funziona, grazie! – BenV

+0

Funziona perfettamente, grazie mille per avermi fatto conoscere l'annotazione @hide, non mi ero nemmeno reso conto che avrei potuto ottenere quei metodi usando il reflection. Pubblicherò un problema a b.android.com come suggerito! – BenV

+0

@ BenV: felice di sentirlo ha funzionato! Se ci pensi, metti un commento qui con un link al problema una volta che lo hai archiviato. Mi piacerebbe tenere d'occhio questo. – CommonsWare

7
@Override 
protected void onPause() { 
    super.onPause(); 
    this.callHiddenWebViewMethod("onPause"); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    this.callHiddenWebViewMethod("onResume"); 
} 

Questo è come lo chiami nella tua attività ... Funziona come un fascino.