Search code examples
androidbadparcelableexception

Parcelebles ClassNotFoundException RecyclerView


I am new to android kindly bare with my question id it too basic. I tried my best to find solution online but couldnt. I was trying out RecyclerView Concepts.

While Copying array of data to parcelebles array I am getting an error stating "Class not found when unmarshalling: java.lang.ClassNotFoundException: Invalid name:"

MainActivity Code :

public class MainActivity extends ActionBarActivity {



@InjectView(R.id.idTemparatureValue) TextView mTemparatureValue;
@InjectView(R.id.idHumidityValue) TextView mHumidityValue;
@InjectView(R.id.idRainValue) TextView mRainValue;
@InjectView(R.id.idSummaryValue) TextView mSummaryValue;
@InjectView(R.id.idTimeValue) TextView mTimeValue;



private final String TAG=MainActivity.class.getSimpleName();
public static final String DAILY_FORECAST="DAILY_FORECAST";
public static final String HOURLY_FORECAST="HOURLY_FORECAST";

private String apiKey="******************";
private double latitude =13.0827;
private double longitude =80.2707;
Forecast mForecast = new Forecast();


private String url;/*="https://api.forecast.io/forecast/"+apiKey+"/"+latitude+","+longitude;*/


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);



    ButterKnife.inject(this);

    if(isNetworkAvailable()){

        url="https://api.forecast.io/forecast/"+apiKey+"/"+latitude+","+longitude;
        Log.i(TAG,url);
        OkHttpClient okHttpClient = new OkHttpClient();
        Request request = new Request.Builder().url(url).build();
        Call call=okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {



            }
  @Override
            public void onResponse(Response response) throws IOException {
                try{
                    if(response.isSuccessful()){
                        String jsonData=response.body().string();
                        Log.v(TAG, jsonData);
                        Log.d(TAG, url);
                        mForecast =parseForcastData(jsonData);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                updateUIScreen();
                            }
                        });

                    }else{
                        alertUserOnFailure();
                    }
                }catch(IOException e){
                    Log.e(TAG,"Caught Exception : "+e);
                }catch(JSONException e){
                    Log.e(TAG,"Caught JSON Exception at onResponse(): "+e);
                    e.printStackTrace();
                }








            }
        });
    }else{
        alertUserOnNetworkFailure();
        Toast.makeText(this,"Network illa da koomoota !",Toast.LENGTH_LONG).show();
    }



}





private Forecast parseForcastData(String jsonData) throws JSONException{

    Forecast mForecast=new Forecast();

    mForecast.setCurrent(getCurrentDetails(jsonData));
    mForecast.setHours(getHourlyDetails(jsonData));
    mForecast.setDay(getDailyDetails(jsonData));
    return mForecast;


}

private Day[] getDailyDetails(String jsonData) throws JSONException {

        JSONObject forecast=new JSONObject(jsonData);
        JSONObject dailyJson=forecast.getJSONObject("daily");

        String icon=dailyJson.getString("icon");
        String timeZone=forecast.getString("timezone");
        JSONArray dailyJsonArray=dailyJson.getJSONArray("data");
        Day days[]=new Day[dailyJsonArray.length()];
        for(int i=0;i<dailyJsonArray.length();i++){
            Day day=new Day();
            JSONObject dailyJsonData=dailyJsonArray.getJSONObject(i);
            day.setSummary(dailyJsonData.getString("summary"));
            day.setIcon(icon);
            day.setTime(dailyJsonData.getLong("time"));
            day.setTimeZone(timeZone);
            day.setTemparatureMax(dailyJsonData.getInt("temperatureMax"));
            days[i]=day;
        }




    return days;

}


private Hour[] getHourlyDetails(String jsonData) throws JSONException{

    JSONObject forecast=new JSONObject(jsonData);
    String timeZone=forecast.getString("timezone");
    JSONObject hourly=forecast.getJSONObject("hourly");
    JSONArray data=hourly.getJSONArray("data");
    Hour[] hours=new Hour[data.length()];
    for(int i=0;i<data.length();i++){
        Hour hour=new Hour();
        JSONObject hourData=data.getJSONObject(i);

        hour.setSummary(hourData.getString("summary"));
        hour.setIcon(hourData.getString("icon"));
        hour.setTime(hourData.getLong("time"));
        hour.setTemparature(hourData.getDouble("temperature"));
        hour.setTimezone(timeZone);
        hours[i]=hour;


    }
    return hours;


}


private Current getCurrentDetails(String jsonData) throws JSONException{

    Current current = new Current();

    JSONObject forecast=new JSONObject(jsonData);
    String timezone=forecast.getString("timezone");
    current.setTimeZone(timezone);
    Log.i(TAG, timezone);
    JSONObject currently =forecast.getJSONObject("currently");
    current.setHumidity(currently.getDouble("humidity"));
    current.setIcon(currently.getString("icon"));
    current.setPreciptationChance(currently.getDouble("precipProbability"));
    current.setTemparature(currently.getDouble("temperature"));

    current.setSummary(currently.getString("summary"));
    current.setTime(currently.getLong("time"));





    return current;
}



private void updateUIScreen() {
    Current current=mForecast.getCurrent();

    Log.i(TAG, current.getTemparature() + "");

    mTemparatureValue.setText(current.getFormattedTemparature());
    mHumidityValue.setText(current.getHumidity() + "");
    mRainValue.setText(current.getPreciptationChance() + "");
    mTimeValue.setText("At " + current.getFormattedTime() + " it will be ");
    mSummaryValue.setText(current.getSummary());



}

private void alertUserOnNetworkFailure() {
    NetworkAlertDialogFragment networkDialogFragment=new NetworkAlertDialogFragment();
    networkDialogFragment.show(getFragmentManager(), "error_network_dialog");


}


private void alertUserOnFailure() {

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



}



private boolean isNetworkAvailable() {

    boolean networkStatus=false;
    ConnectivityManager manager= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo info = manager.getActiveNetworkInfo();
    assert info != null;
    if(info!=null && info.isAvailable() && info.isConnected()){
        networkStatus=true;
    }

    return networkStatus;
}

@OnClick (R.id.idDaily)
public void startDailyActivity(){
    Intent intent=new Intent(this,DailyForecastActivity.class);
    intent.putExtra(DAILY_FORECAST,mForecast.getDay());
    startActivity(intent);
}

@OnClick (R.id.idHourly)
public void startHourlyActivity(){
    Intent intent=new Intent(this,HourlyForecastActivity.class);
    intent.putExtra(HOURLY_FORECAST,mForecast.getHours());
    startActivity(intent);
}

Recycler View Adapter Code :

public class HourlyForecastActivity extends ActionBarActivity {

    Hour[] mHours;

    @InjectView(R.id.idRecylerView)
    RecyclerView mRecyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_hourly_forecast);
        ButterKnife.inject(this);
        Intent intent=getIntent();
        Parcelable[] parcelables=intent.getParcelableArrayExtra(MainActivity.HOURLY_FORECAST);
        mHours= Arrays.copyOf(parcelables,parcelables.length,Hour[].class);
        HourlyAdapter adapter=new HourlyAdapter(mHours);
        mRecyclerView.setAdapter(adapter);
        RecyclerView.LayoutManager layoutManager=new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(layoutManager);
        mRecyclerView.setHasFixedSize(true);


    }

Forecast class

package com.example.ragesh.myweather;

/**
 * Created by ragesh on 11/6/15.
 */
public class Forecast {

    private Hour[] mHours;
    private Day[] mDay;
    private Current mCurrent;

    public Hour[] getHours() {
        return mHours;
    }

    public void setHours(Hour[] hours) {
        mHours = hours;
    }

    public Day[] getDay() {
        return mDay;
    }

    public void setDay(Day[] day) {
        mDay = day;
    }

    public Current getCurrent() {
        return mCurrent;
    }

    public void setCurrent(Current current) {
        mCurrent = current;
    }

    public static int getIconId(){
        return R.mipmap.partly_cloudy;
    }
}

Hour class

package com.example.ragesh.myweather;

import android.os.Parcel;
import android.os.Parcelable;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by ragesh on 11/6/15.
 */
public class Hour implements Parcelable{

    private long mTime;
    private String mSummary;
    private double mTemparature;
    private String mIcon;
    private String mTimezone;

    public Hour(Parcel in) {
        mSummary=in.readString();
        mTime=in.readLong();
        mTemparature=in.readDouble();
        mIcon=in.readString();
    }

    public Hour() {

    }

    public String getHour(){
        SimpleDateFormat format=new SimpleDateFormat("h a");
        Date date=new Date(mTime*1000);
            return format.format(date);
    }

    public String getTimezone() {
        return mTimezone;
    }

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

    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 getTemparature() {
        return (int) Math.round(mTemparature);
    }

