cocos2dx项目(安卓版本)使用x5webview接入第三方H5链接

虽然cocos2dx有提供webview的技术支持,但其性能及业务能力满足不了项目日新月异的需求。这里使用腾讯浏览器的X5webview,依托X5内核强大的处理能力,使第三方H5页面能够更好的表现出来,其webview的优化、安全、体验和业务支持都得到了很大提升。

项目的分析及准备

X5SDK下载链接 使用-Android SDK(完整版)

首先先参考SDK接入文档 熟悉一下流程 。接下来 针对我们自己cocos2dx项目来做具体调整,由于项目代码中之前已经有功能使用到了cocos自己提供的webview,按照X5SDK接入文档是需要把这些地方全部替换掉的,但这样的改动代价有点大了,我们有更好的处理方案。

  1. 原有的cocos webview代码部分不作改动
  2. 新建一个Activity来启动X5webview 打开第三方H5链接。那么只需要在新建的Activity里接入X5SDK即可。第三方H5页面的展示方向可能是横屏或者竖屏,此时只需要调整新建的Activity的启动方向即可,这样也就避开了与我们自己app屏幕展示方向冲突的问题。

X5SDK接入及项目结构部署

  1. 在项目的libs目录中导入X5SDK的需要.jar包
  2. App启动预加载x5内核,接入文档有说明,不会阻塞主线程,对App启动性能没有影响,主要是为了首次创建webview时加快启动速度。代码加的地方在 xxxApplication extends Application。如QbSdk.initX5Environment(getApplicationContext(), null);在这里插入图片描述
  3. 项目新建一个package 可以命名为com.xxx.x5webview 将X5SDK Demo中的X5WebView.java(改改包头即可)放入到新建的package里,同时新建一个Activity类用来打开x5webview。
    在这里插入图片描述

X5Activity在AndroidManifest.xml里的注册及说明
在这里插入图片描述
在这里插入图片描述

启动X5Activity及其处理的业务逻辑

// 从当前项目的主Activity启动一个新Activity
	public static void StartX5Activity(String url, String appid) {
		Intent intent = new Intent();
		intent.setClass(mActivity, X5Activity.class);
		Bundle bundle = new Bundle();
		bundle.putString("url", url);
		bundle.putString("appid", appid);
		intent.putExtras(bundle);
		mActivity.startActivity(intent);
	}

类X5Activity

/**
 * 以andorid原生Activity打开X5Webview
 */
 public class X5Activity extends Activity {
	private X5WebView mWebView;
	private	String mUrl;
	private String mPayMsg;
	private String mAppid;
	private Timer mLoginTimer;
	
	public static final int MSG_INIT_UI = 0;
	public static final int MSG_CLOSE_ACTIVITY = 1;
	public static final int MSG_RELOAD_URL = 2;
	public static final int MSG_START_PAY = 3;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		
		// 接收数据
		Bundle bundle = this.getIntent().getExtras();
		mUrl = bundle.getString("url");
		mAppid = bundle.getString("appid");
		
		// 初始化UI
		mHandler.sendEmptyMessageDelayed(MSG_INIT_UI, 10);
	}
	
	private void init() {
		// 创建x5webview
		mWebView = new X5WebView(this, null);
		
		// 背景透明
		mWebView.setBackgroundColor(Color.TRANSPARENT);
		
		// 创建布局文件
		FrameLayout layout = (FrameLayout) findViewById(android.R.id.content).getRootView();
		layout.setBackgroundColor(0);
		layout.addView(mWebView, new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT,FrameLayout.LayoutParams.FILL_PARENT));
		
		mWebView.setWebViewClient(new WebViewClient() {
			@Override
			public boolean shouldOverrideUrlLoading(WebView view, String url) {
				// 监听关键字 关闭webview
				if(url.equalsIgnoreCase("xxxxx://close_webview")) {
					mHandler.sendEmptyMessageDelayed(MSG_CLOSE_ACTIVITY, 10);
					return true;							
				}
				
				// 截取部分信息 监听关键字 拉起支付 substring 参数 根据 "xxxxx://pay" 设置
				if(url.substring(0,12).equalsIgnoreCase("xxxxx://pay")) {
					mPayMsg = url;
					mHandler.sendEmptyMessageDelayed(MSG_START_PAY, 10);
	                return true;
				}
				
				// 加载重定向链接
				view.loadUrl(url);
				
				return true;
			}
			
			@Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                // TODO Auto-generated method stub
                super.onPageStarted(view, url, favicon);
				
                //启动一个定时器 到达设定时间后 重新加载链接
                mLoginTimer = new Timer();
                TimerTask tt = new TimerTask() {
                    @Override
                    public void run() {
                        if (X5Activity.this.mWebView.getProgress() < 100) {
                            mHandler.sendEmptyMessageDelayed(MSG_RELOAD_URL, 10);    
                            mLoginTimer.cancel();
                            mLoginTimer.purge();
                        }
                    }
                };
                mLoginTimer.schedule(tt, 5000);
            }
			
			@Override
			public void onPageFinished(WebView view, String url) {
				super.onPageFinished(view, url);
				if (X5Activity.this.mWebView.getProgress() == 100) {
					// 取消定时器
					mLoginTimer.cancel();
					mLoginTimer.purge();
				}
			}
			
			@Override  
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {  
                super.onReceivedError(view, errorCode, description, failingUrl);  
            }
		});
		
		mWebView.setWebChromeClient(new WebChromeClient() {
			@Override
			public void onProgressChanged(WebView view, int newProgress) {
				// TODO Auto-generated method stub
				super.onProgressChanged(view, newProgress);
			}
		});
		
		// 加载链接
		mWebView.loadUrl(mUrl);
		
		// cookie
		CookieSyncManager.createInstance(this);
		CookieSyncManager.getInstance().sync();
	}

	
	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			switch (msg.what) {
			case MSG_INIT_UI:
				init();
				break;
			case MSG_CLOSE_ACTIVITY:
				X5Activity.this.finish();
				break;
			case MSG_RELOAD_URL:
				mWebView.loadUrl(mUrl);
				break;
			case MSG_START_PAY:
				StartPay();
				break;
			}
			super.handleMessage(msg);
		}
	};
	
	// 启动支付
	private void StartPay()
	{
		// 构造支付请求链接 业务逻辑处理
		String strPayReqUrl = "";
		
		if (strPayReqUrl == "") return;
		
		// 启动支付的Acitivity
		Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(strPayReqUrl));
		
		// 跳转到支付页面
		this.startActivity(intent);
	}
}