问题
My app is a hybrid html5 + JS + android which run in webview and communicate so much with Andorid through JS interface.
I got some report that it fails after 2 second on some devices. I added ACRA so I can get reports, but I didn't get any thing.
So I tried to test it myself, To raise an exception I add a code that manipulate views of main thread in Javascript interface's function which was triggered with a button in html. This raise an exception: Only the original thread that created a view hierarchy can touch its views. Now the app start and when I tap the button it exit with exception and ACRA send the report.
Then I put the manipulation code in a function of JS interface which was called immediately after the app start. now app is closed after a second. But ACRA doesn't send any error. Even an ExceptionHandler didn't catch it but catch the first case.
This is the log of second scenario:
59): Starting input on non-focused client com.android.internal.view.IInputMethodClient$Stub$Proxy@43f8d990 (uid=10019 pid=329)
12-15 01:18:07.047: WARN/dalvikvm(409): JNI WARNING: JNI method called with exception raised
12-15 01:18:07.047: WARN/dalvikvm(409): in Landroid/webkit/BrowserFrame;.stringByEvaluatingJavaScriptFromString (Ljava/lang/String;)Ljava/lang/String; (NewString)
12-15 01:18:07.057: WARN/dalvikvm(409): Pending exception is:
12-15 01:18:07.057: INFO/dalvikvm(409): Landroid/view/ViewRoot$CalledFromWrongThreadException;: Only the original thread that created a view hierarchy can touch its views
I don't know what this pending exception is? I couldn't find anything on web. I wonder why dont ACRA or Exception Handler catch it?
class JavaScriptInterface
{
MyActivity parent;
JavaScriptInterface(MyActivity parent)
{
this.parent = parent;
}
public void immediatelyCalled()
// Webview load index.html in oncreate of activity and js inside html calls this function immediately
{
parent.textview1.setText("test");
// raise an exception which ACRA or Exception Handler dont catch
// Problem is here
}
public void buttonCalled()
// This is called when a button is tapped in html
{
parent.textview1.setText("test");
// raise an exception which Exception Handler and ACRA catch
}
}
this is my activity:
public class MyActivity extends Activity
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
class MyExceptionHandler implements Thread.UncaughtExceptionHandler
{
@Override
public void uncaughtException(Thread thread, Throwable throwable)
{
Log.d("ExceptionHandler", "Caught exception: " + throwable.getClass().getName() + ": " + throwable.getMessage());
}
}
MyExceptionHandler handler = new MyExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(handler);
this.wv = (WebView) findViewById(R.id.webview);
this.wv.addJavascriptInterface(new JavaScriptInterface(this), "android");
this.ws = this.wv.getSettings();
this.ws.setJavaScriptEnabled(true);
this.wv.loadUrl("file:///android_asset/index.html");
}
}
this is part of index.html:
<script type="text/javascript">
android.immediatelyCalled();
</scritp>
<button onclick="android.buttonCalled()"></button>
Tested on AVD 2.2 and Xperai Arc 4.0.3, Both the same
回答1:
I think the method immediatelyCalled() is called in another thread than the one you are creating "MyActivity parent" (a UI thread, your apps main thread). So an uncaught exception handler which you assign to the ui thread and which has nothing to do with the process which is running the javascript code, can not catch this exception occuring at setText (accessing a view which belongs to another thread).
I think you could catch the exception of course if you enclose parent.textview1.setText("test"); in a try catch block. You should be able to avoid the exception if you modify the setText call in this way:
parent.textView1.post(new Runnable() {
public void run() {
parent.textview1.setText("test");
}
});
You'll have to mark your parent parameter as final. Unfortunately i have no eclipse here to test and it's late already :) good luck!
来源:https://stackoverflow.com/questions/13886941/android-pending-exception