简体   繁体   English

Android JSON解析崩溃的应用程序AsyncTask

[英]Android JSON Parsing Crashing Application AsyncTask

I am using a JSON parser to read the data from my JSON file and display it within my app, I was originally using this code to create arrays which works fine but now I have pasted it into a new application to make it get data from the JSON and put it onto a text field which isn't working. 我正在使用JSON解析器从JSON文件读取数据并将其显示在我的应用程序中,我最初是使用此代码来创建可以正常工作的数组,但现在我将其粘贴到新的应用程序中以使其从JSON并将其放在无法正常工作的文本字段中。 I will post the code and error log below. 我将在下面发布代码和错误日志。

package com.example.curtisboylan.myapplication;

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

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



public class TechnicianProfile extends AppCompatActivity {

    private static String url;
    private String TAG = SearchScreen.class.getSimpleName();
    private ProgressDialog pDialog;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_technician_profile);
        Bundle bundle = getIntent().getExtras();
        String username = bundle.getString("username");
        String userid = bundle.getString("userid");

        setTitle("Technician - " + username);
        url = "http://curtisboylan.me/mygeek/mygeekprofile.php?user=" + userid;

        Log.d("test", url);

        new GetProfile().execute();

    }
    private class GetProfile extends AsyncTask<Void, Void, Void> {

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            // Showing progress dialog
            pDialog = new ProgressDialog(TechnicianProfile.this);
            pDialog.setMessage("Please Wait..");
            pDialog.setCancelable(false);
            pDialog.show();

        }

        @Override
        protected Void doInBackground(Void... arg0) {
            HttpHandler sh = new HttpHandler();

            // Making a request to url and getting response
            String jsonStr = sh.makeServiceCall(url);

            Log.e(TAG, "Response from url: " + jsonStr);

            if (jsonStr != null) {
                try {
                    JSONObject jsonObj = new JSONObject(jsonStr);

                    // Getting JSON Array node
                    JSONArray contacts = jsonObj.getJSONArray("MyGeek");
                    TextView usernametext;
                    // looping through All Contacts

                        JSONObject c = contacts.getJSONObject(0);
                        usernametext = (TextView) TechnicianProfile.this.findViewById(R.id.abouttext);
                        usernametext.setText(c.getString("name"));
                        // username.add(c.getString("name"));
                        // userid.add(c.getString("id"));
                        // location.add(c.getString("location"));
                        // reviewscore.add(c.getString("reviewscore"));
                        //  price.add(c.getString("price"));
                        // urllist.add(c.getString("url"));




                } catch (final JSONException e) {
                    Log.e(TAG, "Json parsing error: " + e.getMessage());
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(),
                                    "Json parsing error: " + e.getMessage(),
                                    Toast.LENGTH_LONG)
                                    .show();
                        }
                    });

                }
            } else {
                Log.e(TAG, "Couldn't get json from server.");
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(),
                                "Couldn't get json from server. Check LogCat for possible errors!",
                                Toast.LENGTH_LONG)
                                .show();
                    }
                });

            }

            return null;
        }
    }
}

