Android 首选项中的Toast活动延迟显示

Android 首选项中的Toast活动延迟显示,android,preferences,toast,preferenceactivity,Android,Preferences,Toast,Preferenceactivity,我想在用户单击我的首选项活动中的复选框首选项后立即显示祝酒词 myCheckBox.setOnPreferenceClickListener(new OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { Toast.makeText(Prefs.this,

我想在用户单击我的首选项活动中的复选框首选项后立即显示祝酒词

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。这
,但没有帮助。
你知道为什么Toast不会立即出现,以及如何让它出现吗?

之所以会出现这种情况,是因为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
也将在Toast之后发布到队列。这样做的缺点是,在调用
doSomething
之前,可能会处理UI消息。此外,如果
doSomething
长时间运行,它将独占您的UI线程,并可能导致ANR强制关闭。如果需要超过150毫秒左右的时间,您可能需要考虑在一个应用程序中运行
doSomething

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

在AndroidManifest中:

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

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();
        }
    }
}

谢谢你详细解释。该方法实际上是启动OAuth握手,然后启动一个新的活动,显示一个WebView来执行OAuth授权。因此,当用户单击复选框时,WebView活动开始前需要几秒钟,因为首先建立到Twitter的连接以接收请求令牌。-->我想展示toast的原因是为了通知用户,如果他不明白为什么几秒钟内(在WebView活动启动/显示之前)似乎什么都没有发生,那么会发生一些事情。使用进度对话框What is Prefs来展示asynctask。这??感谢您详细介绍这个概念。在我的例子中,我必须用v.post(new Runnable()…rununuithread)替换rununuithread(new Runnable…)。rununuithread将使该块立即运行。v.post将把该块放在运行队列的末尾,以提供所需的效果。
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();
        }
    }
}