Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Android Build a Weather App (2015) Hooking Up the Model to the View Setting the Weather Icon

I don't get the right result as gotten in the video (min. 01:22)

hi,

I've been following step by step to ben's instructions but the succesfull result ben got in the min. 01:22 of the video isn't the same as the one i got.

My mCurrentWheather code:

public class CurrentWeather {

private String mIcon;
private long mTime;
private double mTemperature;
private double mHumidity;
private double mPrecipChance;
private String mSummary;
private String mTimeZone;


public String getTimeZone() {
    return mTimeZone;
}

public void setTimeZone(String mTimeZone) {
   this.mTimeZone = mTimeZone;
}

public String getmIcon() {
    return mIcon;
}

public void setmIcon(String mIcon) {
    this.mIcon = mIcon;
}

public long getTime() {
    return mTime;
}

public String getFormattedTime(){

    SimpleDateFormat formatter = new SimpleDateFormat("h:mm a");
    formatter.setTimeZone(TimeZone.getTimeZone(getTimeZone()));
    Date dateTime = new Date(getTime() * 1000);
    String timeString = formatter.format(dateTime);

    return timeString;

}

public int getIconId(){

    // clear-day, clear-night, rain, snow, sleet, wind, fog, cloudy, partly-cloudy-day, or partly-cloudy-night
    int iconId = R.drawable.clear_day;

    if(mIcon.equals("clear-day")){
       iconId = R.drawable.clear_day;
    }

    else if(mIcon.equals("clear-night")){
       iconId = R.drawable.clear_night;
    }

    else if (mIcon.equals("rain")) {
        iconId = R.drawable.rain;
    }
    else if (mIcon.equals("snow")) {
        iconId = R.drawable.snow;
    }
    else if (mIcon.equals("sleet")) {
        iconId = R.drawable.sleet;
    }
    else if (mIcon.equals("wind")) {
        iconId = R.drawable.wind;
    }
    else if (mIcon.equals("fog")) {
        iconId = R.drawable.fog;
    }
    else if (mIcon.equals("cloudy")) {
        iconId = R.drawable.cloudy;
    }
    else if (mIcon.equals("partly-cloudy-day")) {
        iconId = R.drawable.partly_cloudy;
    }
    else if (mIcon.equals("partly-cloudy-night")) {
        iconId = R.drawable.cloudy_night;
    }

    return iconId;
}



public void setmTime(long mTime) {
    this.mTime = mTime;
}

public int getmTemperature() {

    return (int) Math.round(mTemperature);
}

public void setmTemperature(double mTemperature) {
    this.mTemperature = mTemperature;
}

public double getmHumidity() {
    return mHumidity;
}

public void setmHumidity(double mHumidity) {
    this.mHumidity = mHumidity;
}

public int getmPrecipChance() {

    double precipPercentaje = mPrecipChance * 100;
    return (int) Math.round(precipPercentaje);
}

public void setmPrecipChance(double mPrecipChance) {
    this.mPrecipChance = mPrecipChance;
}

public String getmSummary() {
    return mSummary;
}

public void setmSummary(String mSummary) {
    this.mSum





                                  Error shown after launching the app:

FATAL EXCEPTION: main Process: com.example.mario.stormy, PID: 19640 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference at com.example.mario.stormy.MainActivity.updateDisplay(MainActivity.java:128) at com.example.mario.stormy.MainActivity.access$200(MainActivity.java:35) at com.example.mario.stormy.MainActivity$1$1.run(MainActivity.java:91

i can see the possible issue migth be what's the object is missing or null, but what could it be ?

I appreciate any help.

Regards,

Deividas Strioga
Deividas Strioga
12,851 Points

Hello, first of all, your setters and getters are a bit messed up. Like this one:

public void setTimeZone(String mTimeZone) { this.mTimeZone = mTimeZone;}

it should be:

public void setTimeZone(String timeZone) { mTimeZone = timeZone;}

And: public String getmSummary() { return mSummary;}

should be : public String getSummary() { return mSummary;}

But they do not cause error here. According to your log: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference at com.example.mario.stormy.MainActivity.updateDisplay(MainActivity.java:128) There is an error in line 128. In the code given it's the last line and it is not finished. Please provide all the code.

Michael Nock
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Michael Nock
Android Development Techdegree Graduate 16,018 Points

Others having this issue should check out the github site: https://github.com/JakeWharton/butterknife#download

You need to configure your build.gradle files to include the android-apt plugin as well as the butterknife compiler.

5 Answers

I had the same issue, in my case it was the ButterKnife compile statement in the app build.gradle. yuo need to add the line: annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'

Below the compile 'com.jakewharton:butterknife:8.4.0' and sync gradle.

Jacob Bergdahl
Jacob Bergdahl
29,118 Points

In your error message, you can see that your error is in MainActivity, and that one of your TextView variables has a null reference :) Take a look at that TextView in MainActivity and see if you can figure out why it says null! If not, please post your code for MainActivity.

thank you so much for your answer. i attached my MainActivity code though i tried hards to identify the null object but just i couldn't.

package com.example.mario.stormy;

import android.content.Context; import android.graphics.drawable.Drawable; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.os.Bundle; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast;

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

import java.io.IOException;

import butterknife.BindView; import butterknife.ButterKnife; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response;

public class MainActivity extends AppCompatActivity {

public static final String TAG = MainActivity.class.getSimpleName();

private CurrentWeather mCurrentWeather;

@BindView(R.id.timeLabel) TextView mTimeLabel;
@BindView(R.id.temperatureLabel) TextView mTemperatureLabel;
@BindView(R.id.humidityLabel) TextView mHumidityValue;
@BindView(R.id.preciptLabel) TextView mPrecipValue;
@BindView(R.id.summaryLabel) TextView mSummaryLabel;
@BindView(R.id.iconImageView) ImageView mIconImageView;



@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);
    mTemperatureLabel = (TextView)findViewById(R.id.temperatureLabel);
    String apiKey = "1f2797fd70b0fb0c614560bd5e123912";
    double latitude = 37.8267;
    double longitude = -122.423;
    String forecastURL = "https://api.forecast.io/forecast/" + apiKey +
            "/" + latitude + "," + longitude;

    if (isNetworkAvailable()) {


        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(forecastURL)
                .build();

        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {

            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {

                try {

                    String jsonData = response.body().string();
                    Log.v(TAG, jsonData);
                    if (response.isSuccessful()) {

                    mCurrentWeather = getCurrentDetails(jsonData);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {

                                updateDisplay();
                            }
                        });



                    } else {

                        AlertUserAboutError();
                    }

                } catch (IOException e) {

                    Log.e(TAG, "Exception caught: ", e);
                }

                  catch (JSONException  e){

                    Log.e(TAG, "Exception caught: ", e);

                }
            }
        });

    } else {

        Toast.makeText(this, R.string.network_unavailable_message, Toast.LENGTH_SHORT).show();
    }

    Log.d(TAG, "Main UI code is running ! ");

}