D/test: http://curtisboylan.me/mygeek/mygeekprofile.php?user=1 E/EGL_emulation: tid 2593: eglSurfaceAttrib(1174): error 0x3009 (EGL_BAD_MATCH) W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0x91199f00, error=EGL_BAD_MATCH E/EGL_emulation: tid 2593: eglSurfaceAttrib(1174): error 0x3009 (EGL_BAD_MATCH) W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0x8f2f5000, error=EGL_BAD_MATCH E/SearchScreen: Response from url: {"MyGeek":[{"id":"1","name":"Curtis Boylan","location":"Swords, Co Dublin","reviewscore":"5.6","url":"https://scontent-lhr3-1.xx.fbcdn.net/v/t1.0-9/11062691_831452480236559_1123476984274233173_n.jpg?oh=8eb4bb9519a2cd3b96b085146b0ae718&oe=596BBB5F","price":"30"}]} D /测试: http ://curtisboylan.me/mygeek/mygeekprofile.php?user=1 E / EGL_emulation:tid 2593:eglSurfaceAttrib(1174):error 0x3009(EGL_BAD_MATCH)W / OpenGLRenderer:无法在表面0x91199f00上设置EGL_SWAP_BEHAVIOR错误= EGL_BAD_MATCH E / EGL_仿真:tid 2593:eglSurfaceAttrib(1174):错误0x3009(EGL_BAD_MATCH)W / OpenGLRenderer:无法在表面0x8f2f5000上设置EGL_SWAP_BEHAVIOR,错误= EGL_BAD_MATCH {我从“:” “ id”:“ 1”,“ name”:“ Curtis Boylan”,“ location”:“ Swords,Co Dublin”,“ reviewscore”:“ 5.6”,“ url”:“ https:// scontent-lhr3-1 .xx.fbcdn.net / v / t1.0-9 / 11062691_831452480236559_1123476984274233173_n.jpg?oh = 8eb4bb9519a2cd3b96b085146b0ae718&oe = 596BBB5F“,”价格“:” 30“}]}

  --------- beginning of crash E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #2 Process: com.example.curtisboylan.myapplication, PID: 2416 java.lang.RuntimeException: An error occurred while executing doInBackground() at android.os.AsyncTask$3.done(AsyncTask.java:325) at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354) at java.util.concurrent.FutureTask.setException(FutureTask.java:223) at java.util.concurrent.FutureTask.run(FutureTask.java:242) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) at java.lang.Thread.run(Thread.java:761) 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:6891) at android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1083) at android.view.ViewGroup.invalidateChild(ViewGroup.java:5205) at android.view.View.invalidateInternal(View.java:13656) at android.view.View.invalidate(View.java:13620) at android.view.View.invalidate(View.java:13604) at android.widget.TextView.checkForRelayout(TextView.java:7347) at android.widget.TextView.setText(TextView.java:4480) at android.widget.TextView.setText(TextView.java:4337) at android.widget.TextView.setText(TextView.java:4312) at com.example.curtisboylan.myapplication.TechnicianProfile$GetProfile.doInBackground(TechnicianProfile.java:72) at com.example.curtisboylan.myapplication.TechnicianProfile$GetProfile.doInBackground(TechnicianProfile.java:39) at android.os.AsyncTask$2.call(AsyncTask.java:305) at java.util.concurrent.FutureTask.run(FutureTask.java:237) at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) at java. 在android.view.ViewGroup.invalidateChild(ViewGroup.java:5205)在android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1083)在android.view.ViewRootImpl.checkThread(ViewRootImpl.java:1083)处。 android.view.View.invalidate(View.java:13620)的android.view.View.invalidate(View.java:13604)的android.widget.TextView.checkForRelayout(TextView的View.invalidateInternal(View.java:13656) .java:7347),位于android.widget.TextView.setText(TextView.java:4480),位于android.widget.TextView.setText(TextView.java:4337),位于android.widget.TextView.setText(TextView.java:4312)在com.example.curtisboylan.myapplication.TechnicianProfile $ GetProfile.doInBackground(TechnicianProfile.java:72)处com.example.curtisboylanlan.myapplication.TechnicianProfile $ GetProfile.doInBackground(TechnicianProfile.java:39)在android.os.AsyncTask $ 2处。在java.util.concurrent.FutureTask.run(FutureTask.java:237)处调用android.os.AsyncTask $ SerialExecutor $ 1.run(AsyncTask.java:243)处的调用(AsyncTask.java:305)。 util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) at java.lang.Thread.run(Thread.java:761) E/EGL_emulation: tid 2593: eglSurfaceAttrib(1174): error 0x3009 (EGL_BAD_MATCH) W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0x8f2f5080, error=EGL_BAD_MATCH E/WindowManager: android.view.WindowLeaked: Activity com.example.curtisboylan.myapplication.TechnicianProfile has leaked window DecorView@415df5e[] that was originally added here at android.view.ViewRootImpl.(ViewRootImpl.java:418) at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:331) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93) at android.app.Dialog.show(Dialog.java:322) at com.example.curtisboylan.myapplication.TechnicianProfile$GetProfile.onPreExecute(TechnicianProfile.java:48) at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:620) at android.os.AsyncTask.execute(A util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:607)at java.lang.Thread.run(Thread.java:761)E / EGL_Emulation:tid 2593:eglSurfaceAttrib(1174):错误0x3009(EGL_BAD_MATCH)W / OpenGLRenderer:无法在表面0x8f2f5080上设置EGL_SWAP_BEHAVIOR,错误= EGL_BAD_MATCH E / WindowManager:android.view.Window。泄漏了DecorView @ 415df5e []窗口,该窗口最初是在android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:331)的android.view.ViewRootImpl。(ViewRootImpl.java:418)此处添加的,而在android.view.WindowManagerImpl.addView (WindowManagerImpl.java:93),位于android.app.Dialog.show(Dialog.java:322),位于com.example.curtisboylan.myapplication.TechnicianProfile $ GetProfile.onPreExecute(TechnicianProfile.java:48),位于android.os.AsyncTask。 android.os.AsyncTask.execute(A上的executeOnExecutor(AsyncTask.java:620) syncTask.java:567) at com.example.curtisboylan.myapplication.TechnicianProfile.onCreate(TechnicianProfile.java:36) at android.app.Activity.performCreate(Activity.java:6679) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) at android.app.ActivityThread.-wrap12(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6119) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) E/WindowManager: android.view.WindowLeaked: Activity com.example.curtisboylan.myapplication.TechnicianLis com.example.curtisboylan.myapplication.TechnicianProfile.onCreate(TechnicianProfile.java:36)上的syncTask.java:567)android.app.Instrumentation.callActivityOnCreate(Instrumentation)上的android.app.Activity.performCreate(Activity.java:6679) .java:1118,位于android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618),位于android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726),位于android.app.ActivityThread.-wrap12(ActivityThread.java),位于android.os.Looper.loop(Looper.java:154)处的android.os.Handler.dispatchMessage(Handler.java:102)处的android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1477) com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:886)的java.lang.reflect.Method.invoke(本机方法)的.ActivityThread.main(ActivityThread.java:6119) .internal.os.ZygoteInit.main(ZygoteInit.java:776)E / WindowManager:android.view.WindowLeaked:活动com.example.curtisboylan.myapplication.TechnicianLis tView has leaked window DecorView@b6a1d55[] that was originally added here at android.view.ViewRootImpl.(ViewRootImpl.java:418) at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:331) at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93) at android.app.Dialog.show(Dialog.java:322) at com.example.curtisboylan.myapplication.TechnicianListView$GetContacts.onPreExecute(TechnicianListView.java:78) at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:620) at android.os.AsyncTask.execute(AsyncTask.java:567) at com.example.curtisboylan.myapplication.TechnicianListView.initViews(TechnicianListView.java:67) at com.example.curtisboylan.myapplication.TechnicianListView.onCreate(TechnicianListView.java:48) at android.app.Activity.performCreate(Activity.java:6679) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618) at android.app.ActivityThread.handleLaunchAct tView泄漏了DecorView @ b6a1d55 []窗口,该窗口最初在android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:331)的android.view.ViewRootImpl。(ViewRootImpl.java:418)此处添加。 android.app.Dialog.show(Dialog.java:322)上com.example.curtisboylan.myapplication.TechnicianListView $ GetContacts.onPreExecute(TechnicianListView.java:78)上的android.os.AsyncTask上的addView(WindowManagerImpl.java:93) com.example.curtisboylan.myapplication.TechnicianListView.initViews(TechnicianListView.java:67)上android.os.AsyncTask.execute(AsyncTask.java:567)上的.executeOnExecutor(AsyncTask.java:620)。 android.app.Activity.performCreate(Activity.java:6679)处的myapplication.TechnicianListView.onCreate(TechnicianListView.java:48)android.app.ActivityThread.performLaunchActivity处的android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) (ActivityThread.java:2618)在android.app.ActivityThread.handleLaunchAct ivity(ActivityThread.java:2726) at android.app.ActivityThread.-wrap12(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:154) at android.app.ActivityThread.main(ActivityThread.java:6119) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 在android.app.ActivityThread.-wrap12(ActivityThread.java)在android.app.ActivityThread $ H.handleMessage(ActivityThread.java:1477)在android.os.Handler.dispatchMessage(Handler)的ivity(ActivityThread.java:2726) com的java.lang.reflect.Method.invoke(本机方法)处的android.os.Looper.loop(Looper.java:154)处的android.os.Looper.loop(Looper.java:154) .android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:886)在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

You can not do any UI operation in doInBackground . 您不能在doInBackground执行任何UI操作。

Put set text related stuff in onPostExecute method of AsyncTask 将与设置文本相关的内容放入AsyncTask onPostExecute方法中

@Override
protected void onPostExecute(Void aVoid) {

}

从doInBackground中删除UI组件,并在Asynctask的postExecute方法中更新UI

You are trying to modify a View from a background thread. 您正在尝试从后台线程修改视图。
View Android UI in not thread safe, and so can only be modified from the main thread. 以非线程安全的方式查看Android UI,因此只能从主线程进行修改。

The offence is this line in your doInBackground() 冒犯的是您doInBackground()这一行

usernametext.setText(c.getString("name"));

Instead, you should return the found String from the doInBackground , override onPostExecute and set it there. 相反,您应该从doInBackground返回找到的String,重写onPostExecute并将其设置在那里。
An other option is wrap is in a runOnUiThread() but honestly that's more complicated and unnecessary in this case. 另一个选择是将换行包装在runOnUiThread()但老实说,在这种情况下,它更复杂且不必要。

You cannot use 你不能使用

usernametext = (TextView) TechnicianProfile.this.findViewById(R.id.abouttext);
                        usernametext.setText(c.getString("name"));

from .doInbackground() method, because this method is executed on background thread, but UI elements can only be changed from a main thread. 从.doInbackground()方法开始,因为此方法在后台线程上执行,但是UI元素只能从主线程更改。 Move UI update to .onPostExecute() method. 将UI更新移至.onPostExecute()方法。

As the error suggest "Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException" you are doing wrong thing in wrong thread. 由于错误提示“由android.view.ViewRootImpl $ CalledFromWrongThreadException引起”,您在错误的线程中执行了错误的操作。 Please move your setText code to onPostExecute . 请将您的setText代码移至onPostExecute

You have to use publishProgress and onProgressUpdate . 您必须使用publishProgressonProgressUpdate

package com.example.curtisboylan.myapplication;

import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

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



public class TechnicianProfile extends AppCompatActivity {

    private static String url;
    private String TAG = SearchScreen.class.getSimpleName();
    private ProgressDialog pDialog;
    private TextView usernametext;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_technician_profile);
        usernametext = (TextView) TechnicianProfile.this.findViewById(R.id.abouttext);
        Bundle bundle = getIntent().getExtras();
        String username = bundle.getString("username");
        String userid = bundle.getString("userid");

        setTitle("Technician - " + username);
        url = "http://curtisboylan.me/mygeek/mygeekprofile.php?user=" + userid;

        Log.d("test", url);

        new GetProfile(usernametext).execute();

    }



    private class GetProfile extends AsyncTask<Void, String, Void> {
    private TextView tv;
        public GetProfile(TextView tv) {
            this.tv = tv;
        }
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            // Showing progress dialog
            pDialog = new ProgressDialog(TechnicianProfile.this);
            pDialog.setMessage("Please Wait..");
            pDialog.setCancelable(false);
            pDialog.show();

        }

        @Override
        protected Void doInBackground(Void... arg0) {
            HttpHandler sh = new HttpHandler();

            // Making a request to url and getting response
            String jsonStr = sh.makeServiceCall(url);

            Log.e(TAG, "Response from url: " + jsonStr);

            if (jsonStr != null) {
                try {
                    JSONObject jsonObj = new JSONObject(jsonStr);

                    // Getting JSON Array node
                    JSONArray contacts = jsonObj.getJSONArray("MyGeek");

                    // looping through All Contacts

                        JSONObject c = contacts.getJSONObject(0);
                        String str = c.getString("name");
                        publishProgress(str);

                        // username.add(c.getString("name"));
                        // userid.add(c.getString("id"));
                        // location.add(c.getString("location"));
                        // reviewscore.add(c.getString("reviewscore"));
                        //  price.add(c.getString("price"));
                        // urllist.add(c.getString("url"));




                } catch (final JSONException e) {
                    Log.e(TAG, "Json parsing error: " + e.getMessage());
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(getApplicationContext(),
                                    "Json parsing error: " + e.getMessage(),
                                    Toast.LENGTH_LONG)
                                    .show();
                        }
                    });

                }
            } else {
                Log.e(TAG, "Couldn't get json from server.");
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(getApplicationContext(),
                                "Couldn't get json from server. Check LogCat for possible errors!",
                                Toast.LENGTH_LONG)
                                .show();
                    }
                });

            }

            return null;
        }

        @Override
    protected void onProgressUpdate(String... values) {
      super.onProgressUpdate(values);
      tv.setText(values[0]);
    }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM