java—是否有其他解决方案具有CalledFromErrorThreadException?

q43xntqr  于 2021-07-13  发布在  Java
关注(0)|答案(1)|浏览(357)

这个问题在这里已经有答案了

android-viewrootimpl$CalledFromErrorThreadException(4个答案)
5年前关门了。
我尝试使用json和php从phpmyadmin获取数据。我用的是android工作室。我尝试使用progress dialog,然后windows泄漏(已经使用p.dialog.dismission())。之后,我有删除进度对话框,然后新的异常发生。有没有别的解决办法?
这是我的日志。

java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.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 android.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: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
            at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:5351)
            at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:970)
            at android.view.View.requestLayout(View.java:15722)
            at android.view.View.requestLayout(View.java:15722)
            at android.view.View.requestLayout(View.java:15722)
            at android.view.View.requestLayout(View.java:15722)
            at android.view.View.requestLayout(View.java:15722)
            at android.view.View.requestLayout(View.java:15722)
            at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:318)
            at android.view.View.requestLayout(View.java:15722)
            at android.widget.TextView.checkForRelayout(TextView.java:6605)
            at android.widget.TextView.setText(TextView.java:3804)
            at android.widget.TextView.setText(TextView.java:3662)
            at android.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 android.os.AsyncTask$2.call(AsyncTask.java:287)
            at java.util.concurrent.FutureTask.run(FutureTask.java:234)
            at android.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 android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.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();
           // }

        }

    }
}
omjgkv6w

omjgkv6w1#

这个错误清楚地告诉您不能在主线程之外访问视图层次结构。
原因:android.view.viewrootimpl$CalledFromErrorThreadException:只有创建视图层次结构的原始线程才能接触其视图。
因为您使用的是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"));
    }
});

相关问题