    public void setTemparature(double temparature) {
        mTemparature = temparature;
    }

    public String getIcon() {
        return mIcon;
    }

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


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

    @Override
    public void writeToParcel(Parcel dest, int flags) {

        dest.writeString(mSummary);
        dest.writeDouble(mTemparature);
        dest.writeString(mIcon);
        dest.writeLong(mTime);

    }

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

        @Override
        public Hour[] newArray(int size) {
            return new Hour[size];
        }
    };
}

Logs :

07-15 14:59:20.708    2554-2572/com.example.ragesh.myweather I/MainActivity﹕ Asia/Kolkata
07-15 14:59:20.770    2554-2554/com.example.ragesh.myweather I/MainActivity﹕ 85.0
07-15 14:59:23.777    2554-2562/com.example.ragesh.myweather W/art﹕ Suspending all threads took: 8.576ms
07-15 14:59:23.834    2554-2554/com.example.ragesh.myweather E/Parcel﹕ Class not found when unmarshalling:
    java.lang.ClassNotFoundException: Invalid name:
            at java.lang.Class.classForName(Native Method)
            at java.lang.Class.forName(Class.java:309)
            at android.os.Parcel.readParcelableCreator(Parcel.java:2281)
            at android.os.Parcel.readParcelable(Parcel.java:2245)
            at android.os.Parcel.readParcelableArray(Parcel.java:2338)
            at android.os.Parcel.readValue(Parcel.java:2206)
            at android.os.Parcel.readArrayMapInternal(Parcel.java:2485)
            at android.os.BaseBundle.unparcel(BaseBundle.java:221)
            at android.os.Bundle.getParcelableArray(Bundle.java:777)
            at android.content.Intent.getParcelableArrayExtra(Intent.java:5112)
            at com.example.ragesh.myweather.HourlyForecastActivity.onCreate(HourlyForecastActivity.java:32)
            at android.app.Activity.performCreate(Activity.java:6010)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1129)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2292)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2413)
            at android.app.ActivityThread.access$800(ActivityThread.java:155)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5343)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
07-15 14:59:23.835    2554-2554/com.example.ragesh.myweather D/AndroidRuntime﹕ Shutting down VM
07-15 14:59:23.836    2554-2554/com.example.ragesh.myweather E/AndroidRuntime﹕ FATAL EXCEPTION: main
    Process: com.example.ragesh.myweather, PID: 2554
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ragesh.myweather/com.example.ragesh.myweather.HourlyForecastActivity}: android.os.BadParcelableException: ClassNotFoundException when unmarshalling:
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2339)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2413)
            at android.app.ActivityThread.access$800(ActivityThread.java:155)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5343)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)
     Caused by: android.os.BadParcelableException: ClassNotFoundException when unmarshalling:
            at android.os.Parcel.readParcelableCreator(Parcel.java:2295)
            at android.os.Parcel.readParcelable(Parcel.java:2245)
            at android.os.Parcel.readParcelableArray(Parcel.java:2338)
            at android.os.Parcel.readValue(Parcel.java:2206)
            at android.os.Parcel.readArrayMapInternal(Parcel.java:2485)
            at android.os.BaseBundle.unparcel(BaseBundle.java:221)
            at android.os.Bundle.getParcelableArray(Bundle.java:777)
            at android.content.Intent.getParcelableArrayExtra(Intent.java:5112)
            at com.example.ragesh.myweather.HourlyForecastActivity.onCreate(HourlyForecastActivity.java:32)
            at android.app.Activity.performCreate(Activity.java:6010)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1129)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2292)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2413)
            at android.app.ActivityThread.access$800(ActivityThread.java:155)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1317)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:135)
            at android.app.ActivityThread.main(ActivityThread.java:5343)
            at java.lang.reflect.Method.invoke(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:372)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:905)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:700)

Solution

  • Reading and writing must be in same order or your Parcelable class will fail. Your reading and writing are not in the same order:

     public Hour(Parcel in) {
        mSummary=in.readString();
        mTime=in.readLong();
        mTemparature=in.readDouble();
        mIcon=in.readString();
    } 
    
    @Override 
    public void writeToParcel(Parcel dest, int flags) {
    
        dest.writeString(mSummary);
        dest.writeDouble(mTemparature);
        dest.writeString(mIcon);
        dest.writeLong(mTime);
    
    } 
    

    Fix your class using Parcelabler here: http://www.parcelabler.com/