كيفية إعادة تشغيل تطبيق أندرويد تلقائيًا بعد حدوث عطل أو خطأ إغلاق قوة؟

أكبر كابوس لمطوري Android هو Crash أو Force Close Error الذي يمكن أن يحدث عندما يستخدم المستخدم أحد تطبيقاته. في الحقيقة ، إنها رسالة سيئة دومًا يتم إرسالها إلى المستخدم والخطر الرئيسي هو أن يقوم المستخدم بإلغاء تثبيت التطبيق. لسوء الحظ ، لا يمكنك دائمًا التقاط جميع الأخطاء بشكل صحيح وأحيانًا لا يمكنك تجنب حدوث تعطل أو خطأ إغلاق قوي. في هذه الحالات المحددة ، تتمثل الطريقة الجيدة في تكوين إعادة التشغيل التلقائي لتطبيق Android. مع هذا النهج ، لديك فرص أفضل للحفاظ على المستخدمين في التطبيق الخاص بك.

لاحظ أنه يمكنك أيضًا الاستمتاع بهذا البرنامج التعليمي في الفيديو على Youtube:

للبدء ، تحتاج إلى إنشاء تطبيق فئة تطبيق مخصص للحصول على مثيل لسياقك بشكل مستمر:

حزمة com.ssaurel.appcrash ؛
استيراد android.app.Application ؛
استيراد android.content.Context؛
الطبقة العامة MyApplication يمتد التطبيق {
 مثيل MyApplication ثابت العامة؛
 @تجاوز
 باطل عام onCreate () {
   super.onCreate ()؛
   المثال = هذا ؛
 }
 @تجاوز
 السياق العام getApplicationContext () {
   إرجاع super.getApplicationContext ()؛
 }
 ثابت عام MyApplication getInstance () {
   عودة المثال ؛
 }
}

لا تنس إضافة تطبيق التطبيق هذا على Android Manifest:

<؟ xml version = "1.0" encoding = "utf-8"؟>
  <تطبيق
    الروبوت: allowBackup = "صحيح"
    الروبوت: رمز = "@ مظهر سطحي نقطي / ic_launcher"
    الروبوت: التسمية = "@ سلسلة / APP_NAME"
    الروبوت: supportsRtl = "صحيح"
    الروبوت: موضوع = "@ النمط / AppTheme"
    الروبوت: اسم = ". MyApplication">
    <نشاط android: name = ". MainActivity">
      <نية تصفية>
        
          
      
    
  

لتجربة ميزة إعادة التشغيل التلقائي ، نحتاج إلى تحديد زر في تخطيط النشاط الرئيسي. عندما نقر على الزر ، سنقوم بتعطيل التطبيق. سيكون للتخطيط النموذج التالي:

<؟ xml version = "1.0" encoding = "utf-8"؟>
  <زر
    الروبوت: layout_width = "wrap_content"
    الروبوت: layout_height = "wrap_content"
    الروبوت: layout_centerInParent = "صحيح"
    android: text = "Crash Me!"
    الروبوت: عند _ النقر = "crashMe" />

الآن ، ندخل في جوهر ميزة إعادة التشغيل التلقائي لدينا. تحتاج إلى إنشاء تطبيق مخصص للواجهة UncaughtExceptionHandler. ما هو الغرض من هذه الواجهة؟ إنها واجهة للمعالجات التي يتم استدعاءها عند إنهاء سلسلة الرسائل بشكل مفاجئ بسبب استثناء غير معلوم.
سيكون للتطبيق المخصص لدينا النموذج التالي:

حزمة com.ssaurel.appcrash ؛
استيراد android.app.Activity ؛
استيراد android.app.AlarmManager ؛
استيراد android.app.PendingIntent؛
استيراد android.content.Context؛
استيراد android.content.Intent ؛
الطبقة العامة MyExceptionHandler تنفذ Thread.UncaughtExceptionHandler {
  نشاط نشاط خاص
  MyExceptionHandler العامة (النشاط أ) {
    النشاط =
  }
  @تجاوز
  public void uncaughtException (سلسلة الرسائل ، Throwable ex) {
    هدف النية = هدف جديد (نشاط ، MainActivity.class) ؛
    intent.putExtra ("تعطل" ، صحيح) ؛
    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)؛
  }
}

عند حدوث استثناء غير معلوم ، سيتم استدعاء طريقة uncaughtException. سننشئ نية لإعادة تشغيل تطبيقنا في الوقت المحدد عبر إنذار. ثم ننتهي من النشاط الحالي ونخرج من التطبيق. لاحظ أننا نضع معلمة منطقية للإشارة إلى إعادة تشغيل التطبيق.

الخطوة الأخيرة هي تثبيت UncaughtExceptionHandler أثناء بدء التطبيق عن طريق استدعاء الأسلوب setDefaultUncaughtExceptionHandler الثابت لفئة سلاسل العمليات:

حزمة com.ssaurel.appcrash ؛
استيراد android.os.Bundle ؛
استيراد android.support.v7.app.AppCompatActivity؛
استيراد android.view.View ؛
استيراد android.widget.Toast ؛
MainActivity فئة عامة يمتد AppCompatActivity {
 @تجاوز
 محمي void onCreate (تم حفظ الحزمة في InstanceState) {
   super.onCreate (savedInstanceState)؛
   setContentView (R.layout.activity_main)؛
   Thread.setDefaultUncaughtExceptionHandler (جديد MyExceptionHandler (هذا)) ؛
   إذا (getIntent (). getBooleanExtra ("تعطل" ، خطأ)) {
     Toast.makeText (هذا ، "إعادة تشغيل التطبيق بعد التعطل" ، Toast.LENGTH_SHORT) .show ()؛
   }
 }
 تحطم الفراغ العام (عرض v) {
   رمي جديد NullPointerException () ؛
 }
}

لاحظ أننا نقوم بتشغيل NullPointerException في طريقة crashMe لفرض تعطل التطبيق واختبار ميزة إعادة التشغيل التلقائي. الشيء الآخر الذي يجب ملاحظته هو اختبار المعلمة المنطقية عند تعطل النشاط. كما قيل سابقًا ، فإنه يتيح لنا معرفة وقت إعادة تشغيل التطبيق بعد حدوث عطل أو عندما يتم تشغيل التطبيق لأول مرة.

الآن ، يمكنك تشغيل التطبيق وسترى الشاشة التالية بعد النقر على زر crashMe: