Приложение разработано с помощью QT 5.9. Запущено в режиме киоска, пользователь ее выключить не может. Встала задача обеспечить живучесть приложения при его падении по любой причине. Нарыл на просторах интернета вот такую перезагрузку приложения и она даже чуть чуть работает:
MainActivity.java
...
public class MainActivity extends org.qtproject.qt5.android.bindings.QtActivity {
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Thread.setDefaultUncaughtExceptionHandler(new Restarter(this));
if (getIntent().getBooleanExtra("crash", false)) {
Toast.makeText(this, "Приложение перезапущено после аварийной остановки", Toast.LENGTH_SHORT).show();
}
...
}
public void raiseException() {
throw new NullPointerException();
}
}
Restarter.java
public class Restarter implements Thread.UncaughtExceptionHandler {
private Activity activity;
public Restarter(Activity a) {
activity = a;
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
Intent intent = new Intent(activity, MainActivity.class);
intent.putExtra("crash", true);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TASK
| Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(MyApplication.getInstance().getBaseContext(), 0, intent, PendingIntent.FLAG_ONE_SHOT);
AlarmManager mgr = (AlarmManager) MyApplication.getInstance().getBaseContext().getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, pendingIntent);
activity.finish();
System.exit(2);
}
}
main.cpp
#if defined(Q_OS_ANDROID)
QtAndroid::runOnAndroidThread([]{
QAndroidJniObject myJavaObject("inc.garage.MainActivity");
myJavaObject.callMethod<void>("raiseException","()V");
});
#endif
Такой код вызывает java метод raiseException и в результате приложение успешно заваливается и через секунду вновь загружается.
Теперь самое интересное. Как обработать любое падение приложения?
Элементарный throw, вызванный из кода c++ убивает приложение и перезапуска не происходит.
Пробовал и так:
main.cpp
int main(int argc, char *argv[])
{
int result = 0;
try {
qmlRegisterType<Utils>("Utils", 1, 0, "Utils");
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
ncfApp app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/interface/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
#if defined(Q_OS_ANDROID)
QQuickWindow *window = qobject_cast<QQuickWindow *>(engine.rootObjects().first());
window->showFullScreen();
#endif
throw; //эта ошибка ловится и приложение перезапускается
result = app.exec();
} catch (...) {
#if defined(Q_OS_ANDROID)
QtAndroid::runOnAndroidThread([]{
QAndroidJniObject myJavaObject("inc.garage.MainActivity");
myJavaObject.callMethod<void>("raiseException","()V");
});
#endif
}
return result;
}
Но, если из qml части вызывать в обработчике нажатия не кнопку cpp-ный throw, то приложение не идет на перезагруз.
и так:
ncfApp::ncfApp(int &argc, char **argv) : QGuiApplication(argc, argv) {}
bool ncfApp::notify(QObject* receiver, QEvent* event) {
bool done = false;
try {
done = QGuiApplication::notify(receiver, event);
} catch (...) {
//этот catch не срабатывает никогда
#if defined(Q_OS_ANDROID)
QtAndroid::runOnAndroidThread([]{
QAndroidJniObject myJavaObject("inc.garage.MainActivity");
myJavaObject.callMethod<void>("raiseException","()V");
});
#endif
}
return done;
}
И даже так:
#include <csignal>
void abortSignalHandler( int signum ) {
qDebug() << "эта функция вызывается при краше, но рестарта нет";
#if defined(Q_OS_ANDROID)
QtAndroid::runOnAndroidThread([]{
QAndroidJniObject myJavaObject("inc.garage.MainActivity");
myJavaObject.callMethod<void>("raiseException","()V");
});
#endif
}
void main(...
signal(SIGABRT, abortSignalHandler);
}
В общем уже думаю писать отдельную службу, которая следит за работой приложения. Подскажите кто как сделал, если встречались с подобным