Como faço para pausar o conteúdo do flash em um Android WebView quando minha atividade não é visível?
-
26-09-2019 - |
Pergunta
Estou experimentando o uso de um WebView para exibir conteúdo flash dentro da minha atividade. Tudo está funcionando muito bem, mas quando o usuário atinge a chave da casa para colocar a atividade em segundo plano, o conteúdo flash continua funcionando (o som continua jogando etc.)
Percebi que o navegador Android e o navegador de golfinhos parecem evitar esse problema e pausar adequadamente o conteúdo do flash quando a atividade de navegação é colocada em segundo plano.
Idealmente, eu gostaria de uma solução que mata completamente o WebView se a atividade estiver terminando, mas faz uma pausa de outra forma (basicamente copiando o comportamento padrão do navegador)
Aqui está um teste simples que montei que carrega um jogo no KonGregate, que tem alguma música de fundo:
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();
}
}
Eu dei uma olhada na fonte mais recente do navegador de ações e parece estar fazendo algo semelhante (chamando Pausetimers/Rumetimers), embora eu tenha medo que o código que tenho olhado está desatualizado, porque está chamando funções que não Parece mais existir.
Eu verifiquei se a chamada para Pausetimers está funcionando testando com um JavaScript SetInterval simples que atualiza um contador. Existe algo mais óbvio que eu deveria estar tentando em relação à janela ou visualizar o gerenciamento?
A documentação para o flash player móvel diz:
O Flash Player também pausa automaticamente a reprodução do SWF que não está à vista ou do aplicativo em primeiro plano, por exemplo, quando uma chamada é recebida ou o alarme dispara, para reduzir a utilização da CPU, o uso da bateria e o uso da memória.
Isso parece estar funcionando perfeitamente no navegador de ações e no navegador de golfinhos, mas não no meu aplicativo. Quaisquer idéias/soluções seriam muito apreciadas!
Atualizar: Aqui está a função que acabamos aumentando nossa atividade para fazer isso funcionar. Chamamos isso com "OnPause" na função onPause da atividade e "OnResume" na função OnResume da atividade:
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);
}
}
}
Solução
Eu não vejo onde você vê isso BrowserActivity
ou qualquer coisa está ligando pauseTimers()
. Eu vejo onde onPause()
por BrowserActivity
eventualmente rotas para onPause()
do WebView
. No entanto, onPause()
do WebView
tem o @hide
Anotação e, portanto, não fazem parte do SDK. Fora do manguito, parece que OnPause () é o que você deseja, dado o comentário:
Chame isso para pausar qualquer processamento extra associado a essa visualização e seu DOM/plug -ins associado/javascript/etc. Por exemplo, se a visualização for retirada da tela, isso poderá ser chamado para reduzir a CPU desnecessária e/ou o tráfego de rede. Quando a visualização estiver novamente "ativa", ligue para o OnResume ().
Observe a referência a "plugins", que não é mencionado no pauseTimers()
documentação.
Eu tentaria usar a reflexão para ver se onPause()
(e depois onResume()
, quando você quer que as coisas sejam iniciadas de novo) faz o que você precisa. Se isso acontecer, poste um problema para b.android.com Sobre isso, pedindo a eles para adicionar esses métodos (ou equivalentes) ao SDK. Seu requisito parece que será comum, e uma solução que passa pelo SDK não é uma boa solução.
Outras dicas
@Override
protected void onPause() {
super.onPause();
this.callHiddenWebViewMethod("onPause");
}
@Override
protected void onResume() {
super.onResume();
this.callHiddenWebViewMethod("onResume");
}
É assim que você chama isso em sua atividade ... funciona como um charme.