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

SOLVED :: Parcelable encountered IOException writing serializable object (name = package.weather.Day;)

While trying to re-follow the weather app (2nd part) I decided to change things up this time and make both the day and the hour a recycler view. I finally got the hourly working but I ran in to a weird issue in the day (where the deviation form the course takes place.)

06-03 13:53:34.786 15574-15574/me.johnweland.tempest E/AndroidRuntime: FATAL EXCEPTION: main
 Process: me.johnweland.tempest, PID: 15574
 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
     at me.johnweland.tempest.adapter.DayAdapter$DayViewHolder.bindDay(DayAdapter.java:55)
     at me.johnweland.tempest.adapter.DayAdapter.onBindViewHolder(DayAdapter.java:31)
     at me.johnweland.tempest.adapter.DayAdapter.onBindViewHolder(DayAdapter.java:13)
     at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:5471)
     at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:5504)
     at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4741)
     at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4617)
     at android.support.v7.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:1994)
     at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1390)
     at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1353)
     at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:574)
     at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3028)
     at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:2906)
     at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3283)
     at android.view.View.layout(View.java:17508)
     at android.view.ViewGroup.layout(ViewGroup.java:5555)
     at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1079)
     at android.view.View.layout(View.java:17508)
     at android.view.ViewGroup.layout(ViewGroup.java:5555)
     at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
     at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
     at android.view.View.layout(View.java:17508)
     at android.view.ViewGroup.layout(ViewGroup.java:5555)
     at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1737)
     at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1581)
     at android.widget.LinearLayout.onLayout(LinearLayout.java:1490)
     at android.view.View.layout(View.java:17508)
     at android.view.ViewGroup.layout(ViewGroup.java:5555)
     at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
     at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
     at com.android.internal.policy.DecorView.onLayout(DecorView.java:701)
     at android.view.View.layout(View.java:17508)
     at android.view.ViewGroup.layout(ViewGroup.java:5555)
     at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2319)
     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2049)
     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1240)
     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6298)
     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:858)
     at android.view.Choreographer.doCallbacks(Choreographer.java:670)
     at android.view.Choreographer.doFrame(Choreographer.java:606)
     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:844)
     at android.os.Handler.handleCallback(Handler.java:751)
     at android.os.Handler.dispatchMessage(Handler.java:95)
     at android.os.Looper.loop(Looper.java:154)
     at android.app.ActivityThread.main(ActivityThread.java:5969)
     at java.lang.reflect.Method.invoke(Native Method)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:801)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:691)
day.java
package me.johnweland.tempest.weather;

import android.os.Parcel;
import android.os.Parcelable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

public class Day implements Parcelable {
    private long mTime;
    private String mSummary;
    private double mTempMax;
    private double mTempMin;
    private String mIcon;
    private String mTimezone;

    public Day(){}

    public long getTime() {
        return mTime;
    }

    public void setTime(long time) {
        mTime = time;
    }

    public String getSummary() {
        return mSummary;
    }

    public void setSummary(String summary) {
        mSummary = summary;
    }

    public int getTempMax() {
        return (int) Math.round(mTempMax);
    }

    public void setTempMax(double tempMax) {
        mTempMax = tempMax;
    }

    public int getTempMin() {
        return (int) Math.round(mTempMin);
    }

    public void setTempMin(double tempMin) {
        mTempMin = tempMin;
    }

    public String getIcon() {
        return mIcon;
    }

    public void setIcon(String icon) {
        mIcon = icon;
    }

    public int getIconId() {
        return Forecast.getIconId(mIcon);
    }

    public String getTimezone() {
        return mTimezone;
    }

    public void setTimezone(String timezone) {
        mTimezone = timezone;
    }

    public String getDayOfTheWeek() {
        SimpleDateFormat formatter = new SimpleDateFormat("EEEE");
        formatter.setTimeZone(TimeZone.getTimeZone(getTimezone()));
        Date dateTime = new Date(mTime * 1000);
        return formatter.format(dateTime);
    }


    @Override
    public int describeContents() {
        return 0; // ignore
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeLong(mTime);
        dest.writeDouble(mTempMax);
        dest.writeDouble(mTempMin);
        dest.writeString(mSummary);
        dest.writeString(mIcon);
        dest.writeString(mTimezone);
    }
    private Day(Parcel in) {
        mTime = in.readLong();
        mTempMax = in.readDouble();
        mTempMin = in.readDouble();
        mSummary = in.readString();
        mIcon = in.readString();
        mTimezone = in.readString();
    }

    public static final Creator<Day> CREATOR = new Creator<Day>() {
        @Override
        public Day createFromParcel(Parcel source) {
            return new Day(source);
        }

        @Override
        public Day[] newArray(int size) {
            return new Day[size];
        }
    };
}
DailyActivity.java
package me.johnweland.tempest.ui;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.widget.ArrayAdapter;

