【问题标题】:how to make my phonegap android app crash?如何让我的 phonegap android 应用程序崩溃?
【发布时间】:2015-02-05 09:55:48
【问题描述】:

我正在为 phonegap android 应用程序开发崩溃报告插件。出于测试目的,我必须让我的应用程序崩溃并且必须调用“不幸的是,应用程序已停止”窗口。当我在 javascript 中发生未处理的异常时,应用程序没有崩溃。相反,它显示相同的屏幕。我通过在javascript中执行一些无限循环让应用程序屏幕停止响应用户输入并等待大约1小时,但应用程序仍然没有崩溃。 phonegap 库是否默认处理异常?如何通过在 javascript 级别中生成异常来使我的应用程序崩溃?

我尝试了下面的代码,在“CordovaActivity”类中添加了一个 java 方法来生成崩溃。

public static void generateCrash()
   {
     int a = 0;
     int b = 10;
     int c = b/a ;
    }

当我从 java(从活动类中的“onCreate”)调用此方法时,应用程序崩溃了。但是当我使用插件从 javascript 调用相同的方法时,应用程序没有崩溃。我希望我的应用程序通过从 javascript 调用/调用某些函数来崩溃。

【问题讨论】:

  • 好问题。您可以尝试一个无限递归函数:void function turtle() { turtle() } ()(纯属推测)。
  • @joews,递归函数产生异常(“Uncaught RangeError: Maximum call stack size exceeded”)。但应用程序没有崩溃,而是显示相同的屏幕。
  • 我不知道如何通过 javascript 进行异常处理,但是当我使用一个实际上在 .css 中编写了两次的样式类时,我的应用程序崩溃了。
  • @Jivings,你给的链接没用。

标签: javascript cordova


【解决方案1】:

按菜单按钮崩溃:

您不能通过插件或 javascript 调用使应用程序崩溃,因为异常是在内部处理的。如果您想让应用程序在 android 中崩溃,您可以在 Android 平台中编辑 CordovaActivity.java。改变onCreateOptionsMenu如图:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    this.postMessage("onCreateOptionsMenu", menu);
    throw new RuntimeException();
} 

菜单按钮,应用程序将崩溃并显示“不幸的是,应用程序已停止”窗口。

从 Javascript 调用一些本机函数导致崩溃:

为 Phonegap 编写一个 Android 原生插件。请参阅http://docs.phonegap.com/en/3.0.0/guide_platforms_android_plugin.md.html#Android%20Plugins 以创建插件。在执行方法中抛出异常。这将在父层处理(这就是为什么您可以在控制台中看到有关崩溃的日志),因此请进行以下更改以使应用程序崩溃。(这两个类都属于 org.apache。科尔多瓦包)

  • 删除 pluginManager 类的 execHelper 方法中的 catch (Exception e){} 块。
  • 删除 ExposedJsApi 类的 exec 方法中的 catch (Throwable e) {} 块。

    通过此更改,我可以通过 javascript 调用使应用程序崩溃。

【讨论】:

  • 你是对的。我们无法通过插件或 javascript 调用使应用程序崩溃,因为默认情况下,cordova 库会处理 Web 视图中的异常。因此,如果不编辑 cordova 库中的 Web 视图实现类,可能无法从 Javascript 生成崩溃。所以我接受这个答案。
【解决方案2】:

如果应用程序像网页一样运行,无限循环可能需要一些时间才能导致崩溃,但应该可以正常工作。请记住在测试后将其删除。因为它会导致异常,并使程序超时,所以如果在其中使用了可能有害的东西,则应该正确调用崩溃。做这样的事情:

while(true){ eval("9.99999e+5000 / Infinity"); }

因为我们没有编辑变量,所以我们将防止出现out of memory 错误。

如果这不起作用,请参阅@Aaron D 的回答,如果这不起作用,请参阅@kumar 的回答。

【讨论】:

  • 我试过上面的代码。执行无限while循环,屏幕停止响应,但应用程序没有崩溃。执行了无限循环并等待了很长时间(大约 45 分钟),应用程序仍然没有崩溃。我想这不适用于混合应用程序。如果是原生应用程序,如果屏幕停止响应 2-3 分钟,应用程序将崩溃。但是对于 phonegap/hybrid 应用程序来说并没有发生这种情况。
  • @SinuVarghese 试试 Aaron 所说的,它适用于我的混合应用程序。
  • @Wyatt 我尝试从执行方法中抛出运行时异常。我可以在控制台中看到错误,但应用程序没有崩溃!我正在使用科尔多瓦 3.5 版本。所以我尝试在 onCreateOptionsMenu(如下所示)中抛出异常,这对我有用。
  • @kumar 至少你找到了解决方案。
  • @kumar 你是对的,执行方法中的异常显示在控制台中,但应用程序没有崩溃。每当用户按下菜单按钮时,onCreateOptionsMenu 中的抛出异常都会产生崩溃,但我希望应用程序通过从 Javascript 调用/调用一些本机函数来崩溃。
【解决方案3】:

不幸的是,JS 异常是由 WebView 处理的,甚至本机插件也在它们自己的单独线程中运行,如果您在那里引发异常,不会使主应用程序线程崩溃(这对于混合应用程序可能不是真的)。所以你需要挂钩到主活动并使其在主线程上抛出异常。

继承CordovaActivity 类并覆盖插件消息传递方法:

@Override
public Object onMessage(String id, Object data) {
    if ("crashApp".equals(id)) {
        throw new Exception();
    }
    super(id, data);
}

