Android: Korzystanie z WebView poza kontekstem aktywności

Staram się osiągnąć Scraping WWW poprzez IntentService tła, które okresowo scrapuje stronę internetową bez wyświetlania widoku na telefonie użytkowników.

  • ponieważ muszę wywołać jakiś javascript na załadowanej stronie nie mogę użyć żadnego HttpGet ' s itp.
  • dlatego muszę użyć instancji WebView, która może działać tylko na wątku UI.
  • Wszelkie próby uruchomienia aktywności, która korzysta z WebView, powodują, że Widok pojawia się na pierwszym planie telefonu (zgodnie z Androidem projektowanie działań)
  • Wszelkie próby użycia widoku sieci Web poza kontekstem aktywności powodowały błąd wskazujący na fakt, że nie można używać widoku sieci Web w wątku innym niż interfejs użytkownika.
  • z różnych powodów złożoności nie mogę rozważyć używania bibliotek takich jak Rhino do skrobania stron internetowych bez interfejsu użytkownika.

Czy Jest jakiś sposób obejścia tego problemu?

Author: Pierre, 2013-09-18

8 answers

Możesz wyświetlić widok sieci Web z usługi. Poniższy kod tworzy okno, do którego usługa ma dostęp. Okno nie jest widoczne, ponieważ rozmiar wynosi 0 Na 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);
    }
}

Również to będzie wymagało pozwolenia android.permission.SYSTEM_ALERT_WINDOW.

 39
Author: Randy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-30 18:24:56

Popraw mnie, jeśli się mylę, ale poprawna odpowiedź na to pytanie jest taka, że nie ma możliwości korzystania z widoku sieci Web w tle, podczas gdy użytkownik robi inne rzeczy przez telefon bez przerywania użytkownikowi za pomocą aktywności.

Zastosowałem zarówno sugestie Randy 'ego, jak i Code_Yoga: Korzystanie z aktywności z" motywem.NoDisplay", aby uruchomić usługę w tle z WebView, aby wykonać jakąś pracę. Jednak mimo braku widoczności przejście na tę czynność dla tego drugie uruchomienie usługi przerywa użytkownikowi (np. jak pauzowanie rozgrywanej gry).

Totalnie katastrofalne wiadomości dla mojej aplikacji, więc nadal mam nadzieję, że ktoś da mi sposób na korzystanie z WebView, który nie wymaga aktywności (lub substytut WebView, który może osiągnąć to samo)

 9
Author: Pierre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-28 10:51:35

Możesz użyć tego do ukrycia aktywności

         <activity android:name="MyActivity"
          android:label="@string/app_name"
          android:theme="@android:style/Theme.NoDisplay">

Spowoduje to, że aplikacja nie będzie wyświetlać żadnej aktywności. A potem możesz robić swoje rzeczy w działalności.

 7
Author: Code_Yoga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-25 07:45:36

Rozwiązanie było takie, ale z looperem.getMainLooper ():

Https://github.com/JonasCz/save-for-offline/blob/master/app/src/main/java/jonas/tool/saveForOffline/ScreenshotService.java

@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
}

Z pomocą @JonasCz: https://stackoverflow.com/a/28234761/466363

 2
Author: Shimon Doodkin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:21

WebView nie może istnieć poza działaniem lub fragmentem, ponieważ jest interfejsem użytkownika. Oznacza to jednak, że działanie jest potrzebne tylko do utworzenia widoku sieci Web, a nie do obsługi wszystkich jego żądań.

Jeśli tworzysz niewidoczny WebView w swojej głównej aktywności i masz do niego dostęp ze statycznego kontekstu, powinieneś być w stanie wykonywać zadania w widoku w tle z dowolnego miejsca, ponieważ wierzę, że wszystkie IO WebView są wykonywane asynchronicznie.

Aby zabrać ick tego globalnego dostęp, zawsze możesz uruchomić usługę z odniesieniem do widoku sieci Web, aby wykonać pracę, której potrzebujesz.

 1
Author: user2587659,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-17 15:53:28

Lub substytut WebView, który może osiągnąć to samo

 0
Author: Nartus Team,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-22 10:14:58

Wiem, że minęło półtora roku, ale teraz mam ten sam problem. Rozwiązałem go w końcu uruchamiając mój kod Javascript wewnątrz silnika węzła, który działa w mojej aplikacji na Androida. Nazywa się JXCore . Możesz spojrzeć. Spójrz również na ten Przykład , który uruchamia Javascript bez widoku sieci Web. Naprawdę chciałbym wiedzieć, czego użyłeś?

 0
Author: oriharel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-20 13:16:44

Dlaczego nie stworzysz usługi Backendowej, która zrobi skrobanie za Ciebie?

A potem po prostu sprawdzasz wyniki z RESTful Webservice lub nawet korzystasz z messaging middleware (np. ZeroMQ).

Może bardziej elegancki, jeśli pasuje do twojego przypadku użycia: niech usługa skrobania wysyła wiadomości Push aplikacji przez GCM:)

 0
Author: McOzD,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-08 09:26:31