【问题标题】:Android: retrieve html of website certain time after requestAndroid:请求后一定时间检索网站的html
【发布时间】:2014-09-25 17:56:43
【问题描述】:

我的目标是在可读的String(我已经完成)中检索网站的html,并稍微修改代码,以便在Get 之后的某个时间检索html命令已发出。

这是我正在尝试做的一个示例:在网站http://time.gov/HTML5/ 上,页面加载时出现的html 不是完整的html;几秒钟后,javascript 命令执行,稍微修改html。我的目标是获得修改后的html

这是我为获得网站html所做的工作:

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DownloadTask task = new DownloadTask();
        task.execute("http://time.gov/HTML5/");

    }

    private class DownloadTask extends AsyncTask<String, Void, String>{

        @Override
        protected String doInBackground(String... urls) {
            HttpResponse response = null;
            HttpGet httpGet = null;
            HttpClient mHttpClient = null;
            String s = "";

            try {
                if(mHttpClient == null){
                    mHttpClient = new DefaultHttpClient();
                }


                httpGet = new HttpGet(urls[0]);


                response = mHttpClient.execute(httpGet);
                s = EntityUtils.toString(response.getEntity(), "UTF-8");


            } catch (IOException e) {
                e.printStackTrace();
            } 
            return s;
        }

        @Override
        protected void onPostExecute(String result){
            final TextView textview1 = (TextView) findViewById(R.id.headline);
            textview1.setText(result);

        }
    }
}

此代码正确获取未修改的html。但是,我试图在请求发出几秒钟后使用Thread.sleep(5000) 获取html(希望有足够的时间来更新html),但这不起作用。有谁知道如何解决这个问题?

【问题讨论】:

  • 尝试使用处理程序进行延迟。
  • @user3616949,当您使用 Traceview 或其他工具来确定您的时间花在哪里时,您学到了什么?

标签: java javascript android html


【解决方案1】:

您不想在 AsyncTask 上进行长时间的睡眠,因为它会阻止任何其他 AsyncTask。我会设置一个 5 秒的计时器,然后启动第二个 AsyncTask 实例来进行第二次读取。

【讨论】:

  • 那么我会设置一个 5 秒的计时器,然后再做一个 task.execute("http://time.gov/HTML5/"); 吗?这会进行第二次读取(效果很好)还是会进行另一次请求+读取(这会给我相同的结果)?
【解决方案2】:

我从您的问题中了解到,您需要在页面完全加载后(在运行页面内的所有脚本之后)获取网页的 HTML。

AFAIK,您当前的实现无法实现这一点。一旦调用函数HttpClient.execute(),就不能在该函数中应用任何延迟,它只会获取当前可用的数据。而且您也不能使用Handler。它只会帮助您延迟 'execute()' 调用。

不幸的是,我们无法为客户端设置任何侦听器,只要网页中的数据发生变化,它就会提供回调(至少我不知道有任何此类功能)。

但是您可以使用完全不同但无痛的方法来实现这一点。这就是你可以实现它的方式。

  1. 在您的活动中添加WebView,并保持隐藏
  2. 在 WebView 中加载网页
  3. 挂钩onPageFinished()WebViewClient 实现,然后将WebView 的html 内容注入JavaScriptInterface 实现。

WebView:

在您的布局 XML 中

<WebView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/my_web"
    android:visibility="gone"/>

在你的活动中 onCreate()

TextView textview1;

public void onCreate(Bundle savedInstanceState) {

    /* Your code here */

    textview1 = (TextView) findViewById(R.id.TextView1);

    WebView web = (WebView) view.findViewById(R.id.my_web);
    web.getSettings().setJavaScriptEnabled(true);
    web.addJavascriptInterface(new CustomJavaScriptInterface(), "JavaScriptInterface");
    web.setWebViewClient(new CustomWebViewClient());
    web.loadUrl("http://time.gov/HTML5/");

    /* Your code here */
}

WebViewClient

private class CustomWebViewClient extends WebViewClient {
    @Override
    public void onPageFinished(WebView view, String url) {
        //Inject the HTML in to the JavaScriptInterface
        view.loadUrl("javascript:window.JavaScriptInterface.html('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');");
    }
}

JavaScritpInterface

private class CustomJavaScriptInterface {

    @JavascriptInterface
    public void html(final String html) {
        //Your HTML is here
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                setTextHtml(html);
            }
        });
        Log.e("HTML Length", Integer.toString(html.length()));
    }
}

private void setTextHtml(String html) {
    textview1.setText(html);
}

结论:

为了验证这一点,我将行 Log.e("HTML Length", Integer.toString(html.length())); 放入您的 AsyncTask 的 postExecute() 中,这就是我记录的内容。

08-05 14:29:59.886 13332-13332/com.sample.fetchhtml E/HTML 长度﹕ 10438

同时从JavaScriptInterface的函数html()写入的日志是

08-05 14:30:09.021 13332-13420/com.sample.fetchhtml E/HTML 长度﹕ 22498

您可以看到我在这两种情况下得到的 HTML 字符串的大小差异。希望这会有所帮助。

更新(8 月 7 日): 执行延迟取决于网页在 web 视图中完全加载所用的时间。这种方式适用于包含启动脚本的网页。对于静态网页,最好使用HttpClient.execute()

【讨论】:

  • 酷,一个简单的问题:哪个String 包含实际的html?例如,如果我想将TextView 的文本设置为html,我会选择textview.setText(___)
  • CustomJavaScriptInterface 中函数public void html(String html)String 参数将具有实际的html。
  • 我会去textview.setText(html)吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-23
  • 2014-08-18
  • 2012-11-09
  • 2015-12-14
相关资源
最近更新 更多