0

I have a bare project, just the webview and implementation for alert and prompt... each works ok by themselves but the UI stops responding if prompt is immediately inside alert: alert(prompt("hi", "test"));

Any idea on what could be causing it? below please find the relevant parts of the code:

public class MainActivity extends AppCompatActivity implements JSDialogFragment.JSDialogResultListener{
    private WebView m_webView;

    public void OnJsDialogFragmentPositive(Bundle args, Object cb) {
        Log.d("JSDialogFragment", "OnJsDialogFragmentPositive");
        jsDialogType dType = (jsDialogType)args.getSerializable("dType");
        if(null != dType && null != cb) {
            if(JS_DIALOG_TYPE_ALERT == dType) {
                ((JsResult) cb).confirm();
            } else if(JS_DIALOG_TYPE_PROMPT == dType) {
                String value = args.getString("value");
                ((JsPromptResult) cb).confirm(null != value ? value : "");
            }
        }
    }

    public void OnJsDialogFragmentNegative(Bundle args, Object cb) {
        Log.d("JSDialogFragment", "OnJsDialogFragmentNegative");
    }

    m_webView = (WebView) findViewById(R.id.m_webView);
    m_webView.getSettings().setJavaScriptEnabled(true);

    m_webView.setWebChromeClient(new WebChromeClient() {

        // shared set up transaction code
        FragmentTransaction showJsTransactionInit() {
            FragmentTransaction ft = getFragmentManager().beginTransaction();
            android.app.Fragment prev = getFragmentManager().findFragmentByTag("mytag");
            if (prev != null) ft.remove(prev);
                ft.addToBackStack(null);
                    return ft;
                }

            @Override
            public boolean onJsAlert(WebView view, String url, String message, final android.webkit.JsResult result) {
                FragmentTransaction ft = showJsTransactionInit(); 
                DialogFragment frag = JSDialogFragment.newInstanceAlert(message, result);
                frag.show(ft, "mytag");
                return true; // handled
            }

            public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, final android.webkit.JsPromptResult result) {
                FragmentTransaction ft = showJsTransactionInit();
                DialogFragment frag = JSDialogFragment.newInstancePrompt(message, result);
                frag.show(ft, "mytag");
                return true; // handled
            }
        });

and the JSDialogFragment implementation that handles dialog:

public class JSDialogFragment extends DialogFragment {
    interface JSDialogResultListener {
        void OnJsDialogFragmentPositive(Bundle obj, Object cb);
        void OnJsDialogFragmentNegative(Bundle obj, Object cb);
    }

    private Object mCB;

    public void setCallBack(Object cb) {
        mCB = cb;
    }

    // to init alert incase it may differ from how we show prompt
    public static DialogFragment newInstanceAlert(String message, Object cb) { 
        JSDialogFragment frag = new JSDialogFragment();
        frag.setCallBack(cb);
        Bundle args = new Bundle();
        args.putString("caption", message);
        args.putSerializable("dType", jsDialogType.JS_DIALOG_TYPE_ALERT); (JS_DIALOG_TYPE_ALERT is just an enum to distinguish between the types)
        frag.setArguments(args);
        return frag;
    }

    // to init prompt incase it may differ from how we show alert
    public static DialogFragment newInstancePrompt(String message, Object cb) { 
        JSDialogFragment frag = new JSDialogFragment();
        frag.setCallBack(cb);
        Bundle args = new Bundle();
        args.putString("caption", message);
        args.putSerializable("dType", jsDialogType.JS_DIALOG_TYPE_PROMPT);
        frag.setArguments(args);
        return frag;
    }

    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (!(activity instanceof JSDialogResultListener)) {
            throw new ClassCastException(activity.toString() + " must implement JSDialogResultListener");
        }
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        final Bundle args = getArguments();
        String caption = args.getString("caption");
        jsDialogType jsDType = (jsDialogType)args.getSerializable("dType");
        if(null==jsDType) jsDType = jsDialogType.JS_DIALOG_TYPE_ALERT;

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()) //, R.style.jsDialogsTheme)
                .setTitle(R.string.jsDialogTitle)
                .setMessage(caption);

        switch(jsDType) {
            case JS_DIALOG_TYPE_ALERT:
                builder.setPositiveButton(android.R.string.ok , new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ((JSDialogResultListener) getActivity()).OnJsDialogFragmentPositive(args, mCB);
                        dialog.dismiss();
                    }
                });
                break;


            case JS_DIALOG_TYPE_PROMPT:
                builder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        args.putString("value", "waaaawwweeeee3");
                        ((JSDialogResultListener) getActivity()).OnJsDialogFragmentPositive(args, mCB);
                        dialog.dismiss();
                    }
                }).setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        ((JSDialogResultListener) getActivity()).OnJsDialogFragmentNegative(args, mCB);
                        dialog.dismiss();
                    }
                });
                break;
        }

        return builder.create();
    }
}

Any thoughts, suggestions?

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
danchik
  • 181
  • 10
  • I forgot to include the last call that navigates to the page with alert(prompt(...,...)): m_webView.loadUrl("http://example.com"); – danchik Oct 17 '16 at 23:32
  • 1
    It looks like after dismissal of the prompt, the underlying code for dismissal only hides the dialog to be dismissed later, BUT then the creation of the new fragment for alert starts and in middle of it being created, the original prompt is now being deleted by internal code and sais there is nothing on the backstack.... but alert already made a transaction and attempted to call onshow (which should have by now already added another transaction?) whats the proper way to wait for the dialog to be done before starting another.... – danchik Oct 18 '16 at 20:10

0 Answers0