我正在为Google Glass(SDK级别15)编写应用程序,并且需要显示WebView以在其中显示一些html。为了测试它,我定义了一个带有2个控件的布局 - TextView和WebView。
我在SurfaceHolder.Callback中制作的所有渲染。重要的是回调方法在后台线程上执行。
在调试模式下一切正常 - TextView和WebView显示内容很好。但是一旦我切换到运行配置应用程序崩溃异常:
java.lang.RuntimeException:无法在线程内创建处理程序 没有调用Looper.prepare() 在android.os.Handler。(Handler.java:121) 在android.webkit.ZoomControlExternal。(ZoomControlExternal.java:36) 在android.webkit.ZoomManager.getCurrentZoomControl(ZoomManager.java:1188) 在android.webkit.ZoomManager.dismissZoomPicker(ZoomManager.java:1204) 在android.webkit.ZoomManager.onSizeChanged(ZoomManager.java:946) 在android.webkit.WebView.onSizeChanged(WebView.java:5855) 在android.view.View.setFrame(View.java:11362) 在android.webkit.WebView.setFrame(WebView.java:5829) 在android.view.View.layout(View.java:11273) 在android.view.ViewGroup.layout(ViewGroup.java:4224) 在android.widget.LinearLayout.setChildFrame(LinearLayout.java:1628) 在android.widget.LinearLayout.layoutVertical(LinearLayout.java:1486) 在android.widget.LinearLayout.onLayout(LinearLayout.java:1399) 在android.view.View.layout(View.java:11279) 在android.view.ViewGroup.layout(ViewGroup.java:4224) 在android.widget.FrameLayout.onLayout(FrameLayout.java:431) 在android.view.View.layout(View.java:11279) 在android.view.ViewGroup.layout(ViewGroup.java:4224) 在android.widget.FrameLayout.onLayout(FrameLayout.java:431) 在android.view.View.layout(View.java:11279) 在android.view.ViewGroup.layout(ViewGroup.java:4224) 在com.adnecs.fit.TestDrawer.surfaceChanged(TestDrawer.java:61) 在com.google.android.glass.timeline.RemoteSurfaceHolder.setParameters(RemoteSurfaceHolder.java:104) 在com.google.android.glass.timeline.LiveCard $ 1.performDirectRenderingOperation(LiveCard.java:190) 在com.google.android.glass.timeline.ITimelinePublisher $ Stub.onTransact(ITimelinePublisher.java:60) 在android.os.Binder.execTransact(Binder.java:338) 在dalvik.system.NativeStart.run(原生方法)
原因很清楚 - 需要在UI线程上调用layout方法。我从UI线程传递了一个Handler对象,并尝试在其上运行'layout'方法。 适用于TextView,但WebView始终为空白。
以下是更改的代码(我留下旧版本注释):
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {
final int measuredWidth = View.MeasureSpec.makeMeasureSpec(i2, View.MeasureSpec.EXACTLY);
final int measuredHeight = View.MeasureSpec.makeMeasureSpec(i3, View.MeasureSpec.EXACTLY);
// mView.measure(measuredWidth, measuredHeight);
// mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
// draw();
mView.getHandler().post(
new Runnable() {
@Override
public void run() {
mView.measure(measuredWidth, measuredHeight);
mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
draw();
}
}
) ;
}
所以我的问题是:
感谢您的帮助!
答案 0 :(得分:0)
能够解决这个问题(如果有更多知识渊博的人可以评论或纠正我,也会很好)
首先,您必须在UI线程上运行WebView更新。
为什么它在Debug中工作:看起来就像时间一样。在WebView上运行loadData
时,需要一些时间来处理它。如果您在设置数据后立即致电draw
- 控件仍为空 - 内容页面尚未准备就绪。
我所做的是在页面加载之前运行渲染线程。为了确定页面是否已加载,我使用webview.setWebViewClient
注册回调并对onPageFinished
作出反应。