cordova 非UI线程更新UI闪退的解决办法

文章详细介绍了在Cordova项目中如何更新HTML页面中的Tab标签,并强调了更新UI必须在主线程上的重要性。通过实例演示了如何避免AndroidRuntime异常,并解释了如何使用cordova提供的方法来确保在正确线程执行UI操作。同时,文章还展示了通过反射调用函数类方法的简化操作方式。

最近在用Cordova 做项目,需要在html页面中更新Tab标签,因此就写了一个函数类,方法如下

public void changeTab(final JSONArray args) {
		cordova.getActivity().runOnUiThread(new Runnable() {
		//cordova.getThreadPool().execute(new Runnable() {
			
			@Override
			public void run() {
				try {
					MainActivity.mTabHost.setCurrentTab(args.getInt(0));
				} catch (JSONException e) {
					e.printStackTrace();
				}
				
			}
		});
		
	}

原来一直在小米和三星的tab上测试没有问题,但到生产环境后,在三星note3上就会报如下错误:

AndroidRuntime(4507): android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.  
后来注意到更新UI一定要在主线程上,于是就使用了Activity的runOnUiThread的方法,

通过测试,发现问题解决了,

之后看cordovan的官网文档发现cordova的插件线程并没有运行在webView Interface的线程,

而是运行在WebCoreThread,如果需要更新UI就需要做如下的操作

根据cordova提供的官方文档需要如下操作:

 @Override
    public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
        if ("beep".equals(action)) {
            final long duration = args.getLong(0);
            cordova.getActivity().runOnUiThread(new Runnable() {
                public void run() {
                    ...
                    callbackContext.success(); // Thread-safe.
                }
            });
            return true;
        }
        return false;
    }

如果你不想在UI线程或者webCore线程上运行需要如下操作:

 @Override
    public boolean execute(String action, JSONArray args, final CallbackContext callbackContext) throws JSONException {
        if ("beep".equals(action)) {
            final long duration = args.getLong(0);
            cordova.getThreadPool().execute(new Runnable() {
                public void run() {
                    ...
                    callbackContext.success(); // Thread-safe.
                }
            });
            return true;
        }
        return false;
    }
之所以会出这样的错误还是自己看文档不够仔细

另外附上通过反射调用函数类方法的操作

public class Function extends CordovaPlugin {
	public CallbackContext callbackContext;

	@Override
	public boolean execute(String action, JSONArray args,
			CallbackContext callbackContext) throws JSONException {

		try {
			this.callbackContext = callbackContext;
			Function.class.getMethod(action, JSONArray.class)
					.invoke(this, args);
			return true;
		} catch (IllegalAccessException e) {
			callbackContext.error(e.getMessage());
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
			callbackContext.error(e.getMessage());
		} catch (InvocationTargetException e) {
			e.printStackTrace();
			callbackContext.error(e.getMessage());
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
			callbackContext.error(e.getMessage());
		}

		/*
		 * if("func".equals(action)){ Intent intent = new Intent();
		 * intent.setAction("android.media.action.IMAGE_CAPTURE");
		 * intent.addCategory("android.intent.category.DEFAULT");
		 * cordova.getActivity().startActivity(intent);
		 * Toast.makeText(cordova.getActivity(), "success.......",
		 * Toast.LENGTH_SHORT).show(); callbackContext.success("hello world"); }
		 */
		return false;
	}

这样可以简化一下操作。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值