import java.util.Arrays;
import butterknife.BindView;
import butterknife.ButterKnife;
import me.johnweland.tempest.R;
import me.johnweland.tempest.adapter.DayAdapter;
import me.johnweland.tempest.weather.Day;

public class DailyActivity extends Activity {

    private Day[] mDays;

    @BindView(R.id.dailyRecyclerView) RecyclerView mRecyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_daily);
        ButterKnife.bind(this);

        String[] daysOfTheWeek = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };

        Intent intent = getIntent();
        Parcelable[] parcelables = intent.getParcelableArrayExtra(MainActivity.DAILY_FORECAST);

        mDays = Arrays.copyOf(parcelables, parcelables.length, Day[].class);

        DayAdapter adapter = new DayAdapter(mDays);
        mRecyclerView.setAdapter(adapter);

        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(layoutManager);

        mRecyclerView.setHasFixedSize(true);

    }

}
DayAdapter.java
package me.johnweland.tempest.adapter;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import me.johnweland.tempest.R;
import me.johnweland.tempest.weather.Day;

public class DayAdapter extends RecyclerView.Adapter<DayAdapter.DayViewHolder> {

    private Day[] mDays;

    public DayAdapter(Day[] days) {
        mDays = days;
    }

    @Override
    public DayViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.daily_list_item, parent, false);
        DayViewHolder viewHolder = new DayViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(DayViewHolder holder, int position) {
        holder.bindDay(mDays[position]);
    }

    @Override
    public int getItemCount() {
        return mDays.length;
    }

    public class DayViewHolder extends RecyclerView.ViewHolder {
        public TextView mTimeLabel;
        public TextView mSummaryLabel;
        public TextView mTemperatureLabel;
        public ImageView mIconImageView;


        public DayViewHolder(View itemView) {
            super(itemView);
            mTimeLabel = (TextView) itemView.findViewById(R.id.timeLabel);
            mSummaryLabel = (TextView) itemView.findViewById(R.id.summaryLabel);
            mTemperatureLabel = (TextView) itemView.findViewById(R.id.tempHiLowLabel);
            mIconImageView = (ImageView) itemView.findViewById(R.id.iconImageView);
        }

        public void bindDay(Day day){
            mTimeLabel.setText(day.getDayOfTheWeek());
            mSummaryLabel.setText(day.getSummary());
            mTemperatureLabel.setText(day.getTempMax() + " / "  + day.getTempMin());
            mIconImageView.setImageResource(day.getIconId());
        }

    }
}
daily_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                tools:background="@drawable/bg_gradient"
                android:paddingTop="8dp"
                android:paddingBottom="8dp"
                android:paddingLeft="64dp"
                android:paddingRight="32dp">

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/circleImageView"
        android:src="@drawable/bg_temperature"
        android:layout_centerVertical="true"/>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/iconImageView"
        android:src="@drawable/partly_cloudy"
        android:layout_centerVertical="true"
        android:layout_toRightOf="@id/circleImageView"
        android:layout_toEndOf="@id/circleImageView"
        android:paddingLeft="10dp"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:text="Today"
        android:id="@+id/dayNameLabel"
        android:textColor="@android:color/white"
        android:textSize="20sp"
        android:layout_centerVertical="true"
        android:layout_toRightOf="@id/iconImageView"
        android:layout_toEndOf="@id/iconImageView"
        android:paddingLeft="10dp"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        tools:text="100 \n / \n 80"
        android:id="@+id/tempHiLowLabel"
        android:textColor="#f25019"
        android:textAlignment="center"
        android:gravity="center"
        android:layout_alignTop="@id/circleImageView"
        android:layout_alignBottom="@id/circleImageView"
        android:layout_alignLeft="@id/circleImageView"
        android:layout_alignRight="@id/circleImageView"/>

</RelativeLayout>
activity_daily.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context="me.johnweland.tempest.ui.DailyActivity"
    android:background="@drawable/bg_gradient">

    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/dailyRecyclerView"
        android:layout_below="@+id/thisWeekLabel"
        android:layout_above="@+id/locationLabel">

    </android.support.v7.widget.RecyclerView>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="This Week's Weather"
        android:textColor="@android:color/white"
        android:textSize="24sp"
        android:layout_marginTop="16dp"
        android:id="@+id/thisWeekLabel"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Alcatraz Island, CA"
        android:textColor="@android:color/white"
        android:textSize="18sp"
        android:layout_marginBottom="16dp"
        android:id="@+id/locationLabel"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"/>

</RelativeLayout>

I think this has to do with the String[] daysOfTheWeek which I haven't figured out how to make work in the recycler view Ben Jakuben does it here in the default adapter video.

1 Answer

SOLVED:: As it turns out I fell asleep during the coding of this today for a bit and ended up telling my code to set text to things that don't exist.