2015-06-29 27 views
4

我想從電影數據庫中獲取有關電影的數據。然後在我的佈局中使用gridview我想在我的設備上顯示它。這是通過使用ArrayAdapter來完成的。我只想在網格中顯示電影的名稱。 但我不斷收到「java.lang.NullPointerException:試圖調用虛擬方法'java.lang.String java.lang.Object.toString()'的空對象引用」錯誤。 我的代碼如下:java.lang.NullPointerException:試圖獲取空數組的長度

public class MainActivityFragment extends Fragment { 
    ArrayAdapter<String> mMovieAdapter; 

    public MainActivityFragment() { 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { 
     mMovieAdapter = new ArrayAdapter<String>(getActivity(), R.layout.item_movies, R.id.image_view_movie, new ArrayList<String>()); 
     View rootView = inflater.inflate(R.layout.fragment_main, container, false); 
     GridView listView = (GridView) rootView.findViewById(R.id.gridview_movies); 
     listView.setAdapter(mMovieAdapter); 
     listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { 
      @Override 
      public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { 
       Intent intent = new Intent(getActivity(), DetailActivity.class); 
       String forecast = mMovieAdapter.getItem(i); 
       intent.putExtra(Intent.EXTRA_TEXT, forecast); 
       startActivity(intent); 
       /* 
       * Context context = getActivity(); String forecast = 
       * mForecastAdapter.getItem(i); int duration = 
       * Toast.LENGTH_SHORT; Toast.makeText(context, forecast, 
       * duration).show(); 
       */ 
      } 
     }); 
     return rootView; 
    } 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setHasOptionsMenu(true); 
    } 

    @Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     inflater.inflate(R.menu.moviefragment, menu); 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     int id = item.getItemId(); 
     if (id == R.id.action_refresh) { 
      updateMovie(); 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    // TO update weather when activity starts 
    @Override 
    public void onStart() { 
     super.onStart(); 
     updateMovie(); 
    } 

    private void updateMovie() { 
     FetchMovieTask movieTask = new FetchMovieTask(); 
     movieTask.execute(); 
    } 

    class FetchMovieTask extends AsyncTask<Void, Void, String[]> { 
     private final String LOG_TAG = FetchMovieTask.class.getSimpleName(); 

     @Override 
     protected String[] doInBackground(Void... params) { 
      /* if(params.length == 0) { return null; } */ 
      // These two need to be declared outside the try/catch 
      // so that they can be closed in the finally block. 
      HttpURLConnection urlConnection = null; 
      BufferedReader reader = null; 

      // Will contain the raw JSON response as a string. 
      String movieJsonStr = null; 

      try { 
       // Construct the URL for the OpenWeatherMap query 
       // Possible parameters are avaiable at OWM's forecast API page, 
       // at 
       // http://openweathermap.org/API#forecast 
       final String BASE_URL = "http://api.themoviedb.org/3/discover/movie?"; 
       final String QUERY_PARAM = "sort_by"; 
       final String KEY_PARAM = "&api_key"; 
       // Using UriBuilder 
       Uri builtUri = Uri.parse(BASE_URL).buildUpon().appendQueryParameter(QUERY_PARAM, "popularity.desc").appendQueryParameter(KEY_PARAM, "c20129fdf73b5df3ab44548ad7f73586").build(); 
       URL url = new URL(builtUri.toString()); 
       // Printing the url in the log 
       // Log.v(LOG_TAG, "Built URI " + builtUri.toString()); 

       // Create the request to OpenWeatherMap, and open the connection 
       urlConnection = (HttpURLConnection) url.openConnection(); 
       urlConnection.setRequestMethod("GET"); 
       urlConnection.connect(); 

       // Read the input stream into a String 
       InputStream inputStream = urlConnection.getInputStream(); 
       StringBuffer buffer = new StringBuffer(); 
       if (inputStream == null) { 
        // Nothing to do. 
        return null; 
       } 
       reader = new BufferedReader(new InputStreamReader(inputStream)); 

       String line; 
       while ((line = reader.readLine()) != null) { 
        // Since it's JSON, adding a newline isn't necessary (it 
        // won't affect parsing) 
        // But it does make debugging a *lot* easier if you print 
        // out the completed 
        // buffer for debugging. 
        buffer.append(line + "\n"); 
       } 

       if (buffer.length() == 0) { 
        // Stream was empty. No point in parsing. 
        return null; 
       } 
       movieJsonStr = buffer.toString(); 

      } catch (IOException e) { 
       Log.e(LOG_TAG, "Error ", e); 
       // If the code didn't successfully get the weather data, there's 
       // no point in attemping 
       // to parse it. 
       return null; 
      } finally { 
       if (urlConnection != null) { 
        urlConnection.disconnect(); 
       } 
       if (reader != null) { 
        try { 
         reader.close(); 
        } catch (final IOException e) { 
         Log.e(LOG_TAG, "Error closing stream", e); 
        } 
       } 
      } 
      try { 
       return getMovieDataFromJson(movieJsonStr); 
      } catch (JSONException j) { 
       Log.e(LOG_TAG, "JSON Error", j); 
      } 
      return null; 
     } 

     private String[] getMovieDataFromJson(String forecastJsonStr) throws JSONException { 
      String title; 
      JSONObject movieJson = new JSONObject(forecastJsonStr); 
      JSONArray movieArray = movieJson.getJSONArray("results"); 

      String[] resultStrs = new String[100]; 
      for (int i = 0; i < movieArray.length(); i++) { 
       // Get the JSON object representing the day 
       JSONObject movie = movieArray.getJSONObject(i); 

       title = movie.getString("original_title"); 
       resultStrs[i] = title; 
       Log.v(LOG_TAG, resultStrs[i]); 
      } 

      /* 
      * for (String s : resultStrs) { Log.v(LOG_TAG, "Forecast entry: " + 
      * s); } 
      */ 
      return resultStrs; 
     } 

     @Override 
     protected void onPostExecute(String[] strings) { 
      super.onPostExecute(strings); 
      mMovieAdapter.clear(); 
      mMovieAdapter.addAll(strings); 
     } 
    } 
} 

