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 trialMark Junge
1,374 PointsNullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on
My code looks like this (as in the video)
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();
}
});
private void updateDisplay() {
(xx) mTemperatureLabel.setText(mCurrentWeather.getTemperature() + "");
// mTimeLabel.setText(" At " + mCurrentWeather.getFormatedTime() + " it will be ");
}
I wonder why i cant run, it constantly stop the stormy app. It is line (xx) that is the problem, if i note it out, the app run with my hard coded numbers and text.
Have used 2 hours on this problem now, please help me someone :-)
Seth Kroger
56,413 PointsGood to hear! Glad you got it working.
5 Answers
Seth Kroger
56,413 PointsMake sure you are following the the latest instructions on installing and using ButterKnife from it's GitHub page. If that doesn't solve the problem we might have to look the whole MainActivity code to get a better picture.
Mark Junge
1,374 PointsThis is my stormy build.gradle
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
---------------------------------------------------------This is my app build.gradle----------------------------------------------------------
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "com.example.ideap.stormy"
minSdkVersion 14
targetSdkVersion 23
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:23.3.0'
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.jakewharton:butterknife:8.4.0'
}
-------------------------------------------------------This is my code from main-------------------------------------------------------------
package com.example.ideap.stormy;
import android.app.DownloadManager;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.nfc.Tag;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
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.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 = "78c0cc91ee5bab1d0b13f699f08459ef";
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_LONG).show();
}
Log.d(TAG, "Main UI Code is running!" );
}
private void updateDisplay() {
mTemperatureLabel.setText(mCurrentWeather.getTemperature() + "");
// mTimeLabel.setText(" At " + mCurrentWeather.getFormatedTime() + " it will be ");
}
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.getFormatedTime());
return currentweather;
}
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");
}
}
--------------------note related to: mTemperatureLabel.setText(mCurrentWeather.getTemperature()--------------------- Do not concatenate text displayed with setText. Use resource string with placeholders. less... (Ctrl+F1)
When calling TextView#setText
- Never call Number#toString() to format numbers; it will not handle fraction separators and locale-specific digits properly. Consider using String#format with proper format specifications (%d or %f) instead.
- Do not pass a string literal (e.g. "Hello") to display text. Hardcoded text can not be properly translated to other languages. Consider using Android resource strings instead.
- Do not build messages by concatenating text chunks. Such messages can not be properly translated.
Hopefully this can bring a better picture of my situation
btw. Thanks a lot ;-)
[mod edit - code formatting]
Seth Kroger
56,413 PointsYou got most of the butterknife configuration right but you're still missing the butterknife-compiler dependency. Once you add that, sync gradle and rebuild it should be fine. The other messages are warnings about best practice but they shouldn't affect your app being able to run.
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.jakewharton:butterknife:8.4.0'
apt 'com.jakewharton:butterknife-compiler:8.4.0' // <- add this line
}
Mark Junge
1,374 PointsWhen i try to add the line: apt 'com.jakewharton:butterknife-compiler:8.4.0'
Then this occurs Error:(30, 0) Could not find method apt() for arguments [com.jakewharton:butterknife-compiler:8.4.0] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler. <a href="openFile:C:\Users\ideap\Downloads\WeeDo 2.0\Stormy\app\build.gradle">Open File</a>
Hope it still makes sense for you, so I can do something else to make it work.
TNX again, I really appreciate it :-)
Seth Kroger
56,413 PointsOops, I missed that you also forgot the line apply plugin: 'android-apt'
in build.gradle too. It should be after the apply plugin: 'com.android.application'
line.
Kevin Perez
Courses Plus Student 8,180 PointsModule: app
apply plugin: 'com.android.application'
apply plugin: 'android-apt'
kris Moore
1,752 Pointsadd compile 'com.jakewharton:butterknife:8.4.0' annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0' to the module: app for the build.gradle
Emily Conroyd
6,512 PointsThis was my solution which used a bit of everyones here with a slight twist. I needed the 2nd class path in addition to the new line in the project: app.
Module: app ____________________________________________________________________
dependencies { classpath 'com.android.tools.build:gradle:1.3.0' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' <--------- needed this last line too after adding the other 3 before it built without errors }
Project: Stormy ___________________________________________________________________ apply plugin: 'com.android.application' apply plugin: 'android-apt' <-------------------------------- also added this to work with the apt 'com.jakewharton:butterknife-compiler:8.5.1'
dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile files('libs/okhttp-3.6.0.jar') testCompile 'junit:junit:4.12' compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.squareup.okhttp3:okhttp:3.6.0' compile('com.jakewharton:butterknife:8.5.1') { exclude module: 'support-compat' <---------------------------- to get the jakewharton to work } apt 'com.jakewharton:butterknife-compiler:8.5.1' <--------------------------
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
}
kerimcharyev
1,589 PointsYou should add in build.gradle
compile 'com.jakewharton:butterknife:8.5.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'
Mark Junge
1,374 PointsMark Junge
1,374 PointsI have missed this on Butterknife description,
Note: If you are using the new Jack compiler with version 2.2.0 or newer you do not need the 'android-apt' plugin and can instead replace apt with annotationProcessor when declaring the compiler dependency. and have updated my Android to 2.2.2 since last time :-)
Now it works fine
Tank you both :-)