JsonReader, запущенный в потоке приложений, вылетает
Мое приложение непредсказуемо падает, и я не понимаю, почему. Я использую HttpURLConnection для получения файла JSON, и я пытаюсь использовать класс JsonReader для чтения и использования этого файла. Проблема в том, что приложение вылетает после чтения или выполнения каких-либо действий с экземпляром JsonReader.
Я прочитал поток ввода со сканера, но это вызывает аналогичную проблему. Однако при чтении со сканером я могу распечатать небольшое количество JSON с сервера. Таким образом, данные с сервера, вероятно, также попадают в JsonReader.
Это мой код:
public class ConnectToServer implements Runnable {
private URL connectionUrl;
private MainActivity output;
public ConnectToServer(URL url, MainActivity mainActivity) {
connectionUrl = url;
output = mainActivity;
}
public void printError(String errorMessage){
output.output(errorMessage);
}
public InputStream GetInputStream(){
try {
HttpURLConnection connection = (HttpURLConnection)connectionUrl.openConnection();
InputStream inputStream = new BufferedInputStream(connection.getInputStream());
if (inputStream == null){
printError("Input stream is null");
}
return inputStream;
} catch (IOException ex){
printError("IO exception has been thrown");
} catch (Exception ex){
printError("Normal exception thrown: " + ex.getClass().getSimpleName());
}
return null;
}
@Override
public void run() {
InputStream inputStream = GetInputStream();
try {
if (inputStream == null){
printError("Input stream not initiated");
} else {
JsonReader reader = new JsonReader(new InputStreamReader(inputStream, "UTF-8"));
printError(reader.toString());
reader.close();
}
} catch (Exception ex){
printError("Exception while printing input stream: " + ex.getClass().getSimpleName());
}
printError("Thread finished");
}
Это запускается в потоке, созданном в основном потоке пользовательского интерфейса.
public void connect(){
output("connect started");
boolean success = true;
try {
URL url = new URL("http://geonews.azurewebsites.net/api/Location");
serverConnection = new ConnectToServer(url,this);
Thread thread = new Thread(serverConnection);
thread.start();
} catch (MalformedURLException ex){
output("Messed up the URL");
success = false;
}
if (success){
output("Thread has been started");
} else {
output("exception was thrown while trying to run thread");
}
}
Кто-нибудь знает, почему этот код будет вызывать сбой моего приложения? Даже если он доходит до "Завершена нить", он вскоре потерпит крах.
Кстати, я понимаю, что должен использовать AsyncTask, но я уже пошел по этому пути, и я бы предпочел, чтобы это пошло первым.
Logcat:
06-14 22:45:00.058 4032-4052/com.tomsapps.thomas.jsonreadertestapp E/AndroidRuntime﹕ FATAL EXCEPTION: Thread-314
Process: com.tomsapps.thomas.jsonreadertestapp, PID: 4032
android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6247)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:867)
at android.view.View.requestLayout(View.java:17364)
at android.view.View.requestLayout(View.java:17364)
at android.view.View.requestLayout(View.java:17364)
at android.view.View.requestLayout(View.java:17364)
at android.view.View.requestLayout(View.java:17364)
at android.view.View.requestLayout(View.java:17364)
at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:360)
at android.view.View.requestLayout(View.java:17364)
at android.widget.TextView.checkForResize(TextView.java:6798)
at android.widget.TextView.updateAfterEdit(TextView.java:7693)
at android.widget.TextView.handleTextChanged(TextView.java:7709)
at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:9440)
at android.text.SpannableStringBuilder.sendTextChanged(SpannableStringBuilder.java:964)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:515)
at android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:272)
at android.text.SpannableStringBuilder.append(SpannableStringBuilder.java:33)
at android.widget.TextView.append(TextView.java:3616)
at android.widget.TextView.append(TextView.java:3603)
at com.tomsapps.thomas.jsonreadertestapp.MainActivity.output(MainActivity.java:63)
at com.tomsapps.thomas.jsonreadertestapp.ConnectToServer.printError(ConnectToServer.java:26)
at com.tomsapps.thomas.jsonreadertestapp.ConnectToServer.run(ConnectToServer.java:74)
at java.lang.Thread.run(Thread.java:818)
1 ответ
Я верю твоему output
метод из MainActivity
изменяет TextView, вызывая исключение.
Иерархия представления может быть изменена только из потока "Main", в этом случае вы можете попробовать runOnUiThread
некоторые ресурсы на Stackru:
Надеюсь это поможет. Удачи:)
Редактировать:
Вы также можете использовать Android Log
Вместо того, чтобы использовать TextView
отображать ошибки.