private void updateDisplay() {

    mTemperatureLabel.setText(mCurrentWeather.getmTemperature() + "");
    mTimeLabel.setText(" At " + mCurrentWeather.getFormattedTime() + " it will be ");
    mHumidityValue.setText(mCurrentWeather.getmHumidity() + "");
    mPrecipValue.setText(mCurrentWeather.getmPrecipChance() + "%");
    mSummaryLabel.setText(mCurrentWeather.getmSummary());
    Drawable drawable = ContextCompat.getDrawable(this, mCurrentWeather.getIconId());
    mIconImageView.setImageDrawable(drawable);


}

private CurrentWeather getCurrentDetails(String jsonData) throws JSONException {

        JSONObject forecast = new JSONObject(jsonData);
        String timezone = forecast.getString("timezone");
        Log.i(TAG, "From JSON: " + timezone);

        JSONObject currently = forecast.getJSONObject("currently");

        CurrentWeather currenweather = new CurrentWeather();
        currenweather.setmHumidity(currently.getDouble("humidity"));
        currenweather.setmTime(currently.getLong("time"));
        currenweather.setmIcon(currently.getString("icon"));
        currenweather.setmPrecipChance(currently.getDouble("precipProbability"));
        currenweather.setmSummary(currently.getString("summary"));
        currenweather.setmTemperature(currently.getDouble("temperature"));
        currenweather.setTimeZone(timezone);

       Log.d(TAG, currenweather.getFormattedTime());

    return currenweather;
}


private boolean isNetworkAvailable() {
    ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkinfo = manager.getActiveNetworkInfo();
    boolean isAvailable = false;

    if(networkinfo != null && networkinfo.isConnected()){

        isAvailable = true;

    }

    return isAvailable;

}

private void AlertUserAboutError() {

    AlertDialogFragment dialog = new AlertDialogFragment();
    dialog.show(getFragmentManager(), "Error_dialog");

}

}

thanks a lot friends,

i also add the error in which the line affected is 121:

07-04 11:35:49.294 12178-12178/com.example.mario.stormy E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.mario.stormy, PID: 12178 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference at com.example.mario.stormy.MainActivity.updateDisplay(MainActivity.java:121) at com.example.mario.stormy.MainActivity.access$200(MainActivity.java:28) at com.example.mario.stormy.MainActivity$1$1.run(MainActivity.java:84) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

thanks,

Jacob Bergdahl
Jacob Bergdahl
29,118 Points

One of your TextViews is null. Look at your assignments. For example, you spelled "preciptLabel" -- is that a misspell? Double-check the name of all ids.

Deividas Strioga
Deividas Strioga
12,851 Points

Which is line 121? Its hard to tell from here.

Jacob Bergdahl
Jacob Bergdahl
29,118 Points

You can just click on MainActivity.java:121 and it'll take you straight to it.

yes, sorry. Here is the line of code pointing out the problem:

mTemperatureLabel.setText(mCurrentWeather.getmTemperature() + ""); mTimeLabel.setText(" At " + mCurrentWeather.getFormattedTime() + " it will be "); // this is the line 121 mHumidityValue.setText(mCurrentWeather.getmHumidity() + ""); mPrecipValue.setText(mCurrentWeather.getmPrecipChance() + "%"); mSummaryLabel.setText(mCurrentWeather.getmSummary()); Drawable drawable = ContextCompat.getDrawable(this, mCurrentWeather.getIconId()); mIconImageView.setImageDrawable(drawable);

thank you Jacob,

Jacob,

these are my TextViews and everything is right.

@BindView(R.id.timeLabel) TextView mTimeLabel; // mTimeLabel @BindView(R.id.temperatureLabel) TextView mTemperatureLabel; @BindView(R.id.humidityLabel) TextView mHumidityValue; @BindView(R.id.preciptLabel) TextView mPrecipValue; @BindView(R.id.summaryLabel) TextView mSummaryLabel; @BindView(R.id.iconImageView) ImageView mIconImageView;

and each one has the corresponding id declared in the content_main.xlm