我的錯誤日誌:

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.Object.toString()' on a null object reference 
     at android.widget.ArrayAdapter.createViewFromResource(ArrayAdapter.java:394) 
     at android.widget.ArrayAdapter.getView(ArrayAdapter.java:362) 
     at android.widget.AbsListView.obtainView(AbsListView.java:2344) 
     at android.widget.GridView.makeAndAddView(GridView.java:1433) 
     at android.widget.GridView.makeRow(GridView.java:361) 
     at android.widget.GridView.fillDown(GridView.java:302) 
     at android.widget.GridView.fillGap(GridView.java:262) 
     at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4968) 
     at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4512) 
     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767) 
     at android.view.Choreographer.doCallbacks(Choreographer.java:580) 
     at android.view.Choreographer.doFrame(Choreographer.java:549) 
     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753) 
     at android.os.Handler.handleCallback(Handler.java:739) 
     at android.os.Handler.dispatchMessage(Handler.java:95) 
     at android.os.Looper.loop(Looper.java:135) 
     at android.app.ActivityThread.main(ActivityThread.java:5312) 
     at java.lang.reflect.Method.invoke(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:372) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:901) 
+0

問題給予null元素** 1)**什麼是你的JSON的樣子? ** 2)**你確定知道你有一系列電影嗎? ** 3)**您的JSON是否結構合理?如果存在JSON異常,我不會僅記錄錯誤並返回null。我寧願拋出一個相關的例外。 – Alp

+0

你的分析字符串數組是否爲空? – hoomi

+0

它看起來像doInBackground返回的結果爲null。你能證實這一點嗎? –

回答

3

我懷疑這是也是由黑帶在評論中提到的錯誤

String[] resultStrs = new String[100];

這應該是

String[] resultStrs = new String[movieArray.length()];

因爲你現在要做的是說,到GridView你有總是 100部電影,但是當有小於100部電影你到GridView

+0

是的,我採取了Blackbelt的建議,現在一切正常。謝謝! –