显示来自 Retrofit 拦截器的对话框

A.B*_*sha 3 android dialog interceptor retrofit

当很少有参数不满足时,我试图从 Retrofit 拦截器显示一个对话框。但是android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?在尝试显示对话框时出现异常。

这是我的代码。

final AlertDialog.Builder alertDialog = new AlertDialog.Builder(ShieldSquare.applicationContext)
            .setIcon(android.R.drawable.ic_dialog_alert)
            .setTitle("Are you sure to Exit")
            .setMessage("Exiting will call finish() method")
            .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    dialogInterface.dismiss();
                }
            })
            //set negative button
            .setNegativeButton("No", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialogInterface, int i) {
                    //set what should happen when negative button is clicked
                    Toast.makeText(ShieldSquare.applicationContext,
                            "Nothing Happened", Toast.LENGTH_LONG).show();
                }
            });

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            alertDialog.create().show();
        }
    };

    new Handler(Looper.getMainLooper()).post(runnable);
Run Code Online (Sandbox Code Playgroud)

在 Retrofit 的链进行之前,上面运行在 Interceptor 上的代码。

ssResponse = chain.proceed(originalRequest);

Hon*_*uan 5

通常,我们只显示来自活动的对话框,因此上下文ShieldSquare.applicationContext无法显示AlertDialog.

有两种方法可以满足您的需求:

第一个,使用特殊权限android.permission.SYSTEM_ALERT_WINDOW。在您的 之前alertDialog.show();,添加:

alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
Run Code Online (Sandbox Code Playgroud)

并将下面的权限添加到AndroidManifest.xml.

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
Run Code Online (Sandbox Code Playgroud)

然后你可以使用ShieldSquare.applicationContext对话框构建器。

第二个,您可以将您ShieldSquare.applicationContext的活动更新为最近的活动,然后ShieldSquare.applicationContext将始终是活动的上下文:

public abstract class BaseActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ShieldSquare.applicationContext = this;
    }
}
Run Code Online (Sandbox Code Playgroud)

我发现了一些关于BroadcastReceiver用于显示对话框的方法,你也可以看看,看SO 答案和这篇博文