好久没有写博客了,抽个时间总结一下最近项目遇到的问题,给大家分享一下。。。
大家都是知道的,我们做Android App项目时,混合开发已经成为我们不可或缺的方式,那么这种混合开发肯定涉及到Android原生和H5数据通信,当然了这种相互通信传递数据,网上已经有很多介绍了,这里我们说下其他的点,它就是原生加载本地H5页面,并且在H5页面里做网络请求;这里不知道为什么写好的Html页面在浏览器上是可以打开的也可以正常请求数据刷新页面,但是在Android原生里使用原生控件WebView去loadUrl怎么都不行,H5页面里的初始化方法里也发起网络请求,但是就是拿不到数据,没有请求响应,经过后来一番询问,得知需要点击事件发起动作才行,所以我就写了一下点击事件在H5里去执行请求数据的操作,居然成功了,我也是呵呵......,但是细想这个数据刷新操作不可能进来点击才去执行呀,所以翻了一下之前做过的项目,找到了下面的方法分享出来。。。
原生部分示例:
下面是加载本地H5页面的WebViewActivitypublic class WebViewActivity extends Activity { private static final String TAG = "WebViewActivity"; public static final String INTENT_URL = "H5_request_url"; private WebView webview; private String webUrl; private boolean isReady = false;//默认false,待本地页面加载完成后为true @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().setBackgroundDrawableResource(android.R.color.holo_blue_light); setContentView(R.layout.web_view); initView(); } // 初始化控件 private void initView() { webUrl = getIntent().getStringExtra(INTENT_URL); LogUtil.d(TAG, "webUrl h5 = " + webUrl); webview = (WebView) findViewById(R.id.webview); WebSettings webSettings = webview.getSettings(); // 设置WebView属性,能够执行Javascript脚本 webSettings.setJavaScriptEnabled(true); // 设置可以访问文件 webSettings.setAllowFileAccess(true); webSettings.setAllowFileAccessFromFileURLs(true); webSettings.setAllowContentAccess(true); webview.setWebChromeClient(new WebChromeClient() { @Override public void onProgressChanged(WebView view, int newProgress) { super.onProgressChanged(view, newProgress); if (newProgress==100) //对页面进度加载做出判断,加载完成时,即修改isReady为True,去进行H5中的请求操作 isReady = true; LogUtil.d(TAG,"newProgress = "+newProgress); } }); //js与android调用 webview.addJavascriptInterface(new NativeInterface(this, webview), NativeInterface.INTERFACE_NAME); webview.loadUrl("file:///android_asset/"+webUrl); } @Override protected void onResume() { super.onResume(); final String action = "javascript:startRequest();"; exec(action); // 执行H5中的startRequest()进行网络请求操作 } //一直循环执行,等待页面加载完成,再去做请求操作 protected void exec(final String trigger) { if (isReady) { load(trigger); } else { webview.postDelayed(new Runnable() { @Override public void run() { exec(trigger); } }, 100); } } //执行webview的loadUrl操作去startRequest private void load(String trigger) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { webview.evaluateJavascript(trigger, null); } else { webview.loadUrl(trigger); } } }
那么H5中是怎么处理呢,请继续往下看:
我们只需要早h5中定义下面方法,供原生端使用即可,
// first Request function startRequest() { GetSwdbParame(_token); // 这个方法就是具体进行获取网络数据的处理,具体请求业务就不贴出来了 }综上,其实就是总结Android原生控件WebView加载本地含有网络请求的Html页面时,通过webview做了一个循环延迟迭代,等到页面加载完成后立即触发js的网络请求事件,以达到获取数据的目的,关键逻辑如下:
webview.postDelayed(new Runnable() { @Override public void run() { exec(trigger); } }, 100);
好了,这个点分享就到这里了,如有不足,欢迎各位老铁拍砖。。。O(∩_∩)O哈哈~