Changing Webview Url with Angular

I've been trying to change my webview URL by calling a function via AngularJs, but I had no success so far.

Here is my angular class:

app.controller("speechController", function($scope){
    $scope.page = 'index.html';
    $scope.url = function(page){
        Android.receivePage();
    }
});

And here is my Java class:

public class MainActivity extends AppCompatActivity {


    Button b;
    CustomWebViewClient customWebViewClient;
    WebView myWebView;
    private TextToSpeech tts;
    private final int REQ_CODE_SPEECH_INPUT = 100;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(R.layout.activity_main);



        myWebView = (WebView) findViewById(R.id.webView);
        myWebView.addJavascriptInterface(this, "Android");
        myWebView.setWebViewClient(new WebViewClient());
        WebSettings webSettings = myWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        myWebView.loadUrl("file:///android_asset/index.html");
        b= (Button)  findViewById(R.id.button);
        b.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                receivePage();

            }
        });

    }



    @JavascriptInterface
    public void receivePage() {
        myWebView.loadUrl("file:///android_asset/index.html");
    }
}

Notice that I created a button in onCreate just to call the receivePage function for testing. And by debugging, I noticed that both Angular function and the button onClick function correctly calls receivePage(), however only the button correctly changes the URL. I need to use angular to change the webview due to the project's necessities. Does anyone knows why my code is behaving this way?

Upvotes: 1

Views: 794

Answers (1)

I figured it out, so I'll post it in here in case someone else have the same problem. So, the thing is that JavascriptInteface uses a different thread than webview, and webview only accepts requests made by the same thread, all I had to do was replace:

@JavascriptInterface
public void receivePage() {
    myWebView.loadUrl("file:///android_asset/index.html");
}

with:

@JavascriptInterface
public void receivePage() {
    myWebView.post(new Runnable() {
        @Override
        public void run() {
            myWebView.loadUrl("file:///android_asset/index.html");
        }
    });
}

Upvotes: 1

Related Questions