Форум программистов, компьютерный форум, киберфорум
Наши страницы
Программирование Android
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
AlexV1
-2 / 0 / 0
Регистрация: 05.04.2016
Сообщений: 36
#1

Поймать UncaughtExceptions и запустить ErrorActivity

21.09.2016, 14:34. Просмотров 898. Ответов 7
Метки нет (Все метки)

Привет!

Вот уже неделю как не могу решить одну задачку.
Обработать необработанные (непойманные) исключения и вызвать мою ErrorActivity, в которой я попрошу пользователя прислать мне StackTrace.
Ловлю в своем MyApplication классе, чтобы ловить не только в Activity, но и в любых модулях, потоках, службах и т.п., то есть в пределах всего приложения.
Ловить получается. Не получается при этом запустить мою ErrorActivity - программа в конце handleUncaughtException просто закрывается.
При этом, если запускать активити из OnCreate MainActivity, то все OK, запускается, из-за чего я полагаю, что запуск ErrorActivity написан корректно.

Класс MyApplication

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class MyApplication extends Application {
 
    public static Context appContext; // Link to ApplicationContext
 
    @Override
    public void onCreate() {
 
        appContext = getApplicationContext();
 
        // Удаляем обработчик, чтобы рекурсивно не срабатывал, если далее 
        Thread.setDefaultUncaughtExceptionHandler(null); исключение возникнет
 
        // Setup handler for uncaught exceptions.
        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread thread, Throwable e) {
                handleUncaughtException(thread, e);
            }
        });
 
        super.onCreate();
    }
 
    public static void handleUncaughtException(Thread thread, Throwable e) {
 
        Context context = MyApplication.appContext;
 
        Intent intent = new Intent();
        intent.setAction ("com.example.alexv.testapp.err");
        intent.setFlags (Intent.FLAG_ACTIVITY_NEW_TASK); // required when starting from Application
        context.startActivity (intent);
    }
}
MainActivity

Java
1
2
3
4
5
6
7
8
9
10
11
12
public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        int i = Integer.parseInt("23,222.345"); // имитация исключения
 
    }
}
Манифест

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.alexv.testapp">
 
    <application
        android:name="MyApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
 
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
 
        <activity android:name=".ErrorActivity"
            android:windowSoftInputMode="stateHidden">
            <intent-filter>
                <action android:name="com.example.alexv.testapp.err" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
        </activity>
 
    </application>
 
</manifest>
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.09.2016, 14:34
Ответы с готовыми решениями:

В одном фрагменте запустить интент - во втором поймать его
Если оба фрагмента находятся в LinearLayout одного активити можно ли из одного...

Как поймать смену фокуса EditText?
Вопрос в следующем (Упрощу суть): Есть EditText1, тыкаем на него пальцем и в...

Как поймать событие нажатия пальцами на экран?
Добрый день. Хочу поймать событие нажатия пальцами на экран. Использую ...

Как поймать ошибку показанную в Play Console
Здравствуйте, Опубликовал приложение в Плей Маркете. Когда смотрю иногда...

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

7
Pablito
2665 / 2147 / 729
Регистрация: 12.05.2014
Сообщений: 7,499
Завершенные тесты: 1
21.09.2016, 14:54 #2
https://github.com/ACRA/acra
https://try.crashlytics.com/
и не мучайся
0
vxg
Модератор
3236 / 2040 / 319
Регистрация: 13.01.2012
Сообщений: 7,898
21.09.2016, 19:41 #3
AlexV1, почему просто не запустить ее по нормальному?
Java
1
2
3
Intent intent = new Intent(context, ErrorActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
0
AlexV1
-2 / 0 / 0
Регистрация: 05.04.2016
Сообщений: 36
22.09.2016, 04:38  [ТС] #4
vxg, если бы все было так просто...
Пробовал именно так как вы предлагаете.
context.startActivity(intent); отрабатывает, но активити не появляется, а приложение молча выгружается.
0
vxg
Модератор
3236 / 2040 / 319
Регистрация: 13.01.2012
Сообщений: 7,898
22.09.2016, 08:27 #5
AlexV1, попробуйте не делать обработчик static и не использовать в нем context
0
AlexV1
-2 / 0 / 0
Регистрация: 05.04.2016
Сообщений: 36
22.09.2016, 14:07  [ТС] #6
Пробовал, не помогает.
0
vxg
Модератор
3236 / 2040 / 319
Регистрация: 13.01.2012
Сообщений: 7,898
23.09.2016, 22:04 #7
Лучший ответ Сообщение было отмечено vxg как решение

Решение

AlexV1, так работает
MainActivity
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.example.et;
 
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
 
public class MainActivity extends Activity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        ((Button)findViewById(R.id.button1)).setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                int i = Integer.parseInt("23,222.345");
            }
        });
    }
 
}

ErrorActivity
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.example.et;
 
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
 
public class ErrorActivity extends Activity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_error);
    }
 
}

App
Кликните здесь для просмотра всего текста
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.example.et;
 
import android.app.Application;
import android.content.Intent;
 
public class App extends Application {
    @Override
    public void onCreate() {
        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread thread, Throwable e) {
                Intent i = new Intent();
                i.setClassName("com.example.et", "com.example.et.ErrorActivity");
                i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(i);
                
                System.exit(1);
            }
        });
 
        super.onCreate();
    }
 
}

Manifest
Кликните здесь для просмотра всего текста
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.et"
    android:versionCode="1"
    android:versionName="1.0" >
 
    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
 
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme"
        android:name="App" >
        <activity
            android:name="com.example.et.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
 
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name="com.example.et.ErrorActivity"
            android:label="@string/app_name" >
        </activity>
    </application>
 
</manifest>

принципиальных отличий от вашего кода никаких кроме убийства после запуска активити с сообщением об ошибке
причина по которой активити не хотело показываться скорее всего в этом
You're not seeing anything because the exception happened on your UI thread and the stack unrolled all the way.
убийство скорее всего развязывает этот узел и дает активити с сообщением об ошибке стартовать
кроме того в некоторых источниках советуют добавить к активити с сообщением об ошибке в манифест вот такую магию
XML
1
android:process=":report_process"
You can add attribute android: process=":report_process" to the <activity> element which refers to your bug report activity in AndroidManifest.xml.

By default, activities belong to the same appliction would run in the same process identified by your package name. By setting android: process attribute, you can override this. android: process starting with : refers to a private identifier within your package, so that you can start the activity in a new process without conflicting other packages' process.
с этой магией активити с сообщением об ошибке стартует даже без убийства, но нажатие кнопки назад в этом случае возвращало меня на мертвую активити вызвавшую исключение
0
AlexV1
-2 / 0 / 0
Регистрация: 05.04.2016
Сообщений: 36
24.09.2016, 20:13  [ТС] #8
vxg, спасибо за помощь.
Ваш вариант то, что надо, все работает :-)
0
24.09.2016, 20:13
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
24.09.2016, 20:13

Поймать 3G
Я живу в деревне, с интернетом там очень тяжко. 3G ловит только на крыше дома,...

Поймать исключение
Почему-то не ловятся исключения: try { return a.exec(); } ...

Запустить программу, при ее успешном завершении запустить следующую
- запустить программу PRIM.exe, при успешном завершении запустить...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru