[WebView坑]Calling View methods on another thread than the UI thread

问题

最近接搜狗sdk,调用支付接口的时候闪退,报错

java.lang.IllegalStateException: Must be called from main thread of process

于是放到runOnUiThread中调用

m_context.runOnUiThread(new Runnable() {
	@Override
	public void run() { 
		// TODO 搜狗pay
    }
});

可以拉起支付了,从支付宝的WebView返回,主Activity跪了,app闪退重启
报错如下

java.lang.IllegalStateException: Calling View methods on another thread than the UI thread.

解决办法

经过各种排查,终于找到了问题所在。
之前因为接广告sdk,需要获取设备的UA,即WebView User-Agent

顺便科普下
什么是UA?
答:UA的全称是User-Agent,中文名为用户代理,是Http请求协议中请求头的一部分,这里的请求包括GET请求和POST请求。
UA有什么作用?
答:在手机端/pc端,可以通过UA来判断不同的设备,从而可以显示不同的排版,进而给用户提供更好的体验,例如:用手机访问百度和pc端访问的页面排版是不一样的,这些就是百度根据访问者的UA来判断的。
还可通过UA,进行信息统计,主要是用于渠道统计。例如:在app中接入广告的sdk,当用户点击广告图片时就需要通过webview进行详细广告页面的跳转,这时候就需要在webview中进行UA的自定义设置了,这样后台广告平台的人员就可以通过UA判断是哪个客户端(安卓/苹果),哪个浏览器的客户,进而进行客户端的统计。

看了下之前获取UA封装的接口是这样的

@SuppressWarnings("unchecked")
public static String GetWebViewUserAgent(Context ctx) {
	String ua = "";
	try {
		WebView web = new WebView(ctx);
		ua = web.getSettings().getUserAgentString();
		web.destroy();
	}
	catch(Exception e) {
		Log.e("SDK", "GetWebViewUserAgent Exception");
		e.printStackTrace();
	}
	return ua;
}

上面的写法已经过时了,在android4.4+之后,要使用WebSettings.getDefaultUserAgent接口,如下

@SuppressWarnings("unchecked")
public static String GetWebViewUserAgent(Context ctx) {
	String ua = "";
	try {
		if(Build.VERSION.SDK_INT < 19) {
			WebView web = new WebView(ctx);
			ua = web.getSettings().getUserAgentString();
			web.destroy();
		}
		else
		{
			ua = WebSettings.getDefaultUserAgent(ctx);
		}
	}
	catch(Exception e) {
		Log.e("SDK", "GetWebViewUserAgent Exception");
		e.printStackTrace();
	}
	return ua;
}

改完之后,就不会闪退了。
虽然不知道这里获取UA和搜狗sdk的支付那里有什么直接联系,但确实就是这里改了就好了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章