Android-приложение перезапускается после сбоя / силы

Мое приложение для Android запускается после принудительного закрытия, через мое приложение, состоящее из 20 видов деятельности, я полагаюсь на статические данные, созданные в основном действии. Поэтому, когда приложение становится разбитым, все мои статические данные теряются, и когда приложение автоматически перезагружается, у него нет каких-либо важных данных для работы.

Мой вопрос: после аварии я хочу, чтобы это произошло

  1. Если приложение выходит из строя, я не хочу, чтобы приложение перезапускалось, но я хочу, чтобы весь стек / задача, связанная с этим приложением, была вытерта из памяти. Пользователь может перезапустить его с самого начала
  2. Если я не могу предотвратить перезапуск приложения, по крайней мере, я хочу сохранить важные данные, чтобы при перезапуске приложения я мог их вернуть. Также, когда он перезапускается, я хочу, чтобы мое приложение начиналось с основного действия.

Я знаю, что при сбоях в работе андроидная система приведет к следующей операции в стеке на переднем плане, и это является причиной того, что мое приложение создает избыточные результаты. Также я прошел через разработчиков Android, но только то, что я узнал, было создание атрибута в Manifest android:finishOnTaskLaunch="true" . Но, к сожалению, это не помогает мне. Буду признателен за вашу помощь в решении этой проблемы, а также позвольте мне узнать причину и анализ.

Solutions Collecting From Web of "Android-приложение перезапускается после сбоя / силы"

  1. Лучшим решением будет вместо использования статических данных, использования Shared Preferences или хранения данных в базе Database и если произойдет какое-либо uncaught Exception , покажите сообщение, такое как Application has crashed and a report is sent to the admin а затем перезапустите действие, которое вызвало сбой , Таким образом, пользователь может продолжить использование приложения.

  2. Сделайте то же самое, но вместо перезапуска Activity, которая вызвала перезапуск приложения Exception.

Создать класс, используемый для обработки unCaughtException

 public class MyExceptionHandler implements java.lang.Thread.UncaughtExceptionHandler { private final Context myContext; private final Class<?> myActivityClass; public MyExceptionHandler(Context context, Class<?> c) { myContext = context; myActivityClass = c; } public void uncaughtException(Thread thread, Throwable exception) { StringWriter stackTrace = new StringWriter(); exception.printStackTrace(new PrintWriter(stackTrace)); System.err.println(stackTrace);// You can use LogCat too Intent intent = new Intent(myContext, myActivityClass); String s = stackTrace.toString(); //you can use this String to know what caused the exception and in which Activity intent.putExtra("uncaughtException", "Exception is: " + stackTrace.toString()); intent.putExtra("stacktrace", s); myContext.startActivity(intent); //for restarting the Activity Process.killProcess(Process.myPid()); System.exit(0); } } 

И в каждом DefaultUncaughtExceptionHandler создайте объект этого класса и установите его как DefaultUncaughtExceptionHandler

  Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this, YourCurrentActivity.class)); 
 public class MyApp extends Application { private static final String TAG = "MyApp"; private static final String KEY_APP_CRASHED = "KEY_APP_CRASHED"; @Override public void onCreate() { super.onCreate(); final UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler(); Thread.setDefaultUncaughtExceptionHandler( new UncaughtExceptionHandler() { @Override public void uncaughtException(Thread thread, Throwable exception) { // Save the fact we crashed out. getSharedPreferences( TAG , Context.MODE_PRIVATE ).edit() .putBoolean( KEY_APP_CRASHED, true ).apply(); // Chain default exception handler. if ( defaultHandler != null ) { defaultHandler.uncaughtException( thread, exception ); } } } ); boolean bRestartAfterCrash = getSharedPreferences( TAG , Context.MODE_PRIVATE ) .getBoolean( KEY_APP_CRASHED, false ); if ( bRestartAfterCrash ) { // Clear crash flag. getSharedPreferences( TAG , Context.MODE_PRIVATE ).edit() .putBoolean( KEY_APP_CRASHED, false ).apply(); // Re-launch from root activity with cleared stack. Intent intent = new Intent( this, MyRootActivity.class ); intent.addFlags( Intent.FLAG_ACTIVITY_CLEAR_TASK | Intent.FLAG_ACTIVITY_NEW_TASK ); startActivity( intent ); } } } 
  setContentView(R.layout.current); Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { android.os.Process.killProcess(android.os.Process.myPid()); System.exit(0); } code.... 

(Ссылка: Archie.bpgc)

Если пользователь принудительно останавливает ваше приложение (из «Настройки»> «Приложения»> «Информация о приложении» или из списка последних приложений), или операционная система останавливает ваше приложение, вы можете сохранить все, что вам нужно, используя onSaveInstanceState() .

Однако, если ваше приложение терпит крах, то вы не можете с этим справиться (кроме того, чтобы периодически сохранять важные вещи в настройках / базах данных и т. Д.). Скорее всего, лучше сосредоточиться на предотвращении сбоев, а не на попытках справиться с авариями!

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

Ну, приложение – это не только интерфейс (действия). Представьте, что у вас есть сложное корпоративное приложение, использующее транзакции SQL, безопасность, веб-аутентификацию и т. Д. Практически невозможно сделать каждое действие возможным восстановить весь контекст приложения, используя только общие настройки. Поэтому в этом случае я использую этот фрагмент кода:

 public class MyApplication extends Application { private static final String TAG = "my.app"; public static final String MainActivityName = "my.app.top.activity"; @Override public void onCreate() { try{ ActivityManager am = (ActivityManager) this .getSystemService(ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1); ComponentName componentInfo = taskInfo.get(0).topActivity; if (MainActivityName.length()>0 && !componentInfo.getClassName().equals(MainActivityName)){ Log.d(TAG, "Partial Restart Not Supported! : " +componentInfo.getClassName()); android.os.Process.killProcess(android.os.Process.myPid()); System.exit(0); return; }else Log.d(TAG, "!!! BCSApplication topActivity=" +componentInfo.getClassName()); }catch(Exception eee){} super.onCreate(); /* .... */ } /* .... */ } 

Мое приложение также возобновлялось с пустым экраном, когда он падал. Чтобы решить эту проблему, я проверил объект savedInstanceState на методе onCreate моего основного действия, и если он не является нулевым (значит, он перезагружен системой android), я закончил свою деятельность. Что-то вроде того:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState != null) { finish(); } } 

Это может помочь и в вашем случае.