3

私の以前の質問に関連 して、例外が a によってキャッチされたときにコンテキストに何が起こるかを正確に知りたいと思いますThread.UncaughtExceptionListener。キャッチされていない例外がリスナーによって受信されると、コンテキストが不安定な状態に陥ったように見えます。一部のメソッド (主にリソースに関連するもの) にアクセスできますが、非常に多くのメソッドが機能しません (または目に見えて機能しません)。これには次のものが含まれます (ただし、これに限定されません。まだ見つかっていないものもあると確信しています)。

  • Toast(私のリンクのように)
  • Dialog
  • 新しい活動の創造。これには、ノーマルContext.startActivity(Intent)とが含まれますPendingIntent

ただし、コンテキストには、コンテキスト リソース ( getString()Resourcesおよび奇妙なことに十分なNotifications ) への明らかなアクセスがまだあります。

どうしてこれなの?コンテキスト内のこの状態の不均衡 (?) によって、コンテキスト駆動の呼び出しが妨げられる原因は何ですか?

以下に、例外がキャッチされないままになっている場合にエラー アクティビティを起動することを想定したテスト アプリケーションを作成しました。私が行ってきた状況で私が言及したこと (トーストとダイアログ) をテストするには、通知ビルダーの代わりに BoomMitActivity にビルダーを配置します。

与えられた例では、アクティビティがエラーになり (どうしてできないのでしょうか?)、 がクリックされると BoomMitActivtiy が起動Notificationします。ただし、BoomMitonCreateは呼び出されません。

応用:

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>
4

1 に答える 1

3

Context 自体には何も起こりません。アプリのクラッシュ ダイアログが表示されている状況について話している場合は、クラッシュしているスレッドがそこに座って、ユーザーがボタンを押して自分自身を強制終了するのを待っています。この時点で、システムはアプリが破棄されたことを認識し、ユーザーが確認して最終的に終了するのを待っています。したがって、あなたは本当にあなたが途中であると想定し、何かが働いていることに頼るべきではありません.

さらに、このクラッシュがメイン スレッドから発生した場合、そのスレッドはブロックされたまま、ユーザーがクラッシュ ダイアログを確認するのを待っているため、自殺することができます。メッセージループを処理しているのではなく、完全にブロックされて自殺を待っています。そのスレッドでスケジュールされる作業は実行されません。メイン スレッドの場合、これには、Activity.onCreate()、Service.onStart()、および on and on などのコンポーネントのコールバックが含まれます。どのスレッドでも、これにはスレッドに関連付けられたウィンドウ UI の作業のディスパッチが含まれます。繰り返しますが、これがメイン スレッドである場合、これはおそらくすべての UI を意味します。

于 2012-05-14T20:28:09.170 に答える