PreferenceActivity中的Toast显示较晚

时间:2010-08-29 17:58:43

标签: android preferences toast preferenceactivity

我希望在用户点击PreferenceActivity中的CheckBoxPreference后立即显示Toast。

myCheckBox.setOnPreferenceClickListener(new OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {
                Toast.makeText(Prefs.this,
                        "test",
                        Toast.LENGTH_SHORT).show();
                doSomething();
                return false;
            }
        });

我还尝试将Toast放入doSomething()方法,但是在处理完整个方法之后总会显示。我尝试了getBaseContext()而不是Prefs.this,但它没有帮助。 知道Toast为什么不立刻出现以及如何做到这一点?

2 个答案:

答案 0 :(得分:3)

这是因为onPreferenceClick侦听器正在UI线程中运行。此线程也与处理显示Toast的线程相同。 Toast#show仅将消息推送到消息队列,然后运行代码以显示Toast。在onPreferenceClick处理程序完成后,才会处理该队列。

您可以尝试:

myCheckBox.setOnPreferenceClickListener(new OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference preference) {
                Toast.makeText(Prefs.this,
                        "test",
                        Toast.LENGTH_SHORT).show();

                Prefs.this.runOnUiThread(new Runnable() {
                    @Override
                        public void run() {
                            doSomething();
                        }
                    });
                return false;
            }
    });

这将导致Toast发布到消息队列,然后您的doSomething也将在吐司后发布到队列中。这样做的缺点是可能会在调用doSomething之前处理UI消息。此外,如果doSomething长时间运行,它将独占您的UI线程并可能导致可能的ANR强制关闭。如果需要超过150毫秒左右,您可能需要考虑在AsyncTask中运行doSomething

答案 1 :(得分:0)

我的解决方案是使用广播,并在android清单中注册接收器。

AndroidManifest中的

    <receiver android:name=".MyReceiver" >
        <intent-filter >
            <action android:name="showtoast" />
        </intent-filter>
    </receiver>

发送广播:

public static void BroadcastMessage(Context context, Bundle extra)
{
    Intent intent = new Intent();
    intent.setPackage(context.getPackageName());
    intent.setAction("showtoast");
    if (extra != null)
        intent.putExtras(extra);
    context.sendBroadcast(intent);
}
接收器如下:

public class MyReceiver extends BroadcastReceiver {

    public void onReceive(Context context, Intent intent) {
        Bundle bundle = intent.getExtras();
        if ("showtoast".equalsIgnoreCase(intent.getAction()) && (bundle != null)
        {
            String title = bundle.getString("title", "");

            View view;
            TextView mTextView;
            LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.my_toast_layout, null);
            mTextView = (TextView) view.findViewById(R.id.tv_title);
            mTextView.setText(title);

            Toast toast = new Toast(context.getApplicationContext());
            toast.setGravity(Gravity.CENTER, 0, 0);
            toast.setView(view);
            toast.setDuration(Toast.LENGTH_LONG);
            toast.show();
        }
    }
}