为 Phonegap as per this answer 编写一个 Android 原生插件。它的作用无关紧要,但是当您从 Javascript 发送消息时,您应该使用 ID 'crashApp',它应该由 CordovaActivity 子类中的覆盖方法获取,并在主线程上引发异常。

。然后,您可以通过覆盖 window.onerror 函数,在遇到 Javascript 异常时使用此 ID 向您的插件发送消息:

window.onerror = function myFunction(errorMsg, url, lineNumber) { 
/* call Android native function to throw Exception */ ; 
return false; }

这会将所有 Javascript 错误扔到您的 Java 代码中,在那里它们可以引发 ANR 对话框(您也可以使用它传递调试信息)。

【讨论】:

  • 我试过了,我重写了 window.onerror 函数。现在所有的 Java 脚本异常都在这个函数中。但是从那里当我调用 android 本机函数抛出异常时,我可以在控制台中看到错误,但应用程序没有崩溃。它会在 Web 视图的实现中自动处理。
  • 你是对的,在某些情况下插件在单独的线程中运行,并且不会导致主应用程序线程崩溃的异常。我已经更新了我的答案,以提供一种技术,您可以将应用程序的主要 Activity 子类化并覆盖 Cordova 的 onMessage 公共方法以在您发送正确消息时崩溃。
  • 您的覆盖 onMessage 代码是错误的。该方法应该返回一个对象,但您没有返回任何内容。对 super 的调用也必须是方法中的第一行。如果您进行这些更改,您的解决方案也将不起作用,因为 throw 子句必须包含在 try-catch 块中。因此异常将在 catch 块中处理,并且应用程序不会崩溃。
【解决方案4】:

您可以通过从AndroindManifest.xml 文件中删除权限但仍在应用程序中使用它们来使您的cordova/phonegap 应用程序崩溃,这些异常通常会使您的应用程序崩溃。

请注意(取决于您的项目结构)修改 AndroindManifest.xml 文件本身,它可能会重新生成并更改回其正确状态,因此您需要删除权限行,然后更改 Androind.json 文件在构建之前的plugins 文件夹中,适当地使您的更改生效。

我测试了这个过程,它确实有效! :D

希望对你有帮助,咪咪 ;)

【讨论】:

  • 现在正在开发Phonegap应用程序的过程中,我可以验证一下我的头撞墙后没有正确的权限确实会导致您的应用程序崩溃。
【解决方案5】:
  1. 尝试下载任何超过 100MB 的文件(我的应用卡在低端机器人中)。 你甚至可以在循环中做到这一点。

  2. 使用画布并随机放置一些 3d 图形。

  3. 在 1000 条循环中应用一条警报消息。

【讨论】:

  • 我已经尝试过类似的代码。这会使应用程序由于“内存不足错误”而崩溃。但在这种情况下,崩溃报告插件无法正常工作,因为该插件是应用程序的一部分,并且没有更多内存可供应用程序执行。
【解决方案6】:

我坚信无限循环在这种情况下不起作用。当您将它与 PhoneGap 一起使用时,javascript 只是一种(安全的)脚本语言,不能生成系统驱动的异常。

最好的方法是在另一个PhoneGap插件的帮助下运行一些本机代码(有问题的代码)。例如,您可以在 Objective-C 和 Java 原生代码中进行除零。

【讨论】:

  • 你是对的。在这种情况下,无限循环将不起作用,并且 javascript 无法生成系统驱动的异常。本机代码中的异常可能会导致崩溃,但问题是当我在 PhoneGap 插件的帮助下从 javascript 调用有问题的本机代码时,它不会导致崩溃。
【解决方案7】:

通常,无论有意与否,执行停止都会导致 android 认为应用程序已崩溃。尝试将您的代码包装在 setTimeout(function() { your code }, 60000) 之类的东西中,以将执行延迟一分钟。

或者,尝试发出会超时的 ajax 请求。

【讨论】:

  • 延迟执行不会使 phonegap 应用程序崩溃。我通过执行一些无限循环使应用程序屏幕停止响应并等待了大约 1 小时,但应用程序仍然没有崩溃。
  • 很抱歉,我预计它会导致应用程序的主线程崩溃,就像在原生应用程序中那样会起作用。
【解决方案8】:

如何通过在 javascript 级别进行异常来使我的应用程序崩溃?

您无法处理导致“不幸的是,应用程序已停止”消息的 js 错误,因为它们不存在并且与 javascript 无关,而是与 Webview/plugin 相关。

如果您在 js 调用后看到这种消息,那么它来自 web 视图的 javascript 实现,也就是 Chrome 的一个或插件的本机部分。 Javascript 是沙盒化的,不应产生此类行为。

【讨论】:

    【解决方案9】:

    你可以尝试做一个无限循环,在应用启动时递增地附加一个字符串:

    onDeviceReady: function() {
        var test = "test";
        while (true) {
            test += "--------------------";
            console.log(test);
        }
    },
    

    这样就可以了。

    【讨论】:

    • 我已经试过了。这会使应用程序由于“内存不足错误”而崩溃。但在这种情况下,崩溃收集插件无法作为应用程序的一部分运行,并且没有更多内存可供应用程序执行。此外,“内存不足”是错误而不是例外。我希望我的应用程序由于异常(在 java 脚本级别)而崩溃,以便我可以测试我的崩溃报告收集代码。
    • 这将导致不想要的内存问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-14
    • 2023-01-27
    • 1970-01-01
    相关资源
    最近更新 更多