在异步任务中解析JSON时强制关闭

时间:2012-06-29 05:26:46

标签: android json parsing android-asynctask

我正在尝试显示进度对话框,而json正在后台解析(使用异步任务),但每当我尝试时,我得到强制关闭,只要我使用它而没有异步任务,json就能正常工作。

以下是我的代码:

package com.Parsing.SOAPParsing;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import org.json.JSONArray;
import org.json.JSONObject;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    private static final String SOAP_ACTION = "http://tempuri.org/testService";
    private static final String METHOD_NAME = "testService";
    private static final String NAMESPACE = "http://tempuri.org/";
    private static final String URL = "http://testService/webservice.asmx";

    TextView tv, optionA, optionB, optionC, optionD, optionE;
    ArrayList<HashMap<String, String>> testList = new ArrayList<HashMap<String, String>>();

    private String result;

    int j = 0;
    int k;
    String questions[] = new String[12];

    String opA[] = new String[12];
    String opB[] = new String[12];
    String opC[] = new String[12];
    String opD[] = new String[12];
    String opE[] = new String[12];

    ListView list;
    Button next;
    Button previous;
    int i;
    String v;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        tv = (TextView) findViewById(R.id.questions);

        Fetch fetch = new Fetch(); // Calling async task
        fetch.execute();

    }

    public class Fetch extends AsyncTask<String, Void, Void> {

        private ProgressDialog dialog = new ProgressDialog(MainActivity.this);

        @Override
        public void onPreExecute() {
            this.dialog
                    .setMessage("Loading database. Please wait..."
                            + "\n\n\n\n This will will only load for once when you install the application");
            this.dialog.show();
        }

        @Override
        public Void doInBackground(String... params) {
            for (k = 1; k <= 10; k++) {
                try {

                    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
                    request.addProperty("QuestionId", Long.valueOf(k));

                    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                            SoapEnvelope.VER11);
                    envelope.dotNet = true;
                    envelope.setOutputSoapObject(request);

                    HttpTransportSE androidHttpTransport = new HttpTransportSE(
                            URL);

                    androidHttpTransport.call(SOAP_ACTION, envelope);
                    SoapPrimitive response = (SoapPrimitive) envelope
                            .getResponse();
                    result = response.toString();

                    try {
                        JSONObject o = new JSONObject(result);
                        Iterator<String> it = o.keys();

                        while (it.hasNext()) {
                            JSONArray ja = o.optJSONArray(it.next());
                            if (ja != null) {

                                for (i = 0; i <= ja.length(); i++) {
                                    String v = ja.get(i).toString();
                                    Log.i("value", i + " = " + v);

                                    if (i == 0) {
                                        opA[k - 1] = v;
                                    }

                                    if (i == 1) {
                                        opB[k - 1] = v;
                                    }
                                    if (i == 2) {
                                        opC[k - 1] = v;
                                    }
                                    if (i == 3) {
                                        opD[k - 1] = v;
                                    }
                                    if (i == 4) {
                                        opE[k - 1] = v;
                                    }

                                    if (i == 7) {

                                        questions[k - 1] = v;

                                    }
                                }
                            }

                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                } catch (Exception e) {
                    tv.setText(e.getMessage());
                }
            }
            return null;
        }

        public void onPostExecute(final Void unsed) {
            if (this.dialog.isShowing()) {
                this.dialog.dismiss();
                Toast.makeText(MainActivity.this, opB[k], Toast.LENGTH_LONG)
                        .show();
            }
        }
    }
}

我坚持这一点,抱歉,如果错误是愚蠢的,因为我真的很新。

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

因为您正在从doInBackground

访问UI元素
 @Override
   public Void doInBackground(String... params) {
  //YOUR CODE....
     } catch (Exception e) {

      tv.setText(e.getMessage()); //HERE YOU ARE ACCESSING TEXTVIEW FROM doInBackground

      }
