有没有CalledFromWrongThreadException的其他解决方案?

时间:2015-04-28 13:52:58

标签: java android multithreading android-asynctask

我正在尝试使用带有PHP的JSON从phpMyAdmin获取数据。我正在使用Android Studio。我试图使用Progress Dialog,然后windows泄露(已经使用p.Dialog.dismiss())。之后,我删除了Progress Dialog,然后发生了新的异常。还有其他解决方案来解决这个问题吗?

这是我的logcat。

 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();
           // }

        }


    }
}

1 个答案:

答案 0 :(得分:0)

该错误清楚地告诉您,您无法访问主线程之外的View层次结构。

  

引起:android.view.ViewRootImpl $ CalledFromWrongThreadException:   只有创建视图层次结构的原始线程才能触及它   视图。

由于您使用的是AsyncTask,因此最好更新onPostExecute中的UI元素。此方法将在主线程上运行。您可以将Snackbar .make(((ActMedicalRecordDetailNew)getActivity()).getMainContent(), R.string.snackBarNoNetConnectivity, Snackbar.LENGTH_LONG) .setAction(R.string.snackBarTryAgain, new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = getActivity().getIntent(); getActivity().finish(); startActivity(intent); } }) .show(); 传递给onPostExecute并在那里进行更改。

docProf

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

1:

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();
}

...变为

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

2

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

...变为

if (success == 1) {

3

if (success == 1) return docProf;

...变为

protected void onPostExecute(String file_url) {

您现在可以在onPostExecute中使用docProf。

或者,此块中的所有内容:

protected void onPostExecute(JSONObject docProf) {

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

示例:

if (success == 1) {