-1

i am developing an android news reader apps. I have a AsyncTask that implements Serializable, so that i can save instance. I use it to handle the app refresh when rotating my phone. It work, when i rotate my apps, the task still running. but when the task is running, and i press the home button/back button to close my apps, my apps become force closed. Is there anything wrong with my code?

@Override
protected void onSaveInstanceState(final Bundle outState) {
    // super.onSaveInstanceState(outState);
    outState.putInt("curPage", mPager.getCurrentItem());
    outState.putInt("drawerPos", drawerPos);
    outState.putSerializable("task", task);
    if (dialog != null) {
        outState.putBoolean("isDialogShowing", dialog.isShowing());
    } else {
        outState.putBoolean("isDialogShowing", false);
    }
    // outState.putSerializable("dialog", dialog);
}

// dismiss dialog if activity is destroyed
@Override
protected void onDestroy() {
    if (dialog != null && dialog.isShowing()) {
        dialog.dismiss();
        dialog = null;
    }
    if (task.getStatus() == AsyncTask.Status.RUNNING)
        task.cancel(true);
    task = null;
    super.onDestroy();
}

MyAsyncTask:

public class AsyncTaskRefreshRss extends
    AsyncTask<String, String, ArrayList<BeritaHeader>> implements Serializable{

/**
 * 
 */
private static final long serialVersionUID = 3385729493967673390L;

private OnResponseListener responder;

// MyAlertDialogFragment myDialog;
ProgressDialog dialog;
FragmentManager fm;
Context context;
String type;
String subtype;

public AsyncTaskRefreshRss(Context context, FragmentManager fm,
        String type, String subtype, OnResponseListener listener) {
    this.fm = fm;
    this.context = context;
    this.type = type;
    this.subtype = subtype;
    this.responder = listener;
}

public void setFinishListener(OnResponseListener listener){
    this.responder = listener;
}

public void setDialog(ProgressDialog dialog) {
    this.dialog = dialog;
}

@Override
protected void onPreExecute() {
    dialog.show();
}

@Override
protected ArrayList<BeritaHeader> doInBackground(String... arg0) {
    MyWebService ws = new MyWebService();
    try {
        return ws.GetRSS(type, subtype);
    } catch (Exception e) {
        return null;
    }

}

public interface OnResponseListener {
    public void onSuccess();

    public void onFailure();
}

@Override
protected void onPostExecute(ArrayList<BeritaHeader> result) {
    if (dialog.isShowing())
        dialog.dismiss();
    if (result != null) {
        NewsDataSource ds = new NewsDataSource(context);
        ds.deleteAllBerita(type, subtype);
        ds.createBerita(result, type, subtype);
        responder.onSuccess();
    } else {
        Toast toast = Toast.makeText(context, "Gagal memuat",
                Toast.LENGTH_LONG);
        toast.show();
        responder.onFailure();
    }
    // asyncState = DO_NOTHING;
}

public static class MyAlertDialogFragment extends DialogFragment {

    public boolean isCanceled;

    public static MyAlertDialogFragment newInstance() {
        MyAlertDialogFragment frag = new MyAlertDialogFragment();
        return frag;
    }

    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final ProgressDialog dialog = new ProgressDialog(getActivity());
        dialog.setMessage("Sedang Memuat");
        dialog.setIndeterminate(false);
        dialog.setCancelable(false);
        dialog.setOnCancelListener(new OnCancelListener() {

            @Override
            public void onCancel(DialogInterface dialog) {
                // TODO Auto-generated method stub
                isCanceled = true;
            }
        });
        isCanceled = false;
        return dialog;
    }

}
}

My logcat:

07-19 19:37:00.905: E/AndroidRuntime(29243): FATAL EXCEPTION: main
07-19 19:37:00.905: E/AndroidRuntime(29243): java.lang.RuntimeException: Parcelable encountered IOException writing serializable object (name = com.karyadigital.beritaku.berita.AsyncTaskRefreshRss)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at android.os.Parcel.writeSerializable(Parcel.java:1279)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at android.os.Parcel.writeValue(Parcel.java:1233)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at android.os.Parcel.writeMapInternal(Parcel.java:591)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at android.os.Bundle.writeToParcel(Bundle.java:1619)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at android.os.Parcel.writeBundle(Parcel.java:605)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at android.app.ActivityManagerProxy.activityStopped(ActivityManagerNative.java:2247)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at android.app.ActivityThread$StopInfo.run(ActivityThread.java:2915)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at android.os.Handler.handleCallback(Handler.java:615)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at android.os.Handler.dispatchMessage(Handler.java:92)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at android.os.Looper.loop(Looper.java:137)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at android.app.ActivityThread.main(ActivityThread.java:4898)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at java.lang.reflect.Method.invokeNative(Native Method)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at java.lang.reflect.Method.invoke(Method.java:511)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1008)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:775)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at dalvik.system.NativeStart.main(Native Method)
07-19 19:37:00.905: E/AndroidRuntime(29243): Caused by: java.io.NotSerializableException: android.app.Application
07-19 19:37:00.905: E/AndroidRuntime(29243):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1364)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at java.io.ObjectOutputStream.writeFieldValues(ObjectOutputStream.java:979)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at java.io.ObjectOutputStream.defaultWriteObject(ObjectOutputStream.java:368)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at java.io.ObjectOutputStream.writeHierarchy(ObjectOutputStream.java:1074)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at java.io.ObjectOutputStream.writeNewObject(ObjectOutputStream.java:1404)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at java.io.ObjectOutputStream.writeObjectInternal(ObjectOutputStream.java:1671)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1517)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:1481)
07-19 19:37:00.905: E/AndroidRuntime(29243):    at android.os.Parcel.writeSerializable(Parcel.java:1274)
07-19 19:37:00.905: E/AndroidRuntime(29243):    ... 15 more
mutokenji
  • 525
  • 1
  • 5
  • 14

2 Answers2

2

You just can't make an AsyncTask Serializable and serialize it. Why: you just can't make because the system will try to serialize all its fields and so on for each field's fields. And if a field is not Serializable and not marked with transient then you'll get above Exception.

If you want to decouple the AsyncTask from the Activity when the Activity is recreated, use the configuration changes with Fragments. Here's an article that describes how to.

gunar
  • 14,660
  • 7
  • 56
  • 87
0

This fails due to the Context field in your class. Context objects are not serializable.

"When traversing a graph, an object may be encountered that does not support the Serializable interface. In this case the NotSerializableException will be thrown and will identify the class of the non-serializable object."

You can either remove the Context field entirely, or apply the transient attribute to the Context field so that it is not serialized.

public class MyClass implements Serializable 
{
    ...
    public transient Context myContext;
    ...
}
Mukesh Kumar Singh
  • 4,512
  • 2
  • 22
  • 30