主页 > 原创 > 更改安卓webkit默认的Not found page

更改安卓webkit默认的Not found page

更改后效果如下图所示:nodomain

notfound

 

显示部分由html完全实现,修改只需修改这部分即可。webkit显示该页面的具体实现过程为通过上层framework BrowserFrame.java找到resid,之后传给webkit中的FrameLoaderClientAndroid.cpp中处理文件内容,置换其中的%s字串为网址。附件中的nodomain.html文件放在framework/base/core/res/res/raw目录下,具有语言区分。图片资源放在res/assets/webkit目录下,本文附件中的html及相关代码如下所示:

 

<!--Add by tianyu-->
<html>
    <head>
        <meta name="viewport" content="target-densitydpi=320, initial-scale=1.0, user-scalable=no" />
        <title>找不到网页</title>
        <style type="text/css">
            body { margin-top: 0px; padding-top: 0px; }
            h2   { margin-top: 5px; padding-top: 50px; padding-left: 190px; color:#444444; font-size:42px;}
            li, p1 { margin-top: 5px; padding-top: 10px; color:#7e7e7e; font-size:28px;}
           
            a:link { text-decoration: underline;color: #ff8800}
            a:active { text-decoration:blink}
            a:hover { text-decoration:underline;color: red}
            a:visited { text-decoration: underline;color: #ff8800}
            .web{width:528px;margin:0 auto;}
            .no_web{width:720px;margin:0 auto; color:#444444; font-size:42px; align:center}
            .p0{ margin-top: 5px; padding-top: 40px; color:#444444; font-size:42px; align:center;}
            .p1{ margin-top: 5px; padding-top: 0px; padding-bottom: 20px; color:#7e7e7e; font-size:28px;line-height:40px}
            .p2{ color:#7e7e7e; font-size:28px; margin:-10px auto;}
        </style>
        <body style="background:#f2f2f2">
            <div>  
                <div style="width:238px;margin:0 auto;margin-top:40px">  
                    <img width="238" height="238" src="file:///android_asset/webkit/android-weberror-face.png" />  
                </div>  
            </div>

            <div class="web">
            <p class="p0" align="center">无法访问该网页!</p>
            <p class="p1"><a href="%s">%s</a> 处的网页可能暂时出现故障,也可能已永久移至某个新的网络地址。</p>
            <p class="p2">以下是几点建议:</p>
            <ul>
                <li>进行检查以确保您的设备具有信号和数据连接</li>
                <li>稍后重新载入该网页。</li>
                <li>查看 Google 提供的该网页的缓存副本</li>
            </ul>
            </div>
        </body>
    </head>
</html>
/* package */ static String getRawResFilename(int id, Context context) {
        int resid;
        switch (id) {
            case NODOMAIN:
                resid = com.android.internal.R.raw.nodomain;
                break;

            case LOADERROR:
                resid = com.android.internal.R.raw.loaderror;
                break;

            case DRAWABLEDIR:
                // use one known resource to find the drawable directory
                resid = com.android.internal.R.drawable.btn_check_off;
                break;

            case FILE_UPLOAD_LABEL:
                return context.getResources().getString(
                        com.android.internal.R.string.upload_file);

            case RESET_LABEL:
                return context.getResources().getString(
                        com.android.internal.R.string.reset);

            case SUBMIT_LABEL:
                return context.getResources().getString(
                        com.android.internal.R.string.submit);

            case FILE_UPLOAD_NO_FILE_CHOSEN:
                return context.getResources().getString(
                        com.android.internal.R.string.no_file_chosen);

            default:
                Log.e(LOGTAG, "getRawResFilename got incompatible resource ID");
                return "";
        }
        TypedValue value = new TypedValue();
        context.getResources().getValue(resid, value, true);
        if (id == DRAWABLEDIR) {
            String path = value.string.toString();
            int index = path.lastIndexOf('/');
            if (index < 0) {
                Log.e(LOGTAG, "Can't find drawable directory.");
                return "";
            }
            return path.substring(0, index + 1);
        }
        return value.string.toString();
    }
void FrameLoaderClientAndroid::dispatchDidFailProvisionalLoad(const ResourceError& error) {
    ASSERT(m_frame);
    // Ignore ErrorInterrupted since it is due to a policy interruption. This
    // is caused by a decision to download the main resource rather than
    // display it.
    if (error.errorCode() == InternalErrorInterrupted
            || error.errorCode() == InternalErrorCancelled) {
        // If we decided to download the main resource or if the user cancelled
        // it, make sure we report that the load is done.
        didFinishLoad();
        return;
    }

    AssetManager* am = globalAssetManager();

    // Check to see if the error code was not generated internally
    WebCore::PlatformBridge::rawResId id = WebCore::PlatformBridge::NoDomain;
    if ((error.errorCode() == ErrorFile ||
            error.errorCode() == ErrorFileNotFound) &&
            (!error.localizedDescription().isEmpty())) {
        id = WebCore::PlatformBridge::LoadError;
    }
    String filename = m_webFrame->getRawResourceFilename(id);
    if (filename.isEmpty())
        return;

    // Grab the error page from the asset manager
    Asset* a = am->openNonAsset(
            filename.utf8().data(), Asset::ACCESS_BUFFER);
    if (!a)
        return;

    // Take the failing url and encode html entities so javascript urls are not
    // executed.
    CString failingUrl = error.failingURL().utf8();
    WTF::Vector<char> url;
    int len = failingUrl.length();
    const char* data = failingUrl.data();
    for (int i = 0; i < len; i++) {
        char c = data[i];
        if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
                || (c >= '0' && c <= '9'))
            url.append(c);
        else {
            char buf[16];
            int res = sprintf(buf, "&#%d;", c);
            buf[res] = 0;
            url.append(buf, res);
        }
    }
    // Vector sets up its data buffer lazilly, so if failingUrl is the empty
    // string, the data buffer will be null. This will result in sanitizedUrl
    // being null, and the string substitution below will be a no-op.
    // FIXME: Ideally we'd always have a non-empty URL, or at least improve the
    // wording of the error page in this case. See http://b/5293782.
    String sanitizedUrl = url.data() ? String(url.data(), url.size()) : "";

    // Replace all occurances of %s with the failing url.
    String s = UTF8Encoding().decode((const char*)a->getBuffer(false), a->getLength());
    s = s.replace("%s", sanitizedUrl);

    // Replace all occurances of %e with the error text
    s = s.replace("%e", error.localizedDescription());

    // Create the request and the substitute data and tell the FrameLoader to
    // load with the replacement data.
    // use KURL(const char*) as KURL(const String& url) can trigger ASSERT for
    // invalidate URL string.
    loadDataIntoFrame(m_frame, KURL(ParsedURLString, data), error.failingURL(), s);

    // Delete the asset.
    delete a;

    // Report that the load is finished, since it failed.
    didFinishLoad();
}

评论:1

  1. tianyu 回复
    2013 年 5 月 7 日 于 下午 3:07

    被暴露出来的“影响到其他页面的dpi”修改方法见此

发表评论

邮箱地址不会被公开。 必填项已用*标注