Android: использование WebView вне контекста активности

Я пытаюсь достичь веб-очистки через фоновый IntentService, который периодически очищает веб-сайт без отображения представления на телефоне пользователей.

  • поскольку мне нужно вызвать javascript на загруженной странице, Я не могу использовать HttpGet и т. д.
  • поэтому я должен использовать экземпляр WebView, который может работать только в потоке пользовательского интерфейса.
  • любые попытки запустить действие, использующее WebView, приводят к появлению представления на переднем плане телефонов (в соответствии с дизайном деятельности Android)
  • любые попытки использовать WebView вне контекста действия привели к ошибке, указывающей на то, что вы не можете использовать WebView в потоке без пользовательского интерфейса.
  • по различным причинам сложности я не могу рассматривать использование библиотек, таких как Rhino для веб-скрейпинга без пользовательского интерфейса.

есть ли способ обойти эту проблему?

8 ответов


вы можете отобразить webview из службы. Код ниже создает окно, к которому имеет доступ ваша служба. Окно не отображается, так как размер равен 0 на 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);
    }
}

также для этого потребуется android.permission.SYSTEM_ALERT_WINDOW разрешения.


исправьте меня, если я ошибаюсь, но правильный ответ на этот вопрос заключается в том, что нет возможности использовать WebView в фоновом режиме, когда пользователь делает другие вещи по телефону, не прерывая пользователя с помощью действия.

я применил как предложения Рэнди, так и Code_Yoga: использование действия с " Theme.NoDisplay " для запуска фоновой службы с WebView для выполнения некоторых работ. Однако, несмотря на то, что никакого представления не видно, переключение на эту активность для этой секунды, чтобы запустить службы прерывает пользователя (ex. как приостановка бегущей игры, в которую играли).

полностью катастрофические новости для моего приложения, поэтому я все еще надеюсь, что кто-то даст мне способ использовать WebView, который не нуждается в активности (или замене WebView, который может выполнить то же самое)


вы можете использовать это, чтобы скрыть активность

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

Это предотвратит приложение от показа какой-либо деятельности. И тогда вы сможете заниматься своими делами.


решение было таким, но с Looper.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
}

С помощью @JonasCz:https://stackoverflow.com/a/28234761/466363


WebView не может существовать вне действия или фрагмента из-за того, что он является пользовательским интерфейсом. Однако это означает, что действие необходимо только для создания WebView, а не для обработки всех его запросов.

Если вы создаете невидимый WebView в своей основной деятельности и имеете к нему доступ из статического контекста, вы должны иметь возможность выполнять задачи в представлении в фоновом режиме из любого места, так как я считаю, что все IO WebView выполняется асинхронно.

чтобы забрать ick этот глобальный доступ, вы всегда можете запустить службу со ссылкой на WebView для выполнения необходимой работы.


или заменитель WebView, который может выполнить то же самое


Я знаю, что прошло полтора года, но теперь я столкнулся с той же проблемой. В конце концов я решил это, запустив свой код Javascript внутри движка узла, который работает внутри моего приложения Android. Это называется JXCore. Можете взглянуть. Кроме того, взгляните на это пример который запускает Javascript без WebView. Я действительно хотел бы знать, что вы в конечном итоге используете?


Почему бы вам не создать бэкэнд-сервис, который делает выскабливание для вас?

а затем вы просто опрашиваете результаты веб-сервиса RESTful или даже используете промежуточное программное обеспечение для обмена сообщениями (например, ZeroMQ).

может быть, более элегантный, если он подходит для вашего случая использования: пусть служба очистки отправить приложение Push-сообщения через GCM:)