捕获的 Throwable 或异常为空

Posted

技术标签:

【中文标题】捕获的 Throwable 或异常为空【英文标题】:Caught Throwable or Exception is null 【发布时间】:2012-02-12 11:31:08 【问题描述】:

类似的问题在这里被问了两次,从来没有任何答案。或者答案是:“不可能!”抱歉,可能太多了:

try
    ...
    // the line that causes the error
    LinearLayout cell = (LinearLayout) inflater.inflate(R.layout.channels_list_cell, column);
    ...

catch(Throwable e)
    Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show(); < breakpoint here!

在断点处,e 为空。请问我该如何寻找错误?很可能不是java或android的问题,而是Eclipse调试器的问题,它本身需要调试得很厉害。但是,除了更换到不同的 IDE 之外,我还能做什么?有任何想法吗?事先表示感谢。

我尝试过 Throwable、Exception、RuntimeException。结果是一样的。

尝试越过断点会导致 NullPointerException,因此,在那一刻,e 似乎真的为 null。它会丢失在哪里?

编辑: 我对每个人表示感谢,并对每个回答者 +1。这是一个 Eclipse 错误。重新启动 Eclipse 后,异常不再为空,它是一个正常的 RuntimeException:二进制 XML 文件第 15 行:您必须提供 layout_width 属性。这将是另一个需要解决的问题,但这个问题已经解决了。

【问题讨论】:

为什么要捕获 Throwable 而不是 Exception? 我试过 Throwable、Exception、RuntimeException。结果是一样的。 我自己从不使用调试器,但从我在其他人使用它时看到的情况来看,它为给定对象显示的内容似乎是在该对象上调用String.valueOf(...) 的结果。因此,如果捕获的异常的toString() 方法返回null'null',那么调试器可能会产生错误的印象,即捕获的异常本身就是null 收到异常时 LogCat 会说什么? 你确定吗?您是否知道异常为空,或者这是基于某些运行时因素的假设?如果将 toast 代码更改为简单的 Log.d("", e.getMessage()) 会怎样? 【参考方案1】:

如果您捕获的异常是 NullPointerException,getMessage() 方法会返回“null”,这可能会造成混淆。我知道这有时让我感到困惑!

在调试器中,您应该能够选择 e 并查看类型及其字段。另外,当事情变得非常混乱时,另一种调试方法是去

 e.printStackTrace();

(注意 - 我不是 Android 专家,所以如果这在 Android 上的工作方式有所不同,请评论!)

【讨论】:

老兄,他说e 为空。如果对象为空,如何访问方法printStackTrace()?? 这是一个有趣的想法。但是......当我看到某物的“检查”时,我看不到它的“toString”结果,而是带有值的实例的整个结构。在这里我看到了裸空,就像在未创建的对象上看到的那样。也许,Eclipse在这里犯了这样的错误,它就像你说的那样工作,我明天检查。 @Adel Boutros。他认为,该对象并不是真正的空,它只是由于调试器中的一些错误而将自己显示为空。他只是把那句话当作隐含的句子省略了。而且很有可能。至于具体的揭秘e的尝试,不好意思,我不上班,只能明天继续。 @Gangus 如果你看到了裸空,那么我的猜测是错误的。我从未见过 catch 子句捕获空值。也许Android是不同的?但是明天再检查一遍。 和我一样的问题。任何解决方案。裸空【参考方案2】:

您是否验证过e 实际上是否为空? IE。通过添加类似if (e == null) Log.d("Exception is null") 的内容。然后我会检查日志语句是否在正常执行期间和调试期间都被触发。如果两者之间的结果不同,则表明存在 VM 错误(不太可能,但可能)。如果在这两种情况下都没有触发消息,则可能是调试器问题。

关于您可以尝试调试问题的更多想法:

试试 jdb 之类的东西,看看你是否得到相同的行为

您可以获得调试器和设备之间的 jdwp 通信转储,并查看该级别发生了什么。也许使用 wireshark 或 tcpdump 并抓取通过 USB 总线传输到设备的数据。

您可以尝试向 dalvik 本身添加一些调试语句。例如。获取 AOSP 的副本并构建一个模拟器映像,然后向 dalvik 添加一些调试语句以尝试跟踪发生了什么。

您可以尝试与设备进行某种脚本化的 jdwp 会话

您可以查看字节码 (baksmali/dexdump/dedexer),看看是否有什么有趣的地方

【讨论】:

