java - unfortunately app has stopped




لسوء الحظ توقفت MyApp. كيف يمكنني حل هذا؟ (10)

أولاً ، تحقق من النقطة التي تعطل تطبيقك ( Unfortunately, MyApp has stopped. ). لهذا يمكنك استخدام Log.e("TAG","Message"); ، باستخدام هذا الخط يمكنك أن ترى لك سجل التطبيق في logcat.

بعد ذلك يمكنك العثور على النقطة التي توقف فيها تطبيقك عن حلها السهل جدًا على جانبك.

أقوم بتطوير تطبيق ، وفي كل مرة أقوم بتشغيله ، أحصل على الرسالة:

للأسف ، توقف MyApp.

ما الذي يمكنني فعله لحل هذه المشكلة؟

حول هذا السؤال - مستوحى بوضوح من ما هو تتبع المكدس ، وكيف يمكنني استخدامه لتصحيح أخطاء التطبيقات الخاصة بي؟ ، هناك الكثير من الأسئلة التي تفيد بأن تطبيقهم قد تحطم ، دون أي تفاصيل أخرى. يهدف هذا السؤال إلى تعليم المبرمجين المبتدئين في Android كيفية محاولة إصلاح مشكلاتهم بأنفسهم ، أو طرح الأسئلة الصحيحة.


إذا تعطل تطبيقك لسبب ما دون وجود stacktrace جيد. جرّب تصحيحه من السطر الأول ، وانتقل إلى سطر تلو الآخر حتى تعطل. ثم سيكون لديك إجابة ، أي خط يسبب لك مشكلة. من المحتمل أن تتمكن من لفه في المحاولة وإخراج خطأ الطباعة.


تحقق من رسالة Logcat الخاصة بك Logcat . يجب أن يكون هناك شيء مفقود مثل تحديد Activity, إذن المستخدم ، إلخ.


دعوني أشارك في تحليل Logcat الأساسي عندما تقابل قوة الإغلاق (عندما يتوقف التطبيق عن العمل).

مستندات

الأداة الأساسية من Android لجمع / تحليل السجلات هي logcat.

HERE هي صفحة Android حول logcat

إذا كنت تستخدم Android Studio ، فيمكنك أيضًا التحقق من LINK هذا.

اسر

في الأساس ، يمكنك بشكل أساسي التقاط logcat باستخدام الأمر التالي (أو مجرد التحقق من نافذة AndroidMonitor في AndroidStudio):

adb logcat

هناك الكثير من المعلمات التي يمكنك إضافتها إلى الأمر والتي تساعدك على تصفية وعرض الرسالة التي تريدها ... هذا أمر شخصي ... دائمًا ما أستخدم الأمر أدناه للحصول على الطابع الزمني للرسالة:

adb logcat -v time

يمكنك إعادة توجيه الإخراج إلى ملف وتحليله في "محرر النصوص".

تحليل

إذا كان التطبيق هو التحطيم ، فستحصل على شيء من هذا القبيل:

07-09 08:29:13.474 21144-21144/com.example.khan.abc D/AndroidRuntime: Shutting down VM
07-09 08:29:13.475 21144-21144/com.example.khan.abc E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.khan.abc, PID: 21144
    java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.app.FragmentActivity.onBackPressed()' on a null object reference
     at com.example.khan.abc.AudioFragment$1.onClick(AudioFragment.java:125)
     at android.view.View.performClick(View.java:4848)
     at android.view.View$PerformClick.run(View.java:20262)
     at android.os.Handler.handleCallback(Handler.java:815)
     at android.os.Handler.dispatchMessage(Handler.java:104)
     at android.os.Looper.loop(Looper.java:194)
     at android.app.ActivityThread.main(ActivityThread.java:5631)
     at java.lang.reflect.Method.invoke(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:372)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:959)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:754)
07-09 08:29:15.195 21144-21144/com.example.khan.abc I/Process: Sending signal. PID: 21144 SIG: 9

يعرض لك هذا الجزء من السجل الكثير من المعلومات:

  • عند حدوث المشكلة: 07-09 08:29:13.475

من المهم التحقق عند حدوث المشكلة ... قد تجد العديد من الأخطاء في سجل ... يجب أن تكون على يقين من أنك تتحقق من الرسائل المناسبة :)

  • ما التطبيق الذي تعطل: com.example.khan.abc

بهذه الطريقة ، تعرف أي تطبيق تم تعطله (للتأكد من أنك تتحقق من سجلات رسائلك)

  • الخطأ الذي: java.lang.NullPointerException

خطأ استثناء مؤشر NULL

  • معلومات تفصيلية حول الخطأ: Attempt to invoke virtual method 'void android.support.v4.app.FragmentActivity.onBackPressed()' on a null object reference

لقد حاولت استدعاء الأسلوب onBackPressed() من كائن FragmentActivity . ومع ذلك ، كان هذا الكائن لا شيء عندما فعلت ذلك.

  • Stack Trace: يعرض Stack Trace ترتيب استدعاء الأسلوب ... في بعض الأحيان ، يحدث الخطأ في طريقة الاستدعاء (وليس في الأسلوب الذي يتم الاتصال به).

    at com.example.khan.abc.AudioFragment $ 1.onClick (AudioFragment.java:125)

