有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java有没有其他名为FromErrorThreadException的解决方案?

我正在尝试使用JSON和php从phpMyAdmin获取数据。我正在使用Android Studio。我试图使用Progress Dialog,但windows泄露了(已经使用p.Dialog.discouse())。之后,我会删除进度对话框,然后出现新的异常。有没有其他解决办法

这是我的logcat

 java.lang.RuntimeException: An error occured while executing doInBackground()
            at 安卓.os.AsyncTask$3.done(AsyncTask.java:299)
            at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
            at java.util.concurrent.FutureTask.run(FutureTask.java:239)
            at 安卓.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
            at java.lang.Thread.run(Thread.java:838)
     Caused by: 安卓.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
            at 安卓.view.ViewRootImpl.checkThread(ViewRootImpl.java:5351)
            at 安卓.view.ViewRootImpl.requestLayout(ViewRootImpl.java:970)
            at 安卓.view.View.requestLayout(View.java:15722)
            at 安卓.view.View.requestLayout(View.java:15722)
            at 安卓.view.View.requestLayout(View.java:15722)
            at 安卓.view.View.requestLayout(View.java:15722)
            at 安卓.view.View.requestLayout(View.java:15722)
            at 安卓.view.View.requestLayout(View.java:15722)
            at 安卓.widget.RelativeLayout.requestLayout(RelativeLayout.java:318)
            at 安卓.view.View.requestLayout(View.java:15722)
            at 安卓.widget.TextView.checkForRelayout(TextView.java:6605)
            at 安卓.widget.TextView.setText(TextView.java:3804)
            at 安卓.widget.TextView.setText(TextView.java:3662)
            at 安卓.widget.TextView.setText(TextView.java:3637)
            at com.example.ayim.madoc.docProfile$DocProfile.doInBackground(docProfile.java:113)
            at com.example.ayim.madoc.docProfile$DocProfile.doInBackground(docProfile.java:67)
            at 安卓.os.AsyncTask$2.call(AsyncTask.java:287)
            at java.util.concurrent.FutureTask.run(FutureTask.java:234)
            at 安卓.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
            at java.lang.Thread.run(Thread.java:838) 

这是我写的代码

package com.example.ayim.madoc;

import 安卓.app.ProgressDialog;
import 安卓.content.Intent;
import 安卓.os.AsyncTask;
import 安卓.support.v7.app.ActionBarActivity;
import 安卓.os.Bundle;
import 安卓.util.Log;
import 安卓.widget.TextView;
import 安卓.widget.Toast;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;


public class docProfile extends ActionBarActivity {

    TextView nameDoc;
    TextView iddoc;
    TextView icdoc;
    TextView adddoc;
    TextView notel;

    private ProgressDialog pDialog;

    //JSONArray docprofile = null;

    JSONParser jsonParser = new JSONParser();

    private static final String LOGIN_URL = "http://104.223.3.210/madoc/docprofile.php";

    //JSON element ids from repsonse of php script:
    private static final String TAG_SUCCESS = "success";
    private static final String TAG_MESSAGE = "message";
    private static final String TAG_DOCTOR = "doctor";
    private static final String TAG_ID = "id";
    private static final String TAG_NAME = "name";
    private static final String TAG_IC = "ic";
    private static final String TAG_ADDRESS = "address";
    private static final String TAG_NOTEL = "notel";
    //String iddoctor;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_doc_profile);


       // Intent i = getIntent();

        //iddoctor = i.getStringExtra("idDoc");

        new DocProfile().execute();

