Android:在Activity上下文之外使用WebView

Pie*_*rre 24 android web-scraping android-webview intentservice android-activity

我正在尝试通过后台IntentService实现Web Scraping,该后台定期抓取网站而不在用户手机上显示视图.

  • 因为我必须在加载的页面上调用一些javascript我不能使用任何HttpGet等.
  • 因此,我必须使用只能在UI线程上运行的WebView实例.
  • 任何尝试启动使用WebView的Activity都会导致View进入手机前景(根据Android的活动设计)
  • 任何在Activity上下文之外使用WebView的尝试都会导致错误,指出您无法在非UI线程上使用WebView.
  • 出于各种复杂性的原因,我不能考虑使用像Rhino这样的库来实现无UI的网页抓取.

有什么方法可以解决这个问题吗?

Ran*_*ndy 42

您可以从服务显示Web视图.下面的代码会创建一个您的服务可以访问的窗口.窗口不可见,因为大小为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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这也需要android.permission.SYSTEM_ALERT_WINDOW许可.

  • 我知道这是一个老答案,但为了将来参考:即使使用KitKat中基于Chromium的WebView,这种方法确实有效.我在使用AlarmManager定期启动的服务中使用它.但是,您不需要将WebView添加到LinearLayout.将它直接添加到WindowManager似乎工作正常. (2认同)

Pie*_*rre 11

如果我错了,请纠正我,但对这个问题的正确答案是,当用户在手机上做其他事情而不通过活动中断用户时,没有办法在后台使用WebView.

我已经应用了Randy和Code_Yoga的建议:使用带有"Theme.NoDisplay"的活动来启动带有WebView的后台服务来完成一些工作.然而,即使没有可见的视图,在第二次启动服务时切换到该活动也会中断用户(例如暂停正在播放的正在运行的游戏).

对我的应用程序来说完全是灾难性的消息所以我仍然希望有人能给我一种方法来使用不需要Activity的WebView(或者可以替代可以完成相同操作的WebView)


Cod*_*oga 8

您可以使用它来隐藏活动

         <activity android:name="MyActivity"
          android:label="@string/app_name"
          android:theme="@android:style/Theme.NoDisplay">
Run Code Online (Sandbox Code Playgroud)

这样做会阻止应用显示任何活动.然后你可以在Activity中做你的东西.