谢谢。有趣的是,我一直在努力打开断言,而更简单的方法(if..then)却没有引起我的注意。当我回来工作时,我会立即做。至于 jd 和 jdwp,wireshark 和 tcpdump,AOSP,对不起,我是第一次阅读它们。至于字节码,我可以阅读它,但是我不知道在哪里可以找到它的 java 以及那里写的内容以及它是如何写的。抱歉,这些建议的级别太高,对我没用。 对,我的大部分建议都需要对 android 平台有良好的工作知识。特别是最后一点,您可以在 apk 上运行 baksmali 以获取 dalvik 字节码。 真的,我不明白需要对技术如此深入的学习,因为 99% 的变体解决方案是重新启动或重新加载某些东西或更改使用的软件(因为有 其他错误)。它在 20 或 40 年前很有用,当时的描述适合 SW。 我不确定我理解你的意思。我只是想帮助您解决问题:) 我非常感谢它!我会保存你的 debudding 技术列表,以便稍后返回。 ---- 对于我们的艺术水平,这只是一个悲伤的想法。我们的工具变得越有问题,对更深层次的理解就越没有意义,我们越来越像一个菜鸟,他们只是尝试许多不同的工具,然后将它们从一个堆传递到另一个堆【参考方案3】:

Android 并不总是在 Throwable 中引发异常。它实际上驱动了catLog 的所有异常。即使在 catch 块中,您的 exceptionnull,您也会在那里找到有关您的异常的详细信息。

您可以轻松地从 eclipse 访问 catlog 控制台并过滤以仅查看错误

更新:

你的断点应该在 catch 块内

【讨论】:

logcat 没有捕捉到它。 (过滤器关闭,在导致错误的行之前清理日志) 在导致异常的行之前有很多。我一步一步走。而且我必须在吐司线上休息一下 - 否则那里会有未捕获的错误 nullPointer。 另一个重要的。抱歉,我刚才已经在上面签名了。 Android 不会隐式记录异常。例如,如果你捕获一个异常并吃掉它(不要打印它,不要重新抛出它),那么 logcat 将不会打印任何内容。 (catLog?嗯?) @JesusFreke catLog 比 logcat 好听【参考方案4】:

我知道这个问题是不久前发布的,而且很多次!我昨天陷入了这个陷阱,我想我会发布我发现的内容。

问题定义:我使用了以下代码

public class myAppActivity extends Activity

   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState)
   
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
      try  -- lots of code -- 
      catch (Exception ex) 
          Log.e ("eTutorPrism Error", "Caught this exception " + ex);
          ex.printStackTrace();
      
   


Symptom was that 'ex' was always null and resume will give NullPointerException, although the actual exception was an IllegalArgumentException in a call made into another class from the code above.

问题:onCreate() 代码不显示捕获的异常。相反,它显示异常 = null。

解决方案:不要在 onCreate() 中使用过多的处理。尽可能多地移动到另一个线程。所以我将代码更改为如下所示。瞧,它的工作原理!我可以看到 Logcat 中显示的实际异常。

public class eTutorPrismAppActivity extends Activity

   /** Called when the activity is first created. */
   @Override
   public void onCreate(Bundle savedInstanceState)
   
       super.onCreate(savedInstanceState);
       setContentView(R.layout.main);

       eTutorPrismTest myTest = new eTutorPrismTest (getApplicationContext());
       myTest.start();
   


class eTutorPrismTest extends Thread

   private Context m_AppContext = null;

   public eTutorPrismTest (Context appContext)
   
      m_AppContext = appContext;
   

   public void run ()
      
      -- lots of code that needs appContext --
   

【讨论】:

【参考方案5】:

我不确定是什么原因造成的——如前所述,它可能是一个 Eclipse 错误。不管是什么原因,我确实找到了一种似乎可行的解决方法。我希望它对其他人也有用。

异常被捕获后,赋值给另一个变量。分配的变量应该在调试器中包含正确的异常。

SpecificException assignedVar = null;
try 
    ...

catch (SpecificException exc) 
    assignedVar = exc; // <-- exc comes up null in the debugger, but assignedVar will be the correct object.

希望这对其他人有用。

【讨论】:

以上是关于捕获的 Throwable 或异常为空的主要内容,如果未能解决你的问题,请参考以下文章

异常处理规范

lang——Throwable子类

java异常级别与捕获

无法调用“java.lang.Throwable.getStackTrace()”,因为“异常”为空

异常的处理

错误处理