2016-03-25 1 views
-1

MainActivityFragmentでアダプタを初期化して、偽のデータでアダプタを初期化した後、サーバからデータを取得してアダプタを更新しようとしました。インラインクラスFetchWeatherTaskのメンバメソッドであるonPostExecute()メソッドのmforecastadapterを使用している場合にNULLポインタ例外を取得しています。mforecastadapterがonpostexecuteメソッドでキャッチされたjava.lang.NullPointerException

package com.example.puneet.sunshine; 

import android.os.AsyncTask; 
import android.support.v4.app.Fragment; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ArrayAdapter; 
import android.widget.ListView; 
import android.util.Log; 

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

import android.text.format.Time; 
import java.text.SimpleDateFormat; 
import java.util.ArrayList; 
import java.util.Arrays; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.net.HttpURLConnection; 
import java.net.URL; 
/** 
* A placeholder fragment containing a simple view. 
*/ 
public class MainActivityFragment extends Fragment { 
public ArrayAdapter<String> mforecastadapter; 
public MainActivityFragment() { 

} 


public View onCreateView(LayoutInflater inflater, ViewGroup container,    Bundle savedInstanceState) { 

    View rootview = inflater.inflate(R.layout.fragment_main,container,true); 
     String[] forecast = { 
       "Today - Sunny - 80/66", 
       "Tomorrow - Cloudy - 75/55", 
       "Weds - Foggy - 86/65", 
       "Thurs - Asteroids - 76/43", 
       "Fri - Sunny - 87/56", 
       "Sat - Foggy - 76/55", 
       "Sun - Cloudy - 66/44" 
     }; 
     ArrayList<String> weekforecast = new ArrayList<String>(Arrays.asList(forecast)); 
     mforecastadapter = new ArrayAdapter<String>(getActivity(), R.layout.list_forecast_layout, R.id.list_item_forecast_textview, weekforecast); 

     ListView l = (ListView) rootview.findViewById(R.id.listView_forecast); 
     l.setAdapter(mforecastadapter); 

     return rootview; 
    } 
public class FetchWeatherTask extends AsyncTask<String, Void, String[]> { 
    private final String LOG_TAG = FetchWeatherTask.class.getSimpleName(); 

    /* The date/time conversion code is going to be moved outside the asynctask later, 
    * so for convenience we're breaking it out into its own method now. 
    */ 
    private String getReadableDateString(long time){ 
     // Because the API returns a unix timestamp (measured in seconds), 
     // it must be converted to milliseconds in order to be converted to valid date. 
     SimpleDateFormat shortenedDateFormat = new SimpleDateFormat("EEE MMM dd"); 
     return shortenedDateFormat.format(time); 
    } 

    /** 
    * Prepare the weather high/lows for presentation. 
    */ 
    private String formatHighLows(double high, double low) { 
     // For presentation, assume the user doesn't care about tenths of a degree. 
     long roundedHigh = Math.round(high); 
     long roundedLow = Math.round(low); 

     String highLowStr = roundedHigh + "/" + roundedLow; 
     return highLowStr; 
    } 

