【问题标题】:App works on emulator, crashes on device应用程序在模拟器上运行,在设备上崩溃
【发布时间】:2014-08-04 13:35:47
【问题描述】:

我遇到了一个奇怪的问题。我正在编写应用程序,它使用来自 Web 的 XML。在模拟器上一切正常,但在手机上它崩溃(点击按钮后关闭,没有任何警报)。

代码如下:

using System;

using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using System.Xml;

namespace KursyWalut
{
 [Activity (Label = "KursyWalut", MainLauncher = true, Icon = "@drawable/icon")]
 public class MainActivity : Activity
 {
   protected override void OnCreate (Bundle bundle)
   {
     base.OnCreate (bundle);

        // Set our view from the "main" layout resource
        SetContentView (Resource.Layout.Popularne);

        // Get our button from the layout resource,
        // and attach an event to it
        Button button = FindViewById<Button> (Resource.Id.przycisk);
        TextView data = FindViewById<TextView> (Resource.Id.data);
        TextView kurs = FindViewById<TextView> (Resource.Id.kurs);
        RadioGroup radioGroup = FindViewById<RadioGroup> (Resource.Id.radioGroup);
        RadioButton dolar = FindViewById <RadioButton> (Resource.Id.rbDolar);
        RadioButton euro = FindViewById <RadioButton> (Resource.Id.rbEuro);
        RadioButton frank = FindViewById <RadioButton> (Resource.Id.rbFrank);
        int checkedRadioButton;

        XmlDocument dokument = new XmlDocument ();

        //  --------------------------------------------------------------------------
        button.Click += delegate {
            try{
                dokument.Load("http://nbp.pl/kursy/xml/LastA.xml");
            }
            catch(Exception ex){
                Toast.MakeText(this,"Brak połaczenia z Internetem!",ToastLength.Long);
            }
            data.Text = "Data: " + getDocumentDate(dokument);

            checkedRadioButton = radioGroup.CheckedRadioButtonId;
            switch(checkedRadioButton){

            case Resource.Id.rbDolar:
                kurs.Text = "Kurs USD: " + getRate(dokument,"USD");
                break;

            case Resource.Id.rbEuro:
                kurs.Text = "Kurs EUR: " + getRate(dokument,"EUR");
                break;

            case Resource.Id.rbFrank:
                kurs.Text = "Kurs CHF: " + getRate(dokument,"CHF");
                break;
            }
        };
    }
    String getDocumentDate(XmlDocument xml){
        return xml.SelectSingleNode("/tabela_kursow/data_publikacji").InnerText;
    }

    String getRate(XmlDocument xml, String currency){
        foreach (XmlNode xmlNode in xml.DocumentElement) {

            if (xmlNode.Name == "pozycja") {
                if (xmlNode.SelectSingleNode ("kod_waluty").InnerText == currency)
                    return xmlNode.SelectSingleNode ("kurs_sredni").InnerText;      
            }
        }
        return "Nie znaleziono kursu";
    }
  }
}

【问题讨论】:

  • 你是否在清单中设置了互联网权限?
  • 是的,它是在android manifest中设置的
  • 如果在Toast.MakeText(this,"Brak połaczenia z Internetem!",ToastLength.Long);处下断点,Exception ex是什么异常?

标签: android xamarin xamarin.android emulation device


【解决方案1】:

好吧,我想我找到了。您当前正在阅读按钮中的文档。单击。您应该尝试在后台线程中执行此操作。以 Task Parallel Library 为例:

        XmlDocument dokument = new XmlDocument ();

        Task task = Task.Factory.StartNew(() =>
        {
            try
            {
                dokument.Load("http://nbp.pl/kursy/xml/LastA.xml");
            }
            catch (Exception ex)
            {
                Toast.MakeText(this, "Brak połaczenia z Internetem!", ToastLength.Long);
            }
        });

【讨论】:

  • 不幸的是它不起作用。如果我像你的建议那样编码,我在方法 getRate() 中有 nullpointerexception。我真的不知道为什么它不起作用,在模拟器上它工作正常:(
  • 你在哪里接收到一个空指针? (什么对象是空的?)
  • 我在这样的一行 foreach 中收到异常警告(xml.DocumentElement 中的 XmlNode xmlNode)。我认为xml尚未加载,但主线程在某些方法中使用了它。我必须以某种方式同步这些线程吗?
  • xml.DocumentElement 是 XML 的根节点,它不是一个集合。也许您可以将自己读入XmlReader
【解决方案2】:

首先,如果dokument.Load() 中出现异常,它将通过catch 处理程序,并且您的代码将继续运行,即使文档未加载也是如此。您可能应该将您的 catch 处理程序更改为:

try
{
    // read xml into string
    var xml = new System.Net.WebClient()
        .DownloadString("http://nbp.pl/kursy/xml/LastA.xml");
    dokument.LoadXml(xml);
}
catch (Exception ex)
{
    Toast
        .MakeText(this, "Brak połaczenia z Internetem! " + ex, ToastLength.Long)
        .Show();
    return;
}

请注意,我在MakeText() 的末尾添加了.Show()。否则,您将看不到实际的 Toast。我还添加了实际的异常。

我感觉您在加载文档时遇到了异常。一旦你确定了原因,其余的应该更容易弄清楚。

【讨论】:

  • 感谢您的帮助。将您的代码放入我的代码后,我的屏幕上会收到 Toast 消息,然后会出现类似的消息。 System.XML.XmlException: Unexpected declaration markup was found... 后来在 Mono.Xml2.XmlTextReader.ReadDeclaration()[0x00000] 。问题是没有加载xml?如何解决这个问题,在程序开始时正确加载xml?
  • 听起来您获取的 XML 无效。只有在解析 LoadXml() 调用上放置一个断点,这样您就可以看到实际的xml 文本是什么样子的。 [1]github.com/mono/mono/blob/…
  • 顺便说一句:我通常不建议在事件处理程序中从 Web 下载内容。您可能应该使用 HttpClient 和 async/await 以提高响应速度。
猜你喜欢
  • 2021-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-02
相关资源
最近更新 更多