0

I have an android app which uses several singleton objects. These objects are used in many activities. When an exception is thrown in an activity different fields in my singletons become null and all other activities also throw exceptions. For example I have a singleton class to handle my cookie which has a static HTTPCookie field , and if in any activity an exception occurs this cookie field becomes null too.

I would like to know why is this happening. How can I prevent this from happening?

UPDATE: code for one of my singletons.

public class CookieHandler {

public interface CookieHandlerCallback {
    void OnNewCookieReceived();
    void OnNewCookieFailed();
}

public static HttpCookie myCookie;
private static CookieHandler singleton = new CookieHandler();
private static CookieHandlerCallback cookieHandler;
private static Context context;

public static CookieHandler getInstance() {
    return singleton;
}

private CookieHandler() {
}

public HttpCookie getMyCookie() {
    return myCookie;
}

public static void setupInterface(CookieHandlerCallback co) {
    cookieHandler = co;
}


public static void getNewCookie() {

    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
    final SharedPreferences.Editor editor = prefs.edit();

    Gson gson = new Gson();
    String json = prefs.getString("cookie", "");
    myCookie = gson.fromJson(json, HttpCookie.class);



    AppidoRetroAPI apiRetro = RetrofitService.getAppidoAPI();
    Call<ResponseBody> call = apiRetro.getCookie(myCookie == null ? "" : myCookie.getValue());
    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
            if (response.code() == 401) {

                Log.d("app process", "my debug" + "requestCategories in code 401 ");
                String headerCookie = response.headers().get(ApiCnst.COOKIES_HEADER);
                if (headerCookie != null) {
                    myCookie = new HttpCookie(ApiCnst.MY_COOKIE_NAME, headerCookie);
                    Gson gson = new Gson();
                    String json = gson.toJson(myCookie);
                    myCookie = gson.fromJson(json, HttpCookie.class);
                    editor.putString("cookie", json);
                    editor.commit();
                }

            } else if (response.code() == 200) {
                UserProfileInfo.getInstance().setIs_logged_in(true);
                try {
                    JSONObject jsonObject = new JSONObject(HttpManager.JsonTOString(response.body().byteStream()));
                    UserProfileInfo.getInstance().setUserJson(jsonObject);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                Log.d("app process", "my debug" + "requestCategories in code 200 ");

            }
            cookieHandler.OnNewCookieReceived();

        }

        @Override
        public void onFailure(Call<ResponseBody> call, Throwable t) {
            t.printStackTrace();
            cookieHandler.OnNewCookieFailed();
        }
    });
}

public static void updateContext(Context ctx) {
    context = ctx;
}
milad zahedi
  • 787
  • 6
  • 21

3 Answers3

1

When your app crashes then whole app process is restarted i.e. singletons also gets resets, you cant prevent your singleton becoming null when app crash but you can initialize when you app global application context is create.

make a class App.java

public class App extends Applications{
    @Override
    public void onCreate() {
        super.onCreate();
        initializeSingletons();
    }

    private void initializeSingletons(){
        // Initialize Singletons.
    }
}

and register this class in manifest

<application
        android:name=".App" // Register here
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
.
.
.

This will guaranteed to call before everything i.e. before broadcast, activity, service etc. so you can be sure that your singletons will never be null when your app crashes and restarts.

Nishant Pardamwar
  • 1,450
  • 12
  • 16
  • will this also preserve what is inside this singletons ? – milad zahedi Sep 10 '16 at 11:52
  • 1
    no content of singleton will not be preserveed, you have to store them somewhere like in sqlite db or sharedpreference, this will ensure thats when you initialize you singletons in this manner then they will never be completely null as even after a app crash your **initializeSingletons()** will be called and singletons will be loaded before they will be used by activities or some other component. – Nishant Pardamwar Sep 10 '16 at 11:56
1

When an application crashes, the jvm for this app is restarted, your classes are reloaded and you lose all static variables as well as instance variables.

For more information you can read this question Android static object lifecycle

Community
  • 1
  • 1
Faceles
  • 453
  • 1
  • 5
  • 16
  • is there a way to stop losing data in static objects? – milad zahedi Sep 10 '16 at 11:54
  • 1
    @miladzahedi you can store all the important data in persistent storage like db or preferences as Nishant Pardamwar said, and retrieve it in getters if value is null. – Faceles Sep 10 '16 at 12:04
0

Whenever any activity throws exception it stops and recreates without recreating the parent activity that is why your singleton object become null.

Preetika Kaur
  • 1,991
  • 2
  • 16
  • 23