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 trialMichael Lane
4,408 PointsDo Butterknife bindings fail? My code compiles, runs then fails on first line in updateDisplay().
I have tested the code, and attempted to isolate the error. Logcat details indicate that the error is occurring on the first executable line of the updateDisplay() method. If I put in a log.d call to write the temperature value to the log - it does. If I comment out the mTemperatureLabel.setText() line, then the failure moves to the next line. Logging values from getCurrentDetails() and directly from mCurrentWeather indicate that the JSON data is being received correctly. I just can't get it to display correctly. I suspect that the culprit is the Butterknife bindings (yes I am using @Bind).
3 Answers
Ben Deitch
Treehouse TeacherHey Michael! Check out the previous video at about the 1:25 mark :)
Michael Lane
4,408 PointsThanks Ben. Somehow that part had been overlooked.
Michael Lane
4,408 PointsHey Ben,
code as follows
public class MainActivity extends ActionBarActivity {
public static final String TAG = MainActivity.class.getSimpleName();
private CurrentWeather mCurrentWeather;
@Bind(R.id.timeLabel) TextView mTimeLabel;
@Bind(R.id.temperatureLabel) TextView mTemperatureLabel;
@Bind(R.id.humidityValue) TextView mHumidityValue;
@Bind(R.id.precipValue) TextView mPrecipValue;
@Bind(R.id.summaryLabel) TextView mSummaryLabel;
@Bind(R.id.iconImageView) ImageView mIconImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
String apiKey = "107b299143955ec47685c28b02686128";
double latitude = -34.673686;
double longitude = 148.633763;
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(Request request, IOException e) {
}
@Override
public void onResponse(Response response) throws IOException {
try {
String jsonData = response.body().string();
Log.v(TAG, jsonData);
if (response.isSuccessful()) {
mCurrentWeather = getCurrentDetails(jsonData);
Log.d(TAG, String.valueOf(mCurrentWeather.getTemperature()));
updateDisplay();
} else {
//Log.v(TAG, response.body().string());
alertUserAboutError();
}
} catch (IOException e) {
Log.e(TAG, "Exception caught: ", e);
} catch (JSONException e) {
Log.e(TAG, "Exception caught: ", e);
}
}
});
} else {
Toast.makeText(this, getString(R.string.network_unavailable), Toast.LENGTH_LONG).show();
}
Log.d(TAG, "Main UI code is running!");
}
private void updateDisplay() {
Log.d(TAG, String.valueOf(mCurrentWeather.getTemperature()));
mTemperatureLabel.setText(String.valueOf(mCurrentWeather.getTemperature()) + "");
mTimeLabel.setText("At " + mCurrentWeather.getFormattedTime() + " it will be: ");
mHumidityValue.setText(mCurrentWeather.getHumidity() + "");
mPrecipValue.setText(mCurrentWeather.getPrecipChance() + "%");
mSummaryLabel.setText(mCurrentWeather.getSummary());
Drawable drawable = getResources().getDrawable(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 currentWeather = new CurrentWeather();
currentWeather.setTime(currently.getLong("time"));
currentWeather.setHumidity(currently.getDouble("humidity"));
currentWeather.setIcon(currently.getString("icon"));
currentWeather.setSummary(currently.getString("summary"));
currentWeather.setPrecipChance(currently.getInt("precipProbability"));
currentWeather.setTemperature(currently.getDouble("temperature"));
currentWeather.setTimeZone(timezone);
Log.d(TAG, currentWeather.getFormattedTime());
Log.d(TAG, String.valueOf(currentWeather.getTemperature()));
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");
}
}
Runtime logcat messages:
''' 11-11 08:41:54.960 857-857/com.mikelane9143.stormy D/MainActivity: Main UI code is running! 11-11 08:42:01.370 857-939/com.mikelane9143.stormy I/MainActivity: From JSON: Australia/Sydney 11-11 08:42:01.400 857-939/com.mikelane9143.stormy D/MainActivity: 12:42 AM 11-11 08:42:01.400 857-939/com.mikelane9143.stormy D/MainActivity: 59.71 11-11 08:42:01.400 857-939/com.mikelane9143.stormy D/MainActivity: 59.71 11-11 08:42:01.410 857-939/com.mikelane9143.stormy D/MainActivity: 59.71 11-11 08:42:01.450 857-939/com.mikelane9143.stormy E/AndroidRuntime: at com.mikelane9143.stormy.MainActivity.updateDisplay(MainActivity.java:96) 11-11 08:42:01.450 857-939/com.mikelane9143.stormy E/AndroidRuntime: at com.mikelane9143.stormy.MainActivity.access$200(MainActivity.java:29) 11-11 08:42:01.450 857-939/com.mikelane9143.stormy E/AndroidRuntime: at com.mikelane9143.stormy.MainActivity$1.onResponse(MainActivity.java:75) '''
Ben Deitch
Treehouse TeacherHmm not sure. We should be able to see a more descriptive error message though. If you change the Log Level to 'Error' and change the box at the top right of Logcat to 'No Filters', are you able to see more about the error?
Michael Lane
4,408 PointsLogcat with No filters and Error level gives:
''' 11-12 07:33:29.690 902-933/com.mikelane9143.stormy E/AndroidRuntime: at com.mikelane9143.stormy.MainActivity.updateDisplay(MainActivity.java:96) 11-12 07:33:29.690 902-933/com.mikelane9143.stormy E/AndroidRuntime: at com.mikelane9143.stormy.MainActivity.access$200(MainActivity.java:29) 11-12 07:33:29.690 902-933/com.mikelane9143.stormy E/AndroidRuntime: at com.mikelane9143.stormy.MainActivity$1.onResponse(MainActivity.java:75) 11-12 07:33:37.800 359-388/system_process E/InputDispatcher: channel 'b3100858 com.mikelane9143.stormy/com.mikelane9143.stormy.MainActivity (server)' ~ Channel is unrecoverably broken and will be disposed! '''
Michael Lane
4,408 PointsAlso worth noting - the code did work until adding in the Icon feature
Ben Deitch
Treehouse TeacherBen Deitch
Treehouse TeacherHey Michael! Could you post the problematic code? And maybe the error message you get as well?