android webview 单点登录回退按钮处理终极解决方案 看最后

对于一个内部链接。通过给webview 塞 cookices 自动登录我们内部的 oa 系统然后自动登录跳转到当前页面,但是在这个过程中webview 里面会存储多个重定向的 url ,像这种多余的 URL 必须去掉
首先对保存的Url 请求一下 看下 code 是什么东西

public class MyTask01 extends AsyncTask<String, String, Integer> {

    @Override
    protected Integer doInBackground(String... params) {
        // TODO Auto-generated method stub
        String url = params[0];
        return getPost(url);

    }

    @Override
    protected void onPostExecute(Integer result) {
        // TODO Auto-generated method stub
        if(result==302&&result==401){

// webView.mUrls.remove(indexPost);
// webView.loadUrl(redirectUrl);
}
}

}
private String redirectUrl = null;
public int getPost(String string) {
    // TODO Auto-generated method stub
    int code = 0;
    HttpGet getMethod = new HttpGet(string);
    DefaultHttpClient loginClient = new DefaultHttpClient();
    MyRedirectHandler redirectHandler = new MyRedirectHandler();
    loginClient.setRedirectHandler(redirectHandler);
    try {
        HttpResponse response = loginClient.execute(getMethod);
        code = response.getStatusLine().getStatusCode();
        for(Header header:response.getAllHeaders()){
            if("Location".equals(header.getName())){
                Log.i(TAG, "Location = " + header.getValue()); //获取转跳状态
                redirectUrl= header.getValue();
                break;
            }
        }

//
//
Log.i(TAG+string+"", "resCode = " + response.getStatusLine().getStatusCode()); //获取响应码
Log.i(TAG+string+“请求地址”, "result = " + EntityUtils.toString(response.getEntity(), “utf-8”));//获取服务器响应内容

    } catch (ClientProtocolException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return code;
}
返回的  code 里面有 302,401
有302 的里面有  location  数据 ,
但是这种过滤的方法带过繁琐,对于webview 网络请求太过麻烦,这只是给个思路,
后面通过研究给出几种处理办法:取一个其认为最优的方法

/**
 * 记录URL的栈
 * 规则:
 * 1.不可在{@code WebView.onPageFinished();}中开始记录URL
 * 2.记录需要屏蔽重定向URL
 * */
public  Stack<String> mUrls=new Stack<>();

public void onPageStarted(WebView view, String url, Bitmap favicon) {

        loadingFinished = false;
        Log.d("onPageStarted", url);
        synCookies(getContext(), url);
        currentTime = System.currentTimeMillis();//当前时间

// if(isDoubleClick()){
recordUrl(url);
// }

        super.onPageStarted(view, url, favicon);

    }

    public void onPageFinished(WebView view, String url) {
        Log.d("onPageFinished", url);
        loadingFinished = true;

        if (BuildConfig.DEBUG) {
            view.loadUrl("javascript:window.wst.showSource('<head>'+" +
                    "document.getElementsByTagName('html')[0].innerHTML+'</head>');");
        }

//这个地方的处理最要是我通过 发现在 url 请求的过程中 第一次的url 和通过单点多次登录之后最后一次的 //url 是一样的 所以在一个可控范围时间内 收尾一样那就 只取一个 url 了
if(isDoubleClick()){
if(mUrls.size()>=2 && mUrls.get(0).equals(mUrls.peek())){
String news= mUrls.firstElement();
mUrls.clear();
mUrls.push(news);
}

        }


        super.onPageFinished(view, url);


    }

/**
* 记录非重定向链接 避免刷新页面造成的重复入栈*/
private void recordUrl(String url)
{
//这里还可以根据自身业务来屏蔽一些链接放入URL栈 返回键的时候去除最后一个
if(!TextUtils.isEmpty(url)&& !url.equalsIgnoreCase(getLastPageUrl())){
mUrls.push(url);
}

}

/**获取上一页的链接*/
private synchronized  String getLastPageUrl(){
    return mUrls.size()>0 ? mUrls.peek():null;
}

/**推出上一页链接*/
public String popLastPageUrl(){
    if(mUrls.size()>=2)
    {
        mUrls.pop();// pop current page url
        return mUrls.pop();
    }
    return  null;
}


public  boolean isDoubleClick() {
    long timeInterval = currentTime - lastClickTime;
    if (0 < timeInterval && timeInterval< 10000) {
        return true;//如果间隔在0-1.秒内就是快速重复点击
    }
    lastClickTime = currentTime;
    return false;
}

@Override
public void goBack(View view) {
//这个就是点击返回回到上一个操作页面
String lastPageUrl = webView.popLastPageUrl();
if(lastPageUrl == null){
finish();
}else {
webView.loadUrl(lastPageUrl);
//这个是常见网页红色叉子就是关闭当前webview 的显示 红叉
relativeClose.setVisibility(View.VISIBLE);
}

}
这个方法容错率还是有的,但是整体对性能还是可以的
 2019年4月4日10:53:34


最新终极解决方案:

view.getOriginalUrl() ;  
主要是通过这个方法实现的终极解决方案 这个就是方法说明
之所以会有原始url的概念,是因为某些网页会执行重定向操作,那么通过这个方法获取的就是重定向之前的url。此外,这个方法和getUrl类似,如果当前网页还未加载完毕,那么获得的就是旧的原始url。

public void onPageFinished(WebView view, String url) {
Log.d(“onPageFinished”, url);
loadingFinished = true;

        recordUrl(view.getOriginalUrl());

        super.onPageFinished(view, url);


    }
里面有一个特殊的情况 就是 进入登录界面还返回了 code  为 200 这个无法 getOriginalUrl  那就加载的时候直接处理掉 ,这种为特殊情况,视情况而定 “CasServer/login”

/**
* 记录非重定向链接 避免刷新页面造成的重复入栈*/
private void recordUrl(String url)
{
//这里还可以根据自身业务来屏蔽一些链接放入URL栈 返回键的时候去除最后一个
if(!TextUtils.isEmpty(url)&& !url.equalsIgnoreCase(getLastPageUrl()) && ! url.contains(“CasServer/login”)){
mUrls.push(url);
}

}

/**获取上一页的链接*/
private synchronized  String getLastPageUrl(){
    return mUrls.size()>0 ? mUrls.peek():null;
}

/**推出上一页链接*/
public String popLastPageUrl(){
    if(mUrls.size()>=2)
    {
        mUrls.pop();// pop current page url
        return mUrls.pop();
    }
    return  null;
}

发布了46 篇原创文章 · 获赞 21 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/u012922981/article/details/89020630