حدث خطأ في ملف com.example.khan.abc.AudioFragment.java ، داخل أسلوب onClick() في السطر: 125 (يظهر stacktrace الخط الذي حدث الخطأ)

كان يطلق عليه:

at android.view.View.performClick(View.java:4848)

الذي كان يسمى من قبل:

at android.view.View$PerformClick.run(View.java:20262)

الذي كان يسمى من قبل:

at android.os.Handler.handleCallback(Handler.java:815)

إلخ....

نظرة عامة

كان هذا مجرد نظرة عامة ... ليست كل السجلات بسيطة ... إلخ. إنها فقط لمشاركة الفكرة وتقديم معلومات على مستوى الدخول لك ...

آمل أن أتمكن من مساعدتك بطريقة ما ... التحيات


في الطريقة أدناه showToast () يجب عليك تمرير معلمة أخرى للسياق أو سياق التطبيق من خلال القيام بذلك يمكنك تجربته.

  public void showToast(String error, Context applicationContext){
        LayoutInflater inflater = getLayoutInflater();
        View view = inflater.inflate(R.layout.custom_toast, (ViewGroup)      
        findViewById(R.id.toast_root));
        TextView text = (TextView) findViewById(R.id.toast_error);
        text.setText(error);
        Toast toast = new Toast(applicationContext);
        toast.setGravity(Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0);
        toast.setDuration(Toast.LENGTH_SHORT);
        toast.setView(view);
        toast.show();
}

لا تظهر هذه النافذة المنبثقة إلا عند حصولك على استثناء فادح في شفرتك والذي يوقف تنفيذ التطبيق. يمكن أن يكون أي استثناء NullPointerException ، OutOfMemoryException الخ.

أفضل طريقة للتحقق من خلال Logcat إذا كنت لا تزال تطوير التطبيق في استوديو أندرويد وهي طريقة سريعة لقراءة تتبع المكدس والتحقق من سبب التطبيق.

إذا كان تطبيقك نشطًا بالفعل ، فلا يمكنك استخدام logcat. لذلك ، يمكنك تنفيذ Crashlytics لتزويدك بتقارير الأخطاء عن أي استثناء يحدث.


يمكنك أيضًا الحصول على رسالة الخطأ هذه من تلقاء نفسها ، دون أي تتبع مكدس أو أي رسالة خطأ أخرى.

في هذه الحالة ، يجب التأكد من أن بيان Android الخاص بك قد تم تهيئته بشكل صحيح (بما في ذلك أي دمج يتم عرضه من مكتبة وأي نشاط قد يأتي من المكتبة) ، وإيلاء اهتمام خاص للنشاط الأول المعروض في التطبيق الخاص بك في ملفات البيان الخاصة بك .


يمكنك استخدام أداة ADB من Google للحصول على Logcat file لتحليل المشكلة.

adb logcat > logcat.txt

افتح ملف logcat.txt وابحث عن اسم التطبيق الخاص بك. يجب أن تكون هناك معلومات حول سبب إخفاقها ورقم السطر واسم الفصل وما إلى ذلك.


توضح هذه الإجابة عملية استرداد تتبع المكدس. بالفعل لديك تتبع المكدس؟ تقرأ على تتبعات المكدس في " ما هو تتبع مكدس الذاكرة المؤقتة ، وكيف يمكنني استخدامه لتصحيح أخطاء التطبيقات الخاصة بي؟ "

المشكلة

تم إنهاء التطبيق الخاص بك لأنه تم طرح RuntimeException غير مألوفة.
الأكثر شيوعًا من هذه هي NullPointerException .

كيف حلها؟

في كل مرة يتعطل فيها أحد تطبيقات Android (أو أي تطبيق Java لهذا الأمر) ، تتم كتابة Stack trace إلى وحدة التحكم (في هذه الحالة ، logcat). يحتوي هذا المقتفي على معلومات حيوية لحل مشكلتك.

Android Studio

في الجزء السفلي من النافذة ، انقر على زر Logcat . بدلاً من ذلك ، يمكنك الضغط على alt + 6 . تأكد من تحديد محاكي أو جهازك في لوحة Devices . بعد ذلك ، حاول العثور على تتبع المكدس ، الذي يظهر باللون الأحمر. قد يكون هناك الكثير من الاشياء تسجيل الدخول إلى logcat ، لذلك قد تحتاج إلى التمرير قليلا. طريقة سهلة للعثور على تتبع المكدس هي مسح logcat (باستخدام سلة المحذوفات على اليمين) ، والسماح للتطبيق بالتعطل مرة أخرى.

لقد وجدت أثر المكدس ، الآن ماذا؟

ياي! أنت في منتصف الطريق لحل مشكلتك.
تحتاج فقط إلى معرفة ما الذي حدث بالضبط تعطل التطبيق الخاص بك ، عن طريق تحليل تتبع المكدس.

