2012-05-07 1 views
2

a previous question 광산과 관련하여 예외가 Thread.UncaughtExceptionListener에 걸렸을 때 상황을 정확히 알고 싶습니다. 잡히지 않은 예외가 청취자에 의해 수신 될 때, 문맥은 림보 (limbo) 상태에 빠진 것처럼 보인다. 그것은 몇 가지 방법 (주로 자원에 관한 것)에 접근 할 수 있지만, 많은 사람들이 작동하지 않는다 (또는 눈에 보이지 않게 작동한다). 새로운 활동의 스레드가 UncaughtException을 catch하기 전에 컨텍스트에 어떤 일이 발생합니까

  • Toast

    (내 링크 등)
  • Dialog
  • 창조 :이 (좀 더 내가 발견하지 않았습니다가 확신하며 이에 제한되지 않음)이 포함되어 있습니다. 여기에는 보통 Context.startActivity(Intent)PendingIntent이 포함됩니다. 상황은 여전히 ​​문맥 자원 (getString(), Resources하고 이상하게 Notification들)에게 자명 액세스 할 수 있습니다 그러나

.

왜인가요? 문맥 기반 호출을 방지하기 위해 컨텍스트에서이 상태 불균형 (?)이 발생하는 이유는 무엇입니까?

아래 예외가 잡히지 않은 상태에서 오류 활동을 시작한다고 가정하는 테스트 응용 프로그램을 작성했습니다. 내가하고있는 상황에서 내가 언급 한 (토스트와 대화) 것을 테스트하기 위해 빌더를 알림 빌더 대신 BoomMitActivity에 배치하십시오.

주어진 예제에서 Notification을 클릭하면 활동 오류가 발생하고 (어떻게 작동하지 않습니까?) BoomMitActivtiy를 시작합니다. 그러나 BoomMit의 onCreate은 호출되지 않습니다.

응용 프로그램 :

public class AndroidTestoActivity extends Activity implements UncaughtExceptionHandler { 
    @Override public void onCreate(Bundle icicle) { 
     super.onCreate(icicle); 

     Thread.setDefaultUncaughtExceptionHandler(this); 

     throw new RuntimeException("HAHAHAHA, I broke you"); 
    } 

    @Override public void uncaughtException(Thread arg0, Throwable arg1) { 
     finish(); 
     NotificationManager nm = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); 
     Notification note = new Notification(R.drawable.ic_launcher, "Boom!", System.currentTimeMillis()); 

     Intent i = new Intent(this, BoomMitActivity.class); 
     i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     PendingIntent pi = PendingIntent.getActivity(this, 1, i, PendingIntent.FLAG_ONE_SHOT); 
     note.setLatestEventInfo(this, "Boom!", "Open BoomMitActivity", pi); 
     note.flags |= Notification.FLAG_AUTO_CANCEL; 

     nm.notify(1, note); 
     Log.d("TAG", "End"); 
    } 

    static class BoomMitActivity extends Activity { 
     @Override public void onCreate(Bundle icicle) { 
      super.onCreate(icicle); 
      TextView tv = new TextView(this); 
      tv.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); 
      tv.setBackgroundColor(0xffff0000); 
      tv.setText("BoomMitActivity is the one true activity"); 
      tv.setTextColor(0xff00ffff); 
      setContentView(tv); 
     } 
    } 
} 

매니페스트 :

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.testo" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk android:minSdkVersion="8" /> 

    <application 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" > 
     <activity 
      android:name=".AndroidTestoActivity" 
      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="AndroidTestoActivity$BoomMitActivity" 
      android:label="I'm a real boy!" 
      android:taskAffinity="" 
      android:excludeFromRecents="true" 
      android:launchMode="singleTask"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN"/> 
       <category android:name="android.intent.category.LAUNCHER"/> 
      </intent-filter> 
     </activity> 
    </application> 
</manifest> 
+0

왜 '정적'으로'BoomMitActivity'를 얻었습니까? – Ronnie

+0

@ userSeven7s 중첩 된 활동을 정적으로 선언 할 수 없습니다. 나는 그것을 자신의 클래스에 쉽게 배치 할 수 있었지만 테스트를 위해 AndroidTestoActivity에서 테스트하는 것이 더 쉬웠다. – AedonEtLIRA

+0

일반 수업과도 같습니까? – Ronnie

답변

3

아무것도 문맥 자체에 변화가 없습니다. 앱 크래시 대화 상자가 열려있는 상황에 대해 이야기하고 있다면 충돌하는 스레드가 사용자가 버튼을 누르고 자신을 죽일 때까지 기다리는 중입니다. 이 시점에서 시스템은 귀하의 앱이 휴지통임을 인식하고 사용자가이를 확인하고 마침내 종료 할 때까지 기다리고 있습니다. 그래서 당신은 정말로 당신이 탈출구에 있다고 생각하고 일하는 것에 의존하지 않아야합니다.

또한이 크래시가 주 스레드에서 발생한 경우 사용자가 충돌 대화 상자를 확인하기 위해 대기하는 동안 해당 스레드가 자고 있으므로 자살 할 수 있습니다. 메시지 루프를 처리하는 중 앉아 있지 않고 자살을 기다리는 것을 완전히 차단했습니다. 해당 스레드에서 예약 된 작업은 실행되지 않습니다. 메인 스레드의 경우 Activity.onCreate(), Service.onStart() 및 on과 같은 구성 요소에 대한 콜백이 포함됩니다. 모든 스레드의 경우 스레드와 관련된 창 UI에 대한 작업을 전달하는 작업이 포함됩니다. 다시 이것은 이것이 주 스레드 인 경우 모든 UI를 의미합니다.

+0

좋습니다. 덕분에 많은 감사를드립니다. 나는 단지 "Opps, 우리는 당신의 개발자가 바보 인 것을 유감스럽게 생각합니다."보다 더 우아한 충돌을 원했습니다. – AedonEtLIRA

+0

더 우아하다고 생각하십니까? – hackbod

+0

그냥 아무런 경고 나 원인없이 사라져서 - 나는 그것이 작동하지 않을 것임을 깨달을 때까지 아이콘을 세 번 더 누릅니다. 그게 아이폰이하는 일입니다 ... 나는 꼬마 야, 나는 꼬마 야! :) – Dan

관련 문제