J'essaie de réaliser le Web Scraping à travers un arrière-plan IntentService qui raccroche périodiquement un site Web sans afficher de vue sur le téléphone des utilisateurs.
Existe-t-il un moyen de contourner ce problème?
Corrigez-moi si je me trompe, mais la réponse correcte à cette question est qu'il n'y a AUCUN moyen possible d'utiliser une WebView en arrière-plan lorsque l'utilisateur fait autre chose au téléphone sans l'interrompre au moyen d'une activité.
J'ai appliqué les suggestions de Randy et de Code_Yoga: Utiliser une activité avec "Theme.NoDisplay" pour lancer un service d'arrière-plan avec WebView pour effectuer un travail. Cependant, même si aucune vue n'est visible, le passage à cette activité pendant cette seconde pour que les services démarrent, interrompt l'utilisateur (par exemple, il met en pause un jeu en cours).
Des nouvelles totalement désastreuses pour mon application, j'espère donc toujours que quelqu'un me donnera le moyen d'utiliser une WebView qui ne nécessite pas d'activité (ou un substitut d'une WebView pouvant accomplir la même chose)
Vous pouvez afficher une vue Web à partir d'un service. Le code ci-dessous crée une fenêtre à laquelle votre service a accès. La fenêtre n'est pas visible car la taille est 0 par 0.
public class ServiceWithWebView extends Service {
@Override
public void onCreate() {
super.onCreate();
WindowManager windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
params = new WindowManager.LayoutParams(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, PixelFormat.TRANSLUCENT);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.x = 0;
params.y = 0;
params.width = 0;
params.height = 0;
LinearLayout view = new LinearLayout(this);
view.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
WebView wv = new WebView(this);
wv.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
view.addView(wv);
wv.loadUrl("http://google.com");
windowManager.addView(view, params);
}
}
De plus, cela nécessitera l'autorisation Android.permission.SYSTEM_ALERT_WINDOW
.
Vous pouvez l'utiliser pour masquer l'activité
<activity Android:name="MyActivity"
Android:label="@string/app_name"
Android:theme="@Android:style/Theme.NoDisplay">
Cela empêchera l'application d'afficher une activité. Et vous pourrez ensuite faire votre travail dans l'activité.
la solution était comme ça, mais avec Looper.getMainLooper ():
@Override
public void onCreate() {
super.onCreate();
//HandlerThread thread = new HandlerThread("ScreenshotService", Process.THREAD_PRIORITY_BACKGROUND);
//thread.start();
//mServiceHandler = new ServiceHandler(thread.getLooper()); // not working
mServiceHandler = new ServiceHandler(Looper.getMainLooper()); // working
}
avec l'aide de @JonasCz: https://stackoverflow.com/a/28234761/466363
Une vue Web ne peut pas exister en dehors d'une activité ou d'un fragment, car il s'agit d'une interface utilisateur . Cependant, cela signifie qu'une activité n'est nécessaire que pour créer la vue Web et ne pas traiter toutes ses demandes.
Si vous créez la WebView invisible dans votre activité principale et que vous la rendez accessible à partir d'un contexte statique, vous devriez pouvoir effectuer des tâches dans la vue en arrière-plan depuis n'importe où, car je pense que tous les IO de WebView sont effectués de manière asynchrone.
Pour vous prémunir de cet accès mondial, vous pouvez toujours lancer un service avec une référence à WebView pour effectuer le travail dont vous avez besoin.
ou un substitut d'une WebView qui peut accomplir la même chose <=== si vous ne souhaitez pas afficher les informations chargées sur l'interface utilisateur, vous pouvez peut-être essayer d'utiliser HTTP pour appeler directement l'URL et traiter la réponse renvoyée par HTTP.
Je sais que cela fait un an et demi, mais je suis maintenant confronté au même problème. Je l'ai finalement résolu en exécutant mon code Javascript dans un moteur de nœud qui s'exécute dans mon application Android. Cela s'appelle JXCore . Vous pouvez jeter un coup d'oeil. Jetez également un coup d’œil à ce sample qui exécute Javascript sans WebView. Je voudrais vraiment savoir ce que vous avez fini par utiliser?
Pourquoi ne créez-vous pas un service d’arrière-plan qui effectue le nettoyage à votre place?
Et ensuite, vous n'interrogez que les résultats d'un service Web RESTful ou utilisez même un middleware de messagerie (par exemple, ZeroMQ).
Peut-être plus élégant si cela correspond à votre cas d'utilisation: laissez le service Scraping envoyer vos messages Push App via GCM :)