在线程中运行的 JsonReader 使应用程序崩溃

Posted

技术标签:

【中文标题】在线程中运行的 JsonReader 使应用程序崩溃【英文标题】:JsonReader running in thread crashes app 【发布时间】:2015-06-14 11:47:02 【问题描述】:

我的应用程序意外崩溃,我不明白为什么。我正在使用 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");

这将在主 UI 线程中创建的线程上运行。

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)

【问题讨论】:

崩溃信息是什么意思? logcat输出是你的意思吗?我已添加到原始问题中。 【参考方案1】:

我相信您来自 MainActivityoutput 方法会修改 TextView,因此会触发异常。

只能从“主”线程更改视图层次结构,在这种情况下,您可能想尝试查看 runOnUiThread,*** 上的一些资源:

how to use runOnUiThread Android runOnUiThread explanation Android Java runOnUiThread()

希望这会有所帮助,祝你好运:)

编辑:

您可能还想使用 android Log 而不是使用 TextView 来显示错误。

【讨论】:

以上是关于在线程中运行的 JsonReader 使应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

还在用 SimpleDateFormat 做时间格式化?小心项目崩掉!

还在用 SimpleDateFormat 做时间格式化?小心项目崩掉!

还在用 SimpleDateFormat 做时间格式化?小心项目崩掉!

从 JsonReader 读取 JObject 时出错。当前 JsonReader 项不是对象:StartArray。小路

使用 JsonReader 解析时 JsonArray 或 JsonObject 为空

如何使程序运行在UI线程