0

I am implementing a client end library to an OAUTH API. In the authentication process, a webview client would fire up and load the authentication page's URL.However, the webview client sometimes start correctly, but recently started causing ANRs.

Here's the code for library:

public String inflateView(Activity activity,String redirectUrl, String scope){

    final String rUrl=redirectUrl;
    LayoutInflater inflater = activity.getLayoutInflater();
    page=inflater.inflate(R.layout.web_overlay, null);
    final String scopes=scope;
    activity.setContentView(page);
    gWebView = (WebView) page.findViewById(R.id.webview);
    gWebView.loadUrl("https://api.23andme.com/authorize/?redirect_uri="
            + redirectUrl + "&response_type=code&client_id=" + this.clientId
            + "&scope=" + scope );
    Log.d(TAG, "http://192.241.244.189/auth/authorize?response_type=code&client_id=IV9AMqP9&scope=read:sequence read:patient");

    gWebView.setWebViewClient(new WebViewClient(){
        @Override
        public void onPageFinished(WebView view, String url) {
            super.onPageFinished(view, url);
            if(url.startsWith("https://api.23andme.com")){
                Log.d(TAG, "got to authentication page");
            }
            if (url.startsWith(rUrl)) {
                System.out.println("got to override");
                if (url.indexOf("code=") != -1) {
                    //if the query contains code
                    String queryString = null;
                    try {
                        queryString = new URL(url).getQuery();
                    } catch (MalformedURLException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    System.out.println(queryString);
                    String[] params = queryString.split("&");
                    for (String param : params) {
                        if (param.startsWith("code=")) {
                            code = param.substring(param.indexOf('=') + 1);
                        }
                    }
                    gWebView.setVisibility(View.GONE);
                    request= new PostRequest();
                    request.execute(code, smartClient.this.clientId, smartClient.this.clientSecret, rUrl, scopes);
                    Log.d(TAG, "Post execute");
                    Log.d(TAG, "cancelled");
                    while(true){
                        if(!accessToken.equals("")){
                            request.cancel(true);
                            Log.d(TAG, "not empty");
                            gWebView.destroy();
                            break;
                        }
                    }
                    // don't go to redirectUri
                }
            }
        }
    });

And I called it using:

client= new smartClient(id, secret);
    String token=client.inflateView(SmartActivity.this,REDIRECT_URI, SCOPE);

the layout for webview:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<WebView
    android:id="@+id/webview"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

</LinearLayout>

Have I unknowingly done something stupid here?

EDIT: The PostRequest is an AsyncTask class, just to clarify. EDIT: I found the reason to be this code running outside the webview client:

    while(true){
        if(!accessToken.equals("")){
            Log.d(TAG, "not empty");
            break;
        }
    }

It's not a smart thing to do I know, but how would you implement some listener mechanism that waits until the accessToken is not empty and then returns it?

StephenChen
  • 711
  • 2
  • 8
  • 20

1 Answers1

0
       while(true){
                if(!accessToken.equals("")){
                    request.cancel(true);
                    Log.d(TAG, "not empty");
                    gWebView.destroy();
                    break;
                }
            }

You have a loop, that waits for response for background thread. It's not correct solution. Consider using listener mechanism.

Nickolai Astashonok
  • 2,878
  • 3
  • 20
  • 23