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 Plugging in the Data

"java.lang.NullPointerException" Error

When I run my code, application starts running with old values and than it closes itself. Giving the error: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference

here is my MainActivity class;

package omoody.stormy;

import android.content.Context; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.util.Log; import android.view.View; import android.view.Menu; import android.view.MenuItem; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast;

import com.google.android.gms.appindexing.Action; import com.google.android.gms.appindexing.AppIndex; import com.google.android.gms.common.api.GoogleApiClient;

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;

private GoogleApiClient mClient;
@BindView(R.id.timeLabel) TextView mTimeLabel;
@BindView(R.id.temperatureLabel) TextView mTemperatureLabel;
@BindView(R.id.humidityValue) TextView mHumidityValue;
@BindView(R.id.precipValue) 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);

    String apiKey = "78c372a8f6e218e7dc2ae502ccba4b9e";
    double latitude = 37.8267;
    double longitude = -122.423;
    String forecastUrl = "https://api.forecast.io/forecast/" + apiKey +
            "/" + latitude + "," + longitude;

    if (isNetworkAvaliable()) {
        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 k, jsonData = response.body().string();
                    Log.v(TAG, jsonData);
                    if (response.isSuccessful()) {
                        mCurrentWeather = getCurrentDetails(jsonData);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                updateDisplay();
                            }
                        });
                    } else {
                        allertUserAboutError();
                    }
                } catch (IOException e) {
                    Log.e(TAG, "Execption Caught", e);
                } catch (JSONException e) {
                    Log.e(TAG, "Execption Caught", e);
                }

            }
        });
    } else {
        Toast.makeText(this, R.string.network_unavaliable_message, Toast.LENGTH_LONG).show();
    }
    Log.d(TAG, "Main UI code is running!");

    // ATTENTION: This was auto-generated to implement the App Indexing API.
    // See https://g.co/AppIndexing/AndroidStudio for more information.
    mClient = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
}

private void updateDisplay() {
    mTemperatureLabel.setText(mCurrentWeather.getTemperature()+"");

}

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 currentWeather = new CurrentWeather();
    currentWeather.setHumidity(currently.getDouble("humidity"));
    currentWeather.setTime(currently.getLong("time"));
    currentWeather.setIcon(currently.getString("icon"));
    currentWeather.setPrecipChance(currently.getDouble("precipProbability"));
    currentWeather.setSummary(currently.getString("summary"));
    currentWeather.setTemperature(currently.getDouble("temperature"));
    currentWeather.setTimeZone(timezone);

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

   // Log.i(TAG, "From JSON: " + currently);

    return currentWeather;
}

private boolean isNetworkAvaliable() {
    ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo networkInfo = manager.getActiveNetworkInfo();
    boolean isAvaliable = false;
    if (networkInfo != null && networkInfo.isConnected()) {
        isAvaliable = true;
    }
    return isAvaliable;
}

private void allertUserAboutError() {

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

}

@Override
public void onStart() {
    super.onStart();

    // ATTENTION: This was auto-generated to implement the App Indexing API.
    // See https://g.co/AppIndexing/AndroidStudio for more information.
    mClient.connect();
    Action viewAction = Action.newAction(
            Action.TYPE_VIEW, // TODO: choose an action type.
            "Main Page", // TODO: Define a title for the content shown.
            // TODO: If you have web page content that matches this app activity's content,
            // make sure this auto-generated web page URL is correct.
            // Otherwise, set the URL to null.
            Uri.parse("http://host/path"),
            // TODO: Make sure this auto-generated app deep link URI is correct.
            Uri.parse("android-app://omoody.stormy/http/host/path")
    );
    AppIndex.AppIndexApi.start(mClient, viewAction);
}

@Override
public void onStop() {
    super.onStop();

    // ATTENTION: This was auto-generated to implement the App Indexing API.
    // See https://g.co/AppIndexing/AndroidStudio for more information.
    Action viewAction = Action.newAction(
            Action.TYPE_VIEW, // TODO: choose an action type.
            "Main Page", // TODO: Define a title for the content shown.
            // TODO: If you have web page content that matches this app activity's content,
            // make sure this auto-generated web page URL is correct.
            // Otherwise, set the URL to null.
            Uri.parse("http://host/path"),
            // TODO: Make sure this auto-generated app deep link URI is correct.
            Uri.parse("android-app://omoody.stormy/http/host/path")
    );
    AppIndex.AppIndexApi.end(mClient, viewAction);
    mClient.disconnect();
}

}

I am using ButterKnife 8.2.1 and on my build.gradle(Module: app) I added the line
compile 'com.jakewharton:butterknife:8.2.1' under dependencies. In github documentation it seems like I need to add some more lines but when do it does not sync. I am stucked and dont know what to do. Thank you so much!

Mikal Stapnes
Mikal Stapnes
1,580 Points

In addition to:

compile 'com.jakewharton:butterknife:8.2.1'

First add

apply plugin: 'android-apt'

to the beginning of the gradle file, then add

apt 'com.jakewharton:butterknife-compiler:8.2.1'

under dependencies.

My full build.gradle file:

apply plugin: 'com.android.application'
apply plugin: 'android-apt'

android {
    compileSdkVersion 24
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "com.endgame.stormy"
        minSdkVersion 16
        targetSdkVersion 24
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:24.0.0'
    compile 'com.squareup.okhttp3:mockwebserver:3.3.1'
    compile 'com.jakewharton:butterknife:8.1.0'
    apt 'com.jakewharton:butterknife-compiler:8.1.0'
}

Hope this helps

1 Answer

When I try to add apt 'com.jakewharton:butterknife-compiler:8.2.1' it gives an error mentioning that syn failed. I managed to solve the problem by using the older version which is compile 'com.jakewharton:butterknife:6.0.0'

Mikal Stapnes
Mikal Stapnes
1,580 Points

Yeah i forgot to mention that when using apt you need to write apply plugin: 'android-apt' to the beginning of the android file but if it works without it then it works.