2016-09-10 1 views
0

У меня есть приложение для Android, в котором используется несколько одноэлементных объектов. Эти объекты используются во многих видах деятельности. Когда исключение бросается в действие, разные поля в моих синглонах становятся нулевыми, а все другие действия также вызывают исключения. Например, у меня есть одноэлементный класс для обработки моего файла cookie, у которого есть статическое поле HTTPCookie, и если в какой-либо деятельности возникает исключение, это поле cookie также становится null.android exception в действии делает все одноэлементные поля нулевыми

Хотелось бы знать, почему это происходит. Как я могу предотвратить это?

ОБНОВЛЕНИЕ: код для одного из моих синглетов.

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; 
} 
+0

Показать код. –

+0

@N neeraj Lal это очень огромное приложение с большим количеством классов. –

+0

Не показывать весь код. Покажите фрагмент кода, который имеет отношение к вопросу. –

ответ

1

Когда ваши аварии приложение, то весь процесс приложение перезапускается т.е. одиночек также получает сброс, вы не можете предотвратить ваш синглтон становится нулевым, когда сбой приложения, но вы можете инициализировать, когда приложение глобального контекста приложения является создание.

сделать класс App.java

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

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

и зарегистрировать этот класс в манифеста

<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"> 
. 
. 
. 

Это гарантирует вызов, прежде всего, то есть до того вещания, деятельность, услуги и т.д. поэтому вы можете быть уверены, что ваши сингллеты никогда не будут равны нулю, когда ваше приложение выйдет из строя и перезагрузится.

+0

сохранит ли это то, что находится внутри этих синглетов? –

+1

не будет сохранено ни одного контента в одиночном режиме, вы должны хранить их где-нибудь, как в sqlite db или sharedpreference, это гарантирует, что при инициализации вами синглонов таким образом они никогда не будут полностью пустыми, как даже после того, как приложение выйдет из строя * * initializeSingletons() ** будет вызываться, и синглтоны будут загружены, прежде чем они будут использоваться действиями или каким-либо другим компонентом. –

0

Всякий раз, когда какое-либо действие вызывает исключение, оно останавливается и воссоздается без воссоздания родительской активности, поэтому ваш Singleton-объект становится нулевым.

1

При сбое приложения, jvm для этого приложения перезапускается, ваши классы перезагружаются, и вы теряете все статические переменные, а также переменные экземпляра.

Для получения дополнительной информации вы можете прочитать этот вопрос Android static object lifecycle

+0

Есть ли способ остановить потери данных в статических объектах? –

+1

@miladzahedi вы можете хранить все важные данные в постоянном хранилище, например, db или предпочтения, как сказал Нишант Пардамвар, и получить его в геттерах, если значение равно null. – Faceles

Смежные вопросы