    /** 
    * Take the String representing the complete forecast in JSON Format and 
    * pull out the data we need to construct the Strings needed for the wireframes. 
    * 
    * Fortunately parsing is easy: constructor takes the JSON string and converts it 
    * into an Object hierarchy for us. 
    */ 
    private String[] getWeatherDataFromJson(String forecastJsonStr, int numDays) 
      throws JSONException { 

     // These are the names of the JSON objects that need to be extracted. 
     final String OWM_LIST = "list"; 
     final String OWM_WEATHER = "weather"; 
     final String OWM_TEMPERATURE = "temp"; 
     final String OWM_MAX = "max"; 
     final String OWM_MIN = "min"; 
     final String OWM_DESCRIPTION = "main"; 

     JSONObject forecastJson = new JSONObject(forecastJsonStr); 
     JSONArray weatherArray = forecastJson.getJSONArray(OWM_LIST); 

     // OWM returns daily forecasts based upon the local time of the city that is being 
     // asked for, which means that we need to know the GMT offset to translate this data 
     // properly. 

     // Since this data is also sent in-order and the first day is always the 
     // current day, we're going to take advantage of that to get a nice 
     // normalized UTC date for all of our weather. 

     Time dayTime = new Time(); 
     dayTime.setToNow(); 

     // we start at the day returned by local time. Otherwise this is a mess. 
     int julianStartDay = Time.getJulianDay(System.currentTimeMillis(), dayTime.gmtoff); 

     // now we work exclusively in UTC 
     dayTime = new Time(); 
     int le = weatherArray.length(); 
     String str = new String(String.valueOf(le)); 
     Log.v(LOG_TAG,str); 

     String[] resultStrs = new String[numDays]; 
     for(int i = 0; i < weatherArray.length(); i++) { 
      // For now, using the format "Day, description, hi/low" 
      String day; 
      String description; 
      String highAndLow; 

      // Get the JSON object representing the day 
      JSONObject dayForecast = weatherArray.getJSONObject(i); 

      // The date/time is returned as a long. We need to convert that 
      // into something human-readable, since most people won't read "1400356800" as 
      // "this saturday". 
      long dateTime; 
      // Cheating to convert this to UTC time, which is what we want anyhow 
      dateTime = dayTime.setJulianDay(julianStartDay+i); 
      day = getReadableDateString(dateTime); 

      // description is in a child array called "weather", which is 1 element long. 
      JSONObject weatherObject = dayForecast.getJSONArray(OWM_WEATHER).getJSONObject(0); 
      description = weatherObject.getString(OWM_DESCRIPTION); 

      // Temperatures are in a child object called "temp". Try not to name variables 
      // "temp" when working with temperature. It confuses everybody. 
      JSONObject temperatureObject = dayForecast.getJSONObject(OWM_TEMPERATURE); 
      double high = temperatureObject.getDouble(OWM_MAX); 
      double low = temperatureObject.getDouble(OWM_MIN); 

      highAndLow = formatHighLows(high, low); 
      resultStrs[i] = day + " - " + description + " - " + highAndLow; 
     } 

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

    } 

    @Override 

    public String[] doInBackground(String... params) { 
     // 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; 

     if (params.length == 0) { 
      return null; 
     } 
     // Will contain the raw JSON response as a string. 
     String forecastJsonStr = 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 
      String place = params[0]; 
      String mode = "json"; 
      String unit = "metric"; 
      String count = "7"; 
      String baseUrl = "http://api.openweathermap.org/data/2.5/forecast/daily?q="+place+"&mode=json&units=metric&cnt=7"; 
      String apiKey = "&APPID=" + BuildConfig.OPEN_WEATHER_MAP_API_KEY; 
      URL url = new URL(baseUrl.concat(apiKey)); 
      String o1 = new String(String.valueOf(url)); 
      Log.v(LOG_TAG,"url="+o1); 

      // 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. 
       Log.v(LOG_TAG,"empty input stream"); 
       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. 
       Log.v(LOG_TAG,"empty buffer"); 
       return null; 
      } 
      forecastJsonStr = buffer.toString(); 

      Log.v(LOG_TAG, "Forecast Json string:" + forecastJsonStr); 
     } 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 getWeatherDataFromJson(forecastJsonStr, 7); 
     } catch (JSONException e) { 
      Log.v(LOG_TAG,"null object"); 
      Log.e(LOG_TAG, e.getMessage(), e); 
      e.printStackTrace(); 
     } 
     return null; 
    } 

    @Override 
    protected void onPostExecute(String[] result) { 

     super.onPostExecute(result); 
     if(mforecastadapter==null){ 
      Log.v(LOG_TAG,"adapter null"); 
     } 
     if(result!=null){ 
      mforecastadapter.clear(); 
      for(String s: result){ 
       mforecastadapter.add(s); 
      } 
     } 
     mforecastadapter.notifyDataSetChanged(); 
    } 
} 

}

+2

例外スタックトレースを質問に追加してください。 – JanBo

+2

あなたのFetchWeatherTaskはどこでインスタンス化されますか?あなたはどこでそれを実行しますか? – JanBo

+0

fetchweathertaskは、mainactivityという名前の他のアクティビティでインスタンス化されます –

答えて

0

次のようにsetAdapterコード以下のタスクを実行します。

ListView l = (ListView) rootview.findViewById(R.id.listView_forecast); 
l.setAdapter(mforecastadapter); 
new FetchWeatherTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,inputString); 

をしたり、mforecastAdapter

if(mforecastadapter==null){ 
      Log.v(LOG_TAG,"adapter null"); 
      mforecastadapter = new ArrayAdapter<String>(getActivity(), R.layout.list_forecast_layout, R.id.list_item_forecast_textview, weekforecast); 
} 

を初期化にこのアダプタを設定してくださいすることができますリストビュー。

私はの最初の解決策をお勧めします

+0

どのように私の問題を解決するのだろうか?私の問題は、上記の偽のデータを使用して初期化した顔に関係なく、アダプターをnullにする理由です。 –

関連する問題