        //nameDoc = (TextView) findViewById(R.id.docId);
        //nameDoc.setText(getIntent().getExtras().getString("idDoc"));


    }


    class DocProfile extends AsyncTask<String, String, String> {


/*
        @Override
        protected void onPreExecute() {

            super.onPreExecute();
            pDialog = new ProgressDialog(docProfile.this);
            pDialog.setMessage("Loading Profile. Please wait....");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(true);
            pDialog.show();
        }
*/

        @Override
        protected String doInBackground(String... params) {


            String idd = getIntent().getExtras().getString("idDoc");

                    int success;
                    try {

                        List<NameValuePair> param = new ArrayList<NameValuePair>();
                        param.add(new BasicNameValuePair("id",idd));

                        JSONObject json = jsonParser.makeHttpRequest(LOGIN_URL, "GET", param);

                        Log.d("Doctor Profile", json.toString());

                        success = json.getInt(TAG_SUCCESS);

                        if (success == 1) {

                            JSONArray docProfile = json.getJSONArray(TAG_DOCTOR);

                            JSONObject docProf = docProfile.getJSONObject(0);

                            nameDoc = (TextView) findViewById(R.id.name);
                            iddoc = (TextView) findViewById(R.id.docId);
                            icdoc = (TextView) findViewById(R.id.icdoctor);
                            adddoc = (TextView) findViewById(R.id.addressdoc);
                            notel = (TextView) findViewById(R.id.noteldoc);

                            nameDoc.setText(docProf.getString("name"));
                            iddoc.setText(docProf.getString("id"));
                            icdoc.setText(docProf.getString("ic"));
                            adddoc.setText(docProf.getString("address"));
                            notel.setText(docProf.getString("noTel"));

                        } else {
                            //no doctor
                        }

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




            return null;
        }

        protected void onPostExecute(String file_url) {
            // dismiss the dialog once product deleted
            pDialog.dismiss();
            //if (file_url != null){
              //  Toast.makeText(docProfile.this, file_url, Toast.LENGTH_LONG).show();
           // }

        }


    }
}

共 (1) 个答案

  1. # 1 楼答案

    该错误清楚地告诉您,不能在主线程之外访问视图层次结构

    Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

    由于您使用的是AsyncTask,因此最好在onPostExecute中更新UI元素。此方法将在主线程上运行。您可以将docProf传递到onPostExecute,并在那里进行更改

    protected void onPostExecute(String file_url) {
        nameDoc = (TextView) findViewById(R.id.name);
        iddoc = (TextView) findViewById(R.id.docId);
        icdoc = (TextView) findViewById(R.id.icdoctor);
        adddoc = (TextView) findViewById(R.id.addressdoc);
        notel = (TextView) findViewById(R.id.noteldoc);
    
        nameDoc.setText(docProf.getString("name"));
        iddoc.setText(docProf.getString("id"));
        icdoc.setText(docProf.getString("ic"));
        adddoc.setText(docProf.getString("address"));
        notel.setText(docProf.getString("noTel"));
    
        pDialog.dismiss();
    }
    

    要将数据发送到onPostExecute,需要进行三项更改:

    1:

    class DocProfile extends AsyncTask<String, String, String> {
    

    变成

    class DocProfile extends AsyncTask<String, String, JSONObject> {
    

    二,

    if (success == 1) {
    

    变成

    if (success == 1) return docProf;
    

    三,

    protected void onPostExecute(String file_url) {
    

    变成

    protected void onPostExecute(JSONObject docProf) {
    

    现在可以在onPostExecute中使用docProf

    或者,该区块中的所有内容:

    if (success == 1) {
    

    。。。需要在UI线程上运行

    例如:

    (new Handler(Looper.getMainLooper()).post(new Runnable() {
        public void run() {
            nameDoc = (TextView) findViewById(R.id.name);
            iddoc = (TextView) findViewById(R.id.docId);
            icdoc = (TextView) findViewById(R.id.icdoctor);
            adddoc = (TextView) findViewById(R.id.addressdoc);
            notel = (TextView) findViewById(R.id.noteldoc);
    
            nameDoc.setText(docProf.getString("name"));
            iddoc.setText(docProf.getString("id"));
            icdoc.setText(docProf.getString("ic"));
            adddoc.setText(docProf.getString("address"));
            notel.setText(docProf.getString("noTel"));
        }
    });