;(function() { window.createMeasureObserver = (measureName) => { var markPrefix = `_uol-measure-${measureName}-${new Date().getTime()}`; performance.mark(`${markPrefix}-start`); return { end: function() { performance.mark(`${markPrefix}-end`); performance.measure(`uol-measure-${measureName}`, `${markPrefix}-start`, `${markPrefix}-end`); performance.clearMarks(`${markPrefix}-start`); performance.clearMarks(`${markPrefix}-end`); } } }; /** * Gerenciador de eventos */ window.gevent = { stack: [], RUN_ONCE: true, on: function(name, callback, once) { this.stack.push([name, callback, !!once]); }, emit: function(name, args) { for (var i = this.stack.length, item; i--;) { item = this.stack[i]; if (item[0] === name) { item[1](args); if (item[2]) { this.stack.splice(i, 1); } } } } }; var runningSearch = false; var hadAnEvent = true; var elementsToWatch = window.elementsToWatch = new Map(); var innerHeight = window.innerHeight; // timestamp da última rodada do requestAnimationFrame // É usado para limitar a procura por elementos visíveis. var lastAnimationTS = 0; // verifica se elemento está no viewport do usuário var isElementInViewport = function(el) { var rect = el.getBoundingClientRect(); var clientHeight = window.innerHeight || document.documentElement.clientHeight; // renderizando antes, evitando troca de conteúdo visível no chartbeat-related-content if(el.className.includes('related-content-front')) return true; // garante que usa ao mínimo 280px de margem para fazer o lazyload var margin = clientHeight + Math.max(280, clientHeight * 0.2); // se a base do componente está acima da altura da tela do usuário, está oculto if(rect.bottom < 0 && rect.bottom > margin * -1) { return false; } // se o topo do elemento está abaixo da altura da tela do usuário, está oculto if(rect.top > margin) { return false; } // se a posição do topo é negativa, verifica se a altura dele ainda // compensa o que já foi scrollado if(rect.top < 0 && rect.height + rect.top < 0) { return false; } return true; }; var asynxNextFreeTime = () => { return new Promise((resolve) => { if(window.requestIdleCallback) { window.requestIdleCallback(resolve, { timeout: 5000, }); } else { window.requestAnimationFrame(resolve); } }); }; var asyncValidateIfElIsInViewPort = function(promise, el) { return promise.then(() => { if(el) { if(isElementInViewport(el) == true) { const cb = elementsToWatch.get(el); // remove da lista para não ser disparado novamente elementsToWatch.delete(el); cb(); } } }).then(asynxNextFreeTime); }; // inicia o fluxo de procura de elementos procurados var look = function() { if(window.requestIdleCallback) { window.requestIdleCallback(findByVisibleElements, { timeout: 5000, }); } else { window.requestAnimationFrame(findByVisibleElements); } }; var findByVisibleElements = function(ts) { var elapsedSinceLast = ts - lastAnimationTS; // se não teve nenhum evento que possa alterar a página if(hadAnEvent == false) { return look(); } if(elementsToWatch.size == 0) { return look(); } if(runningSearch == true) { return look(); } // procura por elementos visíveis apenas 5x/seg if(elapsedSinceLast < 1000/5) { return look(); } // atualiza o último ts lastAnimationTS = ts; // reseta status de scroll para não entrar novamente aqui hadAnEvent = false; // indica que está rodando a procura por elementos no viewport runningSearch = true; const done = Array.from(elementsToWatch.keys()).reduce(asyncValidateIfElIsInViewPort, Promise.resolve()); // obtém todos os elementos que podem ter view contabilizados //elementsToWatch.forEach(function(cb, el) { // if(isElementInViewport(el) == true) { // // remove da lista para não ser disparado novamente // elementsToWatch.delete(el); // cb(el); // } //}); done.then(function() { runningSearch = false; }); // reinicia o fluxo de procura look(); }; /** * Quando o elemento `el` entrar no viewport (-20%), cb será disparado. */ window.lazyload = function(el, cb) { if(el.nodeType != Node.ELEMENT_NODE) { throw new Error("element parameter should be a Element Node"); } if(typeof cb !== 'function') { throw new Error("callback parameter should be a Function"); } elementsToWatch.set(el, cb); } var setEvent = function() { hadAnEvent = true; }; window.addEventListener('scroll', setEvent, { capture: true, ive: true }); window.addEventListener('click', setEvent, { ive: true }); window.addEventListener('resize', setEvent, { ive: true }); window.addEventListener('load', setEvent, { once: true, ive: true }); window.addEventListener('DOMContentLoaded', setEvent, { once: true, ive: true }); window.gevent.on('allJSLoadedAndCreated', setEvent, window.gevent.RUN_ONCE); // inicia a validação look(); })();
  • AssineUOL
Topo

A memória lotou? Apps começam a rodar no celular sem instalação

Google Play começa a mostrar a opção "testar agora" para alguns dispositivos - Reprodução
Google Play começa a mostrar a opção "testar agora" para alguns dispositivos Imagem: Reprodução

Do UOL, em São Paulo

25/10/2017 04h00

Na semana ada, o Google começou a disponibilizar para os usuários o recurso Instant Apps para alguns aplicativos. Com ele, você pode usar apps sem instalá-los no seu celular ou tablet Android, resolvendo assim um problema antigo para muita gente: a falta de espaço na memória do aparelho para continuar a instalar apps.

Porém, essa solução por enquanto é parcial. Os motivos são três: ele só está disponível em alguns celulares no momento; nem todos os apps estão contando com a novidade; e mesmo os Instant Apps que já funcionam não contêm todo o conteúdo e interface dos apps "reais", que são instalados na memória.

VEJA TAMBÉM:

Sobre o primeiro motivo, o Google diz que nem todos os aparelhos são compatíveis, mas não especifica quais modelos estão aptos ou não.

24.out.2017 - App ShareTheMeal na versão "instant app" - Reprodução - Reprodução
App ShareTheMeal na versão "instant app"
Imagem: Reprodução

Como funciona?

Quando você está no celular e toca em um link para um endereço web, a Google Play verifica se há um aplicativo instalado no seu celular que pode abrir o link. Não havendo nenhum do tipo, ele abrirá o link no Instant App correspondente (se ele existir).

Outra forma de fazer isso é clicar no botão "Testar agora" de um aplicativo novo para seu celular na página do mesmo na Google Play, como na foto que abre esta notícia). Se esse botão não apareceu, é porque o app em questão ainda não existe na "versão instantânea".

Ok, vou tentar. O que acontece?

Se o celular estiver conectado à web, um Instant App abre no celular como uma janela à parte, ocupando toda a tela. Ele carrega somente as partes do app necessárias para executar a ação atual, como se fossem páginas da web, mas sem usar um app navegador. Daí é só experimentar.

É como se o app - ou parte dele-  funcionasse apenas na "nuvem", isto é, em servidores da web. Nos nossos testes, todos os Instant Apps experimentados mostram um botão "instalar", caso tenha gostado e queira a versão integral do app.

Essas partes do Instant App e os dados armazenados são temporariamente adicionados ao dispositivo. Ensinaremos mais abaixo como limpar os dados de um Instant App específico.

Quais apps contam com o recurso?

Essa lista traz a até agora diminuta lista de apps que já mostram o recurso. Aparecem seis: Buzzfeed (notícias e vídeos), NYTimes Crossword (palavras cruzadas), Onefootball (resultados de jogos de futebol), ShareTheMeal (doação de alimentos), Red Bull TV (vídeos de esportes e música) e Skyscanner (buscador de preços de agens aéreas).

No entanto, o Skyscanner não mostrou a opção "Testar agora" no teste do UOL. É possível que esta apareça só em alguns países.

Já com os demais apps, a versão "Instant" se mostrou bem mais "pobrinha" que a completa. No Buzzfeed, por exemplo, só trazia vídeos, enquanto o app integral também trazia listas e notícias na página principal. No ShareTheMeal, só havia espaço para doações (ver imagem acima), enquanto o app completo traz bem mais opções, como compartilhamento de fotos e acompanhamento de hashtags sociais.

Espera-se que mais apps ganhem compatibilidade com o recurso. As instruções para os desenvolvedores de apps estão disponíveis na página do Android (em inglês)..

O que mais preciso saber?

Os Instant Apps usados ficam registrados nas configurações do seu celular, para controle do próprio usuário (e para o Google ficar sabendo, talvez?). 

Se não gostar ou não quiser mais isso, você pode alterar a configuração:

  • No seu dispositivo, abra o app Configurações.
  • e o menu "Google", depois "Aplicações Instantâneos".
  • Mova o botão de opção para ativar ou desativar os apps instantâneos.

Você pode limpar os dados de um app instantâneo que usou. Para isso, repita os os acima, toque no Instant App em questão e depois em "Limpar dados do app". Nessa mesma tela tem o botão "Instalar", caso queira a versão completa do app.

Você ainda controla as permissões e o o às suas informações --como uso da câmera, o aos contatos telefônicos etc.-- de um Instant App da mesma forma que um app instalado. Repita os os Configurações > Google > Aplicações Instantâneos > escolha um app e clique em "Permissões".

Precisa digitalizar um documento? Deixe o scanner de lado e use seu celular

UOL Notícias