0

我试图在后台解析 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();
            }
        }
    }
}

我坚持这一点,如果错误很愚蠢,我很抱歉,因为我对此真的很陌生。

提前感谢您的帮助。

4

3 回答 3

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...
于 2012-06-29T05:27:56.663 回答
1

你可以做的是:

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

我已将您的代码更新如下。

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();
            }
        }
    }
}
于 2012-06-29T06:07:40.463 回答
0

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

tv.setText(e.getMessage());

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

于 2012-06-29T05:58:08.337 回答