捕获的 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 块中,您的 exception 是 null
,您也会在那里找到有关您的异常的详细信息。
您可以轻松地从 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 或异常为空的主要内容,如果未能解决你的问题,请参考以下文章