#android #exception #dialog #crash
#Android #исключение #диалоговое окно #сбой
Вопрос:
Я хочу перехватить исключение, когда мой XML не анализируется. Поскольку я не имею никакого влияния на создаваемый XML, я не хочу перехватывать исключения, когда что-то идет не так (например, неправильные теги, странные знаки и так далее).
Я создал следующий код, но это приводит к сбою. Я добавил LogCat в код. Я не совсем понимаю, что мне говорит LogCat… У кого-нибудь есть подсказка, чтобы мне помочь? Спасибо
private void getVacatures(){
functie = getIntent().getIntExtra("Functie", 0);
stat =getIntent().getIntExtra("Statuut", 0);
regio = getIntent().getIntExtra("Straal", 0);
opl = getIntent().getIntExtra("Opleiding", 0);
final AlertDialog.Builder builder = new AlertDialog.Builder(JobList.this);
try {
Log.e("in try", "try");
/* Create a URL we want to load some xml-data from. */
URL url = new URL("C:/Users/hannelore.deblau/Desktop/TESTXML.xml");
System.out.println("URL: " url);
/* Get a SAXParser from the SAXPArserFactory. */
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
/* Get the XMLReader of the SAXParser we created. */
XMLReader xr = sp.getXMLReader();
/* Create a new ContentHandler and apply it to the XML-Reader*/
vacatureWebservice vs = new vacatureWebservice();
xr.setContentHandler(vs);
/* Parse the xml-data from our URL. */
xr.parse(new InputSource(url.openStream()));
/* Parsing has finished. */
/* Our ExampleHandler now provides the parsed data to us. */
arrVacatures = vs.getVacatures();
} catch (Exception e) {
builder.setTitle(R.string.Fouttitel);
builder.setMessage(R.string.XMLfout);
builder.setCancelable(false);
builder.setPositiveButton(R.string.Ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
});
builder.create().show();
}
//runOnUiThread(returnRes);
}
В onCreate () я делаю это:
Handler handler = new Handler(); // This code is in the main UI activity class
handler.post(runnable= new Runnable(){
public void run(){
getVacatures();
runOnUiThread(returnRes);
}
});
Thread thread = new Thread(null, runnable, "MagentoBackground");
thread.start();
LogCat с ошибкой:http://pastebin.com/X5uk9cex
Ответ №1:
Вы пытаетесь обновить пользовательский интерфейс из вызываемого рабочего потока MagentoBackground
. Вам нужно выполнять работу с пользовательским интерфейсом из основного потока. Попробуйте использовать Handler
.
Вот несколько руководств для Handler
Снова в вашем используется URL, подобный
URL url = new URL("C:/Users/hannelore.deblau/Desktop/TESTXML.xml");
Это URL
никогда не будет вызвано.Что вам нужно сделать, это сохранить ваш xml на веб-сервере, а затем получить к нему доступ.
Отредактировал ваш onCreate
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.your_view);
runnable= new Runnable() {
public void run() {
// Your code
try{ /* Create a URL we want to load some xml-data from. */
URL url = new URL("C:/Users/hannelore.deblau/Desktop/TESTXML.xml");
System.out.println("URL: " url);
/* Get a SAXParser from the SAXPArserFactory. */
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
/* Get the XMLReader of the SAXParser we created. */
XMLReader xr = sp.getXMLReader();
/* Create a new ContentHandler and apply it to the XML-Reader*/
vacatureWebservice vs = new vacatureWebservice();
xr.setContentHandler(vs);
/* Parse the xml-data from our URL. */
xr.parse(new InputSource(url.openStream()));
/* Parsing has finished. */
/* Our ExampleHandler now provides the parsed data to us. */
arrVacatures = vs.getVacatures();
runOnUiThread(returnRes);
}
catch(Exception e)
{
//here error comes
//here also you need to use this code
runOnUiThread(nullRes);
}
}
};
Thread thread = new Thread(null, runnable, "MagentoBackground");
thread.start();
}
Теперь вот ваш код исключения
private Runnable nullRes= new Runnable() {
public void run() {
final AlertDialog.Builder builder = new AlertDialog.Builder(JobList.this);
builder.setTitle(R.string.Fouttitel);
builder.setMessage(R.string.XMLfout);
builder.setCancelable(false);
builder.setPositiveButton(R.string.Ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
finish();
}
});
builder.create().show();
}
};
Комментарии:
1. Что касается URL-адреса, я знаю, это только для целей тестирования, потому что моя исходная ссылка работает. Тем не менее, я не могу предсказать, будет ли когда-либо неправильный XML. Вот почему я не хочу это перехватывать.
2. Добавлено
onCreate()
.. Возможно, существует проблема с форматом, связанная со скобками ({ }).
Ответ №2:
RuntimeException не является подклассом Exception, поэтому ваше предложение catch не будет перехватывать его. Вы могли бы изменить свое предложение catch на catch Throwable, которое является общим суперклассом. Это, по крайней мере, решило бы проблему, связанную с тем, что ваш код не обрабатывает это. Вероятно, существуют и другие проблемы, связанные с причиной исключения.
Исключение генерируется, потому что нет обработчика / зацикливателя для использования диалогового окна. Вам нужен код диалога для запуска в потоке пользовательского интерфейса.
Комментарии:
1. Однако, если я выполняю отладку, она повторяет код диалогового окна, но не отображается. это также связано с тем, что Exception не является подклассом RuntimException? Изменение Exception на Throwable приводит к тому же сбою.
2. На самом деле, глядя еще раз, я сомневаюсь, что исключение даже генерируется в вашем блоке try. Проблема в том, что код диалога не запускается в потоке пользовательского интерфейса.
Ответ №3:
Я предполагаю, что вы используете AndEngine или что-то в этом роде, и этот подраздел вызывается из подпотока вместо основного действия. Вот почему вы получаете эту ошибку:
java.lang.RuntimeException: не удается создать обработчик внутри потока, который не вызывал Looper.prepare()
Попробуйте вызвать этот sub вне любого потока (возможно, UIThread или UpdateThread). Или, если вам НУЖНО вызвать его в этом потоке, вызовите обработчик по основному действию и опубликуйте его:
Handler handler = new Handler(); // This code is in the main UI activity class
И когда вы хотите его вызвать:
handler.post(new Runnable() {
getVacatures();
});
Комментарии:
1. Я вызвал это,
onCreate
используя этот метод:runnable= new Runnable(){ public void run(){ getVacatures(); runOnUiThread(returnRes); } };
я не знаю, как объединить эти два вместе?2. @Hannelore: Это странно! Если вы вызываете его из onCreate, мне интересно, почему было сгенерировано это исключение. Вы пробовали тот, который я написал? Используя обработчик? И из какого именно класса метода onCreate вы вызываете?
3. Я добавил свой onCreate-code с обработчиком, он по-прежнему вызывает тот же сбой… Я вызываю метод onCreate в Activity, который расширяет ListActivity
4. @Hannelore Итак, из какого класса вы это вызываете? Наследуется ли это из контекста?
5. onCreate находится внутри класса Activity, под onCreate у меня есть ArrayAdapterClass.