Android Browser home page的实现

何时加载home page
Tab.java中实现了WebViewClient的shouldInterceptRequest接口,该函数为回调函数,最终由native代码调用。调用过程为

shouldInterceptRequest() CallbackProxy.java <- shouldInterceptRequest() BrowserFrame.java <- shouldInterceptRequest() WebCoreFrameBridge.cpp

Tab.java

        public WebResourceResponse shouldInterceptRequest(WebView view,
                String url) {
            WebResourceResponse res = HomeProvider.shouldInterceptRequest(
                    mContext, url);
            return res;
        }	


HomeProvider

       home page中的数据是从数据库中读取的,HomeProvider提供了数据。

HomeProvider.java

    public static WebResourceResponse shouldInterceptRequest(Context context,
            String url) {
        try {
            boolean useMostVisited = BrowserSettings.getInstance().useMostVisitedHomepage();
            if (useMostVisited && url.startsWith("content://")) {
                Uri uri = Uri.parse(url);
                if (AUTHORITY.equals(uri.getAuthority())) {
                    InputStream ins = context.getContentResolver()
                            .openInputStream(uri);
                    return new WebResourceResponse("text/html", "utf-8", ins);
                }
            }
        } catch (Exception e) {}
        return null;
    }
       本文只分析当主页为Most Visited时的实现。


    public ParcelFileDescriptor openFile(Uri uri, String mode) {
        try {
            ParcelFileDescriptor[] pipes = ParcelFileDescriptor.createPipe();
            final ParcelFileDescriptor write = pipes[1];
            AssetFileDescriptor afd = new AssetFileDescriptor(write, 0, -1);
            new RequestHandler(getContext(), uri, afd.createOutputStream()).start();
            return pipes[0];
        } catch (IOException e) {
            Log.e(TAG, "Failed to handle request: " + uri, e);
            return null;
        }
    }

        pipes[0]即为shouldInterceptRequest中的ins。


WebResourceResponse

       先来看WebResourceResponse。

        WebResourceResponse位于framework中,它继承了StreamLoader ,具体就不在分析了,在这里它的作用就是把文件作为一个流读出来模拟HTTP协议。

RequestHandler

       数据是由RequestHandler写入HomeProvider读出的。

public class RequestHandler extends Thread {

    private static final String TAG = "RequestHandler";
    private static final int INDEX = 1;
    private static final int RESOURCE = 2;
    private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);

    Uri mUri;
    Context mContext;
    OutputStream mOutput;

    static {
        sUriMatcher.addURI(HomeProvider.AUTHORITY, "/", INDEX);
        sUriMatcher.addURI(HomeProvider.AUTHORITY, "res/*/*", RESOURCE);
    }

    public RequestHandler(Context context, Uri uri, OutputStream out) {
        mUri = uri;
        mContext = context.getApplicationContext();
        mOutput = out;
    }

    @Override
    public void run() {
        super.run();
        try {
            doHandleRequest();
        } catch (Exception e) {
            Log.e(TAG, "Failed to handle request: " + mUri, e);
        } finally {
            cleanup();
        }
    }

    void doHandleRequest() throws IOException {
        int match = sUriMatcher.match(mUri);
        switch (match) {
        case INDEX:
            writeTemplatedIndex();
            break;
        case RESOURCE:
            writeResource(getUriResourcePath());
            break;
        }
    }

        访问主页时执行writeTemplatedIndex()

    void writeTemplatedIndex() throws IOException {
        Template t = Template.getCachedTemplate(mContext, R.raw.most_visited);
        Cursor cursor = mContext.getContentResolver().query(Browser.BOOKMARKS_URI,
                new String[] { "DISTINCT url", "title", "thumbnail" },
                "(visits > 0 OR bookmark = 1) AND url NOT LIKE 'content:%' AND thumbnail IS NOT NULL", null, "visits DESC LIMIT 12");

        t.assignLoop("most_visited", new Template.CursorListEntityWrapper(cursor) {
            @Override
            public void writeValue(OutputStream stream, String key) throws IOException {
                Cursor cursor = getCursor();
                if (key.equals("url")) {
                    stream.write(htmlEncode(cursor.getString(0)));
                } else if (key.equals("title")) {
                    stream.write(htmlEncode(cursor.getString(1)));
                } else if (key.equals("thumbnail")) {
                    stream.write("data:image/png;base64,".getBytes());
                    byte[] thumb = cursor.getBlob(2);
                    stream.write(Base64.encode(thumb, Base64.DEFAULT));
                }
            }
        });
        t.write(mOutput);
    }

        writeTemplatedIndex()中首先从database中读取数据,

Template t = Template.getCachedTemplate(mContext, R.raw.most_visited);

        是从文件中读出HTML文件并进行解析writeValue则将从数据库中读出的数据加入解析后的数据中。

最后t.write(mOutput)则将数据写入pipes[1]中。



  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值