//YOUR CODE...

答案 1 :(得分:1)

你能做的是:

  • 将Asynctask的返回类型更改为String
  • 从doInBackground方法返回必要的字符串
  • 在onPostExecute方法
  • 中将此字符串更新为textview

我已更新您的代码,如下所示。

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import org.json.JSONArray;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import com.qualstream.telfaz.R;

public class MainActivity extends Activity {

    private static final String SOAP_ACTION = "http://tempuri.org/LoadQuestionDetail";
    private static final String METHOD_NAME = "LoadQuestionDetail";
    private static final String NAMESPACE = "http://tempuri.org/";
    private static final String URL = "http://www.beyyondcareers.com/webservice.asmx";

    TextView tv, optionA, optionB, optionC, optionD, optionE;
    ArrayList<HashMap<String, String>> testList = new ArrayList<HashMap<String, String>>();

    private String result;

    int j = 0;
    int k;
    String questions[] = new String[12];

    String opA[] = new String[12];
    String opB[] = new String[12];
    String opC[] = new String[12];
    String opD[] = new String[12];
    String opE[] = new String[12];

    ListView list;
    Button next;
    Button previous;
    int i;
    String v;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.test);

        tv = (TextView) findViewById(R.id.textview123);

        Fetch fetch = new Fetch(); // Calling async task
        fetch.execute();

    }

    public class Fetch extends AsyncTask<Void, Void, String> {

        private ProgressDialog dialog = new ProgressDialog(MainActivity.this);

        @Override
        public void onPreExecute() {
            this.dialog
                    .setMessage("Loading database. Please wait..."
                            + "\n\n\n\n This will will only load for once when you install the application");
            this.dialog.show();
        }

        @Override
        public String doInBackground(Void... params) {
            for (k = 1; k <= 10; k++) {
                try {

                    SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
                    request.addProperty("QuestionId", Long.valueOf(k));

                    SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(
                            SoapEnvelope.VER11);
                    envelope.dotNet = true;
                    envelope.setOutputSoapObject(request);

                    HttpTransportSE androidHttpTransport = new HttpTransportSE(
                            URL);

                    androidHttpTransport.call(SOAP_ACTION, envelope);
                    SoapPrimitive response = (SoapPrimitive) envelope
                            .getResponse();
                    result = response.toString();

                    try {
                        JSONObject o = new JSONObject(result);
                        Iterator<String> it = o.keys();

                        while (it.hasNext()) {
                            JSONArray ja = o.optJSONArray(it.next());
                            if (ja != null) {

                                for (i = 0; i <= ja.length(); i++) {
                                    String v = ja.get(i).toString();
                                    Log.i("value", i + " = " + v);

                                    if (i == 0) {
                                        opA[k - 1] = v;
                                    }

                                    if (i == 1) {
                                        opB[k - 1] = v;
                                    }
                                    if (i == 2) {
                                        opC[k - 1] = v;
                                    }
                                    if (i == 3) {
                                        opD[k - 1] = v;
                                    }
                                    if (i == 4) {
                                        opE[k - 1] = v;
                                    }

                                    if (i == 7) {

                                        questions[k - 1] = v;

                                    }
                                }
                            }

                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                } catch (Exception e) {
                    return e.getMessage();
                }
            }
            return "";
        }

        @Override
        public void onPostExecute(String result) {
            if (this.dialog.isShowing()) {
                this.dialog.dismiss();
                tv.setText(result);
                Toast.makeText(MainActivity.this, opB[k], Toast.LENGTH_LONG)
                        .show();
            }
        }
    }
}

答案 2 :(得分:0)

您无法从 doInBackground 方法访问UI元素, tv 变量是UI元素。

tv.setText(e.getMessage());

相反,您可以使用onProgressUpdate method来访问UI元素。如果您在doInBackground中调用publishProgress,则会自动调用 onProgressUpdate 方法。