Android 待处理异常

标签 android exception

我的应用程序是一个混合的 html5 + JS + android,它在 webview 中运行,并通过 JS 接口(interface)与 Andorid 进行大量通信。

我收到一些报告称在某些设备上 2 秒后会失败。我添加了 ACRA,这样我就可以获得报告,但我什么也没得到。

所以我尝试自己测试它,为了引发异常,我添加了一段代码来操作 Javascript 界面函数中主线程的 View ,该函数是通过 html 中的按钮触发的。这会引发异常:只有创建 View 层次结构的原始线程才能触摸其 View 。现在应用程序启动,当我点击按钮时,它会异常退出,ACRA 会发送报告。

然后我将操作代码放在JS接口(interface)的函数中,该函数在应用程序启动后立即调用。现在应用程序在一秒钟后关闭。但 ACRA 不会发送任何错误。即使 ExceptionHandler 也没有捕获它,但捕获了第一种情况。

这是第二种情况的日志:

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

我不知道这个待处理的异常是什么?我在网上找不到任何东西。我想知道为什么 ACRA 或异常处理程序不捕获它?

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
    }
}

这是我的 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");

    }
}

这是index.html的一部分:

<script type="text/javascript">
android.immediatelyCalled();
</scritp>
<button onclick="android.buttonCalled()"></button>

在 AVD 2.2 和 Xperai Arc 4.0.3 上测试,两者相同

最佳答案

我认为立即调用()方法是在另一个线程中调用的,而不是您正在创建的“MyActivity父级”(UI线程,您的应用程序主线程)。因此,分配给 ui 线程且与运行 javascript 代码的进程无关的未捕获异常处理程序无法捕获 setText 处发生的此异常(访问属于另一个线程的 View )。

我认为如果您附上parent.textview1.setText(“test”);,您当然可以捕获异常。在 try catch block 中。 如果您以这种方式修改 setText 调用,您应该能够避免异常:

parent.textView1.post(new Runnable() {
    public void run() {
        parent.textview1.setText("test");
    }
});

您必须将父参数标记为最终参数。 不幸的是我这里没有 eclipse 可供测试,而且已经晚了:) 祝你好运!

关于Android 待处理异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13886941/

相关文章:

android - Gradle构建时,任务 ':app:transformClassesWithDexForDebug'执行失败

Android 如何在多个动画上添加一些延迟?

list - 如何用Erlang重写列表?

python - 如何检查当前代码是否是 try-except-block 的一部分?

Android Studio 模拟器无法使用 API 27

java - 如何添加 float 但将总数保持/包装在 0..1 范围内?

java - Selenium (Java) 消息 "Unable to locate element"但元素和 XPath 存在

python - 如何在线程后继续代码?对这段代码的流程感到困惑

java - 如何处理您没有预料到的异常,即使它已在文档中声明?

java - 如何对 Android RxJava 多线程进行单元测试