قراءة على تتبعات المكدس في " ما هو تتبع مكدس الذاكرة المؤقتة ، وكيف يمكنني استخدامه لتصحيح أخطاء التطبيقات الخاصة بي؟ "

ما زلت لا أستطيع حل مشكلتي!

إذا وجدت Exception والخط الذي حدث فيه ، ولا يزال لا يمكن معرفة كيفية إصلاحه ، فلا تتردد في طرح سؤال على .

حاول أن تكون موجزة قدر الإمكان: نشر تتبع المكدس ، والشفرة ذات الصلة (على سبيل المثال ، بضعة أسطر حتى الخط الذي ألقى Exception ).


ملاحظة: تستخدم هذه الإجابة Android Studio 2.2.2

ملاحظة 2: أنا أعتبر أن جهازك متصل بنجاح.

أول شيء تقوم به عند تعطل التطبيق الخاص بك هو النظر في LogCat ، في الجزء السفلي من Android Studio هناك شريط أدوات يحتوي على قائمة بالقوائم:

انقر على "Android Monitor" (الشخص الذي أشرت إليه في الصورة أعلاه.)

الآن ، ستحصل على شيء كهذا:

تغيير " Verbose " إلى " Error " الآن سيعرض لك فقط الأخطاء المسجلة. لا تقلق بشأن كل هذه الأخطاء (إذا حصلت عليها) الآن.

حسنا. الآن ، افعل ما فعلت لتحطيم تطبيقك. بعد تعطل التطبيق ، انتقل إلى logcat الخاص بك. يجب أن تجد سجل تعطل جديد يحتوي على الكثير من at:xxx : و Caused by: TrumpIsPresidentException على سبيل المثال. انتقل إلى التي Caused by: بيان في logcat الخاص بك.

بجانب ذلك Caused By: ، يجب أن يكون هناك استثناء حدث. في حالتي ، هو RuntimeException يجب أن يكون هناك خط يحتوي على رابط أزرق مثل:

إذا كان ذلك Caused by: DOESN'T يكون له سطر بنص أزرق في مكان ما تحته ، فابحث عن آخر Caused by: هذا صحيح.

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

throw new RuntimeException();

لذا ، الآن أعرف لماذا يحدث ذلك. ذلك لأنني ألقي الاستثناء بنفسي. كان هذا خطأ واضح .

ومع ذلك ، لنفترض أنني حصلت على خطأ آخر:

java.lang.NullPointerException

لقد راجعت تسجيل الدخول الخاص بي ، ونقرت على الرابط الأزرق الذي أعطاني إياه ، واستغرق الأمر هنا:

mTextView.setText(myString);

لذا ، الآن أريد تصحيح الأخطاء. استناداً إلى NullPointerException ، NullPointerException يقول أن شيء ما null .

لذلك ، دعونا معرفة ما هو لاغية . هناك احتمالان. إما mTextView خالية أو myString خالية. لمعرفة ذلك ، قبل mTextView.setText(mString) ، أضفت هذين السطرين:

Log.d("AppDebug","mTextView is null: " + String.valueOf(mTextView == null);
Log.d("AppDebug","myString is null: " + String.valueOf(myString== null);

الآن ، كما فعلنا سابقًا (لقد غيرنا كلمة Verose إلى Error) ، نريد تغيير "Error" إلى "Debug". بما أننا نسجل من خلال تصحيح الأخطاء. إليك جميع طرق تسجيل الدخول:

Log.
  d means Debug
  e means error
  w means warning
  v means verbose
  i means information
  wtf means "What a terrible failure". This is similar to Log.e

لذا ، بما أننا استخدمنا Log.d ، فنحن نتحقق من Debug. لهذا السبب قمنا بتغييره إلى تصحيح.

لاحظ Log.d يحتوي على المعلمة الأولى ، في حالتنا "AppDebug". انقر على القائمة المنسدلة "بدون فلاتر" في الجزء العلوي الأيسر من logcat. حدد "تحرير تكوين مرشح" ، وإعطاء اسم لفلترك ، وفي "علامة السجل" وضع "تصحيح التطبيق". انقر فوق موافق". الآن ، يجب أن ترى سطرين في logcat:

yourPackageNameAndApp: mTextView is null: true
yourPackageNameAndApp: myString is null: false

الآن نحن نعلم أن mTextView فارغ.

ألاحظ رمز بلدي ، والآن ألاحظ شيئا.

لدي private TextView mTextView أعلن private TextView mTextView في الجزء العلوي من صفي. لكن ، أنا لا أعرّفها.

نسيت في الأساس القيام بذلك في onCreate () الخاص بي:

mTextView = (TextView) findViewById(R.id.textview_id_in_xml);

إذاً هذا هو السبب في أن mTextView فارغ ، لأنني نسيت أن أقول لي ما هو. لذلك أضفت هذا الخط ، وشغِّل تطبيقي ، والآن لا يتعطل التطبيق.





android