2017-02-16 117 views
0

我试图从okcupid json文件中选择数据,但最终发生在android.os.AsyncTask $ 3上执行doInBackground()时发生错误。完成。下面是代码

public class MainActivityFragment extends Fragment{ 
     private static final String URL = "http://www.okcupid.com/matchSample.json"; 
     private static final String TAG = "MainActivityFragment"; 
     private Context mContext; 
     private GridView mGridView; 
     private AsyncTask<Void, Void, List<Person>> mAsyncTask; 
     private View mRootView; 

     public MainActivityFragment() { 
     } 

     @Override 
     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
      View rootView = inflater.inflate(R.layout.fragment_main, container, false); 

      mContext = this.getContext(); 
      mRootView = rootView; 
      mGridView = (GridView) rootView.findViewById(R.id.grid_view); 
      //similar to how the real app works on orientation change 
      checkConfiguration(); 
      return rootView; 
     } 
     private class GetPersonInformation extends AsyncTask<Void, Void, List<Person>> { 
      @Override 
      protected List<Person> doInBackground(Void... params) { 
       try { 
        return getPeople(); 
       } catch (IOException e) { 
        Log.e("GetPersonInformation", "IOException in doInBackground"); 
        //cancel asynctask 
        cancel(true); 
        return null; 
       } 
      } 
      @Override 
      protected void onPostExecute(List<Person> people) { 
       RelativeLayout progressLayout = (RelativeLayout) mRootView.findViewById(R.id.progress_layout); 
       progressLayout.setVisibility(View.GONE); 
       if (people != null) { 
        ItemAdapter itemAdapter = new ItemAdapter(mContext, R.id.grid_view, people); 
        mGridView.setAdapter(itemAdapter); 
        mGridView.setVisibility(View.VISIBLE); 
       } else { 
        mGridView.setEmptyView(mRootView.findViewById(android.R.id.empty)); 
       } 
      } 
      @Override 
      protected void onCancelled(List<Person> people) { 
       mGridView.setEmptyView(mRootView.findViewById(android.R.id.empty)); 
      } 
     } 
     @Override 
     public void onConfigurationChanged(Configuration newConfig) { 
      super.onConfigurationChanged(newConfig); 

      checkConfiguration(); 
      //onDestroy() not called when doing configChanges so putting the below here 
      AsyncTask.Status status = mAsyncTask.getStatus(); 
      if (status == AsyncTask.Status.PENDING || status == AsyncTask.Status.RUNNING) { 
       mAsyncTask.cancel(true); 
      } 
     } 
     public void checkConfiguration() { 
      int orientation = getResources().getConfiguration().orientation; 
      if (orientation == Configuration.ORIENTATION_LANDSCAPE) { 
       mGridView.setNumColumns(3); 
      } else if (orientation == Configuration.ORIENTATION_PORTRAIT) { 
       mGridView.setNumColumns(2); 
      } 
     } 
     @Override 
     public void onStart() { 
      super.onStart(); 

      mAsyncTask = new GetPersonInformation(); 
      mAsyncTask.execute(); 
     } 
     public List<Person> getPeople() throws IOException { 
      ConnectivityManager connMgr = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); 
      NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); 
      if (networkInfo != null && networkInfo.isConnected()) { 
       // Create a new HTTP connection to download JSON 
       HttpURLConnection urlConnection = null; 
       String result = null; 
       int resCode; 
       try { 
        java.net.URL url = new URL(URL); 
        urlConnection = (HttpURLConnection) url.openConnection(); 
        urlConnection.setAllowUserInteraction(false); 
        urlConnection.setInstanceFollowRedirects(true); 

        resCode = urlConnection.getResponseCode(); 

        if (resCode == HttpURLConnection.HTTP_OK) { 
         BufferedReader br = new BufferedReader(new InputStreamReader(urlConnection.getInputStream())); 
         StringBuilder sb = new StringBuilder(); 
         String line; 
         while ((line = br.readLine()) != null) { 
          sb.append(line).append("\n"); 
         } 
         br.close(); 
         result = sb.toString(); 
        } 
       } catch (MalformedURLException e) { 
        Log.e(TAG, "Malformed URL"); 
       } catch (IOException e) { 
        Log.e(TAG, "IOException"); 
       } finally { 
        if (urlConnection != null) { 
         try { 
          urlConnection.disconnect(); 
         } catch (Exception e) { 
          Log.e(TAG, getResources().getString(R.string.disconnect_error)); 
         } 
        } 
       } 
       if (result == null) { 
        mGridView.setEmptyView(mRootView.findViewById(android.R.id.empty)); 
        return null; 
       } 
       return readJSON(result); 
      } 
      return null; 
     } 
     public List<Person> readJSON(String response) { 
      try { 
       JSONObject json = (JSONObject) new JSONTokener(response).nextValue(); 
       JSONArray jsondataArray = json.getJSONArray("data"); 
       List<Person> people = new ArrayList<Person>(); 
       int jsondataArrayLength = jsondataArray.length(); 
       String imageURL = null; 
       String city = null; 
       String state = null; 
       String userName = null; 
       int matchPercentage = 0; 
       int age = 0; 

       for (int i = 0; i < jsondataArrayLength; i++) { 
        JSONObject o = jsondataArray.getJSONObject(i); 
        if (o.optJSONObject("location") != null) { 
         JSONObject location = o.getJSONObject("location"); 
         if (!location.optString("city_name").equals("")) { 
          city = location.getString("city_name"); 
         } 
         if (!location.optString("state_code").equals("")) { 
          state = location.getString("state_code"); 
         } 
        } 
        if (o.optInt("match") != 0) { 
         matchPercentage = o.getInt("match"); 
        } 
        if (o.optInt("age") != 0) { 
         age = o.getInt("age"); 
        } 
        if (!o.optString("username").equals("")) { 
         userName = o.getString("username"); 
        } 
        if (o.optJSONObject("photo") != null) { 
         JSONObject photos = o.getJSONObject("photo"); 
         if (photos.optJSONObject("thumb_paths") != null) { 
          JSONObject thumbPaths = photos.getJSONObject("thumb_paths"); 
          if (!thumbPaths.optString("large").equals("")) { 
           imageURL = thumbPaths.getString("large"); 
          } 
         } 
        } 
        people.add(new Person(userName, imageURL, age, city, state, matchPercentage)); 
        imageURL = null; 
        city = null; 
        state = null; 
        matchPercentage = 0; 
        userName = null; 
        age = 0; 
       } 
       return people; 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
      return null; 
     } 
    } 

错误发生时,任何帮助将不胜感激,它不是一个重复请

02-16 06:55:00.959 7880-7908/com.johnbohne.okcupid E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1 
                    Process: com.johnbohne.okcupid, PID: 7880 
                    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.requestLayout(ViewRootImpl.java:1048) 
                     at android.view.View.requestLayout(View.java:19781) 
                     at android.view.View.requestLayout(View.java:19781) 
                     at android.view.View.requestLayout(View.java:19781) 
                     at android.view.View.requestLayout(View.java:19781) 
                     at android.view.View.requestLayout(View.java:19781) 
                     at android.view.View.requestLayout(View.java:19781) 
                     at android.view.View.requestLayout(View.java:19781) 
                     at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:360) 
                     at android.view.View.requestLayout(View.java:19781) 
                     at android.view.View.setFlags(View.java:11478) 
                     at android.view.View.setVisibility(View.java:8069) 
                     at android.widget.AdapterView.updateEmptyStatus(AdapterView.java:763) 
                     at android.widget.AdapterView.setEmptyView(AdapterView.java:687) 
                     at com.johnbohne.okcupid.MainActivityFragment.getPeople(MainActivityFragment.java:154) 
                     at com.johnbohne.okcupid.MainActivityFragment$GetPersonInformation.doInBackground(MainActivityFragment.java:63) 
                     at com.johnbohne.okcupid.MainActivityFragment$GetPersonInformation.doInBackground(MainActivityFragment.java:59) 
                     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.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)  

回答

0

代码在添加以下内容后进行了工作。是在onCanceled显示错误

RelativeLayout progressLayout = (RelativeLayout) mRootView.findViewById(R.id.progress_layout); 
progressLayout.setVisibility(View.GONE); 
0
doInBackground(Void... params) 

在后台线程(工作线程)上运行,意味着完成任务后,它返回onPostExecute()方法的结果。如果更新任何UI元素,则只应在主线程(UI线程)上更新。

在代码下面的行

mGridView.setEmptyView(mRootView.findViewById(android.R.id.empty)); 

在GridView是UI元素。你不应该在工作线程上做。您可以更新onPostExecute()方法,因为它在主线程(UI线程)上运行。

+0

后,我有'mGridView.setEmptyView两行(mRootView.findViewById(android.R.id.empty))行;'onpostexecutemethod和oncancelrequest方法,你指的是哪一个? – Remy

+0

如果更新UI元素的结果,则使用onPostExecute()方法。 –

相关问题