【问题标题】:Android JSON Parsing Crashing Application AsyncTaskAndroid JSON解析崩溃应用程序AsyncTask
【发布时间】:2017-03-21 10:34:14
【问题描述】:

我正在使用 JSON 解析器从我的 JSON 文件中读取数据并将其显示在我的应用程序中,我最初使用此代码创建工作正常的数组,但现在我已将其粘贴到一个新应用程序中以使其得到来自 JSON 的数据并将其放在一个不起作用的文本字段中。我将在下面发布代码和错误日志。

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/测试:http://curtisboylan.me/mygeek/mygeekprofile.php?user=1 E/EGL_emulation: tid 2593: eglSurfaceAttrib(1174): 错误 0x3009 (EGL_BAD_MATCH) W/OpenGLRenderer:无法设置 EGL_SWAP_BEHAVIOR 表面 0x91199f00,错误 = EGL_BAD_MATCH E/EGL_emulation:tid 2593: eglSurfaceAttrib(1174): 错误 0x3009 (EGL_BAD_MATCH) W/OpenGLRenderer: 未能在表面 0x8f2f5000 上设置 EGL_SWAP_BEHAVIOR, 错误=EGL_BAD_MATCH E/SearchScreen:来自 url 的响应: {"MyGeek":[{"id":"1","name":"Curtis Boylan","location":"Swords, Co 都柏林","re​​viewscore":"5.6","url":"https://scontent-lhr3-1.xx.fbcdn.net/v/t1.0-9/11062691_831452480236559_1123476984274233173_n.jpg?oh=8eb4bb9519a2cd3b96b085146b50e=11062691_831452480236559_1123476984274233173_n.jpg?oh=8eb4bb9519a2cd3b96b085146BBB507e=" ,"价格":"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

创建视图层次结构的原始线程可以触及其视图。 在 android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6891) 在 android.view.ViewRootImpl.invalidateChildInParent(ViewRootImpl.java:1083) 在 android.view.ViewGroup.invalidateChild(ViewGroup.java:5205) 在 android.view.View.invalidateInternal(View.java:13656) 在 android.view.View.invalidate(View.java:13620) 在 android.view.View.invalidate(View.java:13604) 在 android.widget.TextView.checkForRelayout(TextView.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.curtisboylan.myapplication.TechnicianProfile$GetProfile.doInBackground(TechnicianProfile.java:39) 在 android.os.AsyncTask$2.call(AsyncTask.java:305) 在 java.util.concurrent.FutureTask.run(FutureTask.java:237) 在 android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:243) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607) 在 java.lang.Thread.run(Thread.java:761) E/EGL_emulation: tid 2593: eglSurfaceAttrib(1174): 错误 0x3009 (EGL_BAD_MATCH) W/OpenGLRenderer:无法设置 EGL_SWAP_BEHAVIOR 表面 0x8f2f5080,错误 = EGL_BAD_MATCH E/WindowManager: android.view.WindowLeaked:活动 com.example.curtisboylan.myapplication.TechnicianProfile 已泄露 最初在这里添加的 window DecorView@415df5e[] 在 android.view.ViewRootImpl.(ViewRootImpl.java:418) 在 android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:331) 在 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.executeOnExecutor(AsyncTask.java:620) 在 android.os.AsyncTask.execute(AsyncTask.java:567) 在 com.example.curtisboylan.myapplication.TechnicianProfile.onCreate(TechnicianProfile.java:36) 在 android.app.Activity.performCreate(Activity.java:6679) 在 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 在 android.app.ActivityThread.-wrap12(ActivityThread.java) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:154) 在 android.app.ActivityThread.main(ActivityThread.java:6119) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) E/WindowManager: android.view.WindowLeaked: 活动 com.example.curtisboylan.myapplication.TechnicianListView 已泄露 最初在这里添加的窗口 DecorView@b6a1d55[] 在 android.view.ViewRootImpl.(ViewRootImpl.java:418) 在 android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:331) 在 android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93) 在 android.app.Dialog.show(Dialog.java:322) 在 com.example.curtisboylan.myapplication.TechnicianListView$GetContacts.onPreExecute(TechnicianListView.java:78) 在 android.os.AsyncTask.executeOnExecutor(AsyncTask.java:620) 在 android.os.AsyncTask.execute(AsyncTask.java:567) 在 com.example.curtisboylan.myapplication.TechnicianListView.initViews(TechnicianListView.java:67) 在 com.example.curtisboylan.myapplication.TechnicianListView.onCreate(TechnicianListView.java:48) 在 android.app.Activity.performCreate(Activity.java:6679) 在 android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118) 在 android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618) 在 android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 在 android.app.ActivityThread.-wrap12(ActivityThread.java) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 在 android.os.Handler.dispatchMessage(Handler.java:102) 在 android.os.Looper.loop(Looper.java:154) 在 android.app.ActivityThread.main(ActivityThread.java:6119) 在 java.lang.reflect.Method.invoke(本机方法) 在 com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)

【问题讨论】:

    标签: java android json android-asynctask


    【解决方案1】:

    doInBackground不能做任何UI操作。

    将设置文本相关的东西放在AsyncTaskonPostExecutemethod中

    @Override
    protected void onPostExecute(Void aVoid) {
    
    }
    

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        【解决方案3】:

        您正在尝试从后台线程修改视图。
        以非线程安全的方式查看 Android UI,因此只能从主线程进行修改。

        冒犯是你doInBackground()中的这一行

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

        相反,您应该从doInBackground 返回找到的字符串,覆盖onPostExecute 并将其设置在那里。
        另一个选项是 wrap 在 runOnUiThread() 中,但老实说,在这种情况下这更复杂且不必要。

        【讨论】:

          【解决方案4】:

          你不能使用

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

          来自 .doInbackground() 方法,因为该方法在后台线程上执行,但 UI 元素只能从主线程更改。 将 UI 更新移至 .onPostExecute() 方法。

          【讨论】:

            【解决方案5】:

            正如错误提示“由:android.view.ViewRootImpl$CalledFromWrongThreadException”引起的,您在错误的线程中做错了事。请将您的setText 代码移至onPostExecute

            【讨论】:

              【解决方案6】:

              您必须使用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]);
                  }
                  }
              }
              

              【讨论】:

                猜你喜欢
                • 2013-02-22
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多