Code example for WebView: Displaying web pages

Methods: loadUrlrestoreStatesetWebChromeClientsetWebViewClient, restorePicture, setDownloadListener, setOnCreateContextMenuListener

0
        mainView = newTab.mMainView;
        boolean needRestore = (mainView == null);
        if (needRestore) {
            // Same work as in createNewTab() except don't do new Tab() 
            newTab.mMainView = mainView = createNewWebView();
        } 
        mainView.setWebViewClient(mActivity.getWebViewClient());
        mainView.setWebChromeClient(mActivity.getWebChromeClient());
        mainView.setOnCreateContextMenuListener(mActivity);
        mainView.setDownloadListener(mActivity);
        // Add the subwindow if it exists 
        if (newTab.mSubViewContainer != null) {
            subView = newTab.mSubView;
            subView.setWebViewClient(newTab.mSubViewClient);
            subView.setWebChromeClient(newTab.mSubViewChromeClient);
            subView.setOnCreateContextMenuListener(mActivity);
            subView.setDownloadListener(mActivity);
        } 
        if (needRestore) {
            // Have to finish setCurrentTab work before calling restoreState 
            if (!restoreState(newTab.mSavedState, newTab)) {
                mainView.loadUrl(BrowserSettings.getInstance().getHomePage());
            } 
        } 
        return true; 
    } 
 
    /* 
     * Put the tab in the background using all the empty/background clients. 
     */ 
    private void putTabInBackground(Tab t) {
        WebView mainView = t.mMainView;
        // Set an empty callback so that default actions are not triggered. 
        mainView.setWebViewClient(mEmptyClient);
        mainView.setWebChromeClient(mBackgroundChromeClient);
        mainView.setOnCreateContextMenuListener(null);
        // Leave the DownloadManager attached so that downloads can start in 
        // a non-active window. This can happen when going to a site that does 
        // a redirect after a period of time. The user could have switched to 
        // another tab while waiting for the download to start. 
        mainView.setDownloadListener(mActivity);
        WebView subView = t.mSubView;
        if (subView != null) {
            // Set an empty callback so that default actions are not triggered. 
            subView.setWebViewClient(mEmptyClient);
            subView.setWebChromeClient(mBackgroundChromeClient);
            subView.setOnCreateContextMenuListener(null);
            subView.setDownloadListener(mActivity);
        } 
    } 
 
    /* 
     * Dismiss the subwindow for the given tab. 
     */ 
    void dismissSubWindow(Tab t) {
        if (t != null && t.mSubView != null) {
            BrowserSettings.getInstance().deleteObserver( 
                    t.mSubView.getSettings());
            t.mSubView.destroy();
            t.mSubView = null;
            t.mSubViewContainer = null;
        } 
    } 
 
    /** 
     * Ensure that Tab t has data to display in the tab picker. 
     * @param  t   Tab to populate. 
     */ 
    /* package */ void populatePickerData(Tab t) {
        if (t == null) {
            return; 
        } 
 
        // mMainView == null indicates that the tab has been freed. 
        if (t.mMainView == null) {
            populatePickerDataFromSavedState(t);
            return; 
        } 
 
        // FIXME: The only place we cared about subwindow was for  
        // bookmarking (i.e. not when saving state). Was this deliberate? 
        final WebBackForwardList list = t.mMainView.copyBackForwardList();
        final WebHistoryItem item =
                list != null ? list.getCurrentItem() : null;
        populatePickerData(t, item);
 
        // This method is only called during the tab picker creation. At this 
        // point we need to listen for new pictures since the WebView is still 
        // active. 
        final WebView w = t.getTopWindow();
        w.setPictureListener(t);
        // Capture the picture here instead of populatePickerData since it can 
        // be called when saving the state of a tab. 
        t.mPickerData.mPicture = w.capturePicture();
    } 
 
    // Create the PickerData and populate it using the saved state of the tab. 
    private void populatePickerDataFromSavedState(Tab t) {
        if (t.mSavedState == null) {
            return; 
        } 
 
        final PickerData data = new PickerData();
        final Bundle state = t.mSavedState;
        data.mUrl = state.getString(CURRURL);
        data.mTitle = state.getString(CURRTITLE);
        data.mWidth = state.getInt(CURRWIDTH, 0);
        // XXX: These keys are from WebView.savePicture so if they change, this 
        // will break. 
        data.mScale = state.getFloat("scale", 1.0f);
        data.mScrollX = state.getInt("scrollX", 0);
        data.mScrollY = state.getInt("scrollY", 0);
 
        if (state.containsKey(CURRPICTURE)) {
            final File f = new File(t.mSavedState.getString(CURRPICTURE));
            try { 
                final FileInputStream in = new FileInputStream(f);
                data.mPicture = Picture.createFromStream(in);
                in.close();
            } catch (Exception ex) {
                // Ignore any problems with inflating the picture. We just 
                // won't draw anything. 
            } 
        } 
 
        // Set the tab's picker data. 
        t.mPickerData = data;
    } 
 
    // Populate the picker data using the given history item and the current 
    // top WebView. 
    private void populatePickerData(Tab t, WebHistoryItem item) {
        final PickerData data = new PickerData();
        if (item != null) {
            data.mUrl = item.getUrl();
            data.mTitle = item.getTitle();
            if (data.mTitle == null) {
                data.mTitle = data.mUrl;
            } 
        } 
        // We want to display the top window in the tab picker but use the url 
        // and title of the main window. 
        final WebView w = t.getTopWindow();
        data.mWidth = w.getWidth();
        data.mScale = w.getScale();
        data.mScrollX = w.getScrollX();
        data.mScrollY = w.getScrollY();
        t.mPickerData = data;
    } 
     
    /** 
     * Clean up the data for all tabs. 
     */ 
    /* package */ void wipeAllPickerData() { 
        int size = getTabCount();
        for (int i = 0; i < size; i++) {
            final Tab t = getTab(i);
            if (t != null && t.mSavedState == null) {
                t.mPickerData = null;
            } 
            if (t.mMainView != null) {
                // Clear the picture listeners. 
                t.mMainView.setPictureListener(null);
                if (t.mSubView != null) {
                    t.mSubView.setPictureListener(null);
                } 
            } 
        } 
    } 
 
    /* 
     * Save the state for an individual tab. 
     */ 
    private boolean saveState(Tab t) {
        if (t != null) {
            final WebView w = t.mMainView;
            // If the WebView is null it means we ran low on memory and we 
            // already stored the saved state in mSavedState. 
            if (w == null) {
                return true; 
            } 
            final Bundle b = new Bundle();
            final WebBackForwardList list = w.saveState(b);
            if (list != null) {
                final File f = new File(mThumbnailDir, w.hashCode()
                        + "_pic.save"); 
                if (w.savePicture(b, f)) {
                    b.putString(CURRPICTURE, f.getPath());
                } 
            } 
 
            // Store some extra info for displaying the tab in the picker. 
            final WebHistoryItem item =
                    list != null ? list.getCurrentItem() : null;
            populatePickerData(t, item);
 
            // XXX: WebView.savePicture stores the scale and scroll positions 
            // in the bundle so we don't have to do it here. 
            final PickerData data = t.mPickerData;
            if (data.mUrl != null) {
                b.putString(CURRURL, data.mUrl);
            } 
            if (data.mTitle != null) {
                b.putString(CURRTITLE, data.mTitle);
            } 
            b.putInt(CURRWIDTH, data.mWidth);
            b.putBoolean(CLOSEONEXIT, t.mCloseOnExit);
            if (t.mAppId != null) {
                b.putString(APPID, t.mAppId);
            } 
            if (t.mOriginalUrl != null) {
                b.putString(ORIGINALURL, t.mOriginalUrl);
            } 
 
            // Remember the parent tab so the relationship can be restored. 
            if (t.mParentTab != null) {
                b.putInt(PARENTTAB, getTabIndex(t.mParentTab));
            } 
 
            // Remember the saved state. 
            t.mSavedState = b;
            return true; 
        } 
        return false; 
    } 
 
    /* 
     * Restore the state of the tab. 
     */ 
    private boolean restoreState(Bundle b, Tab t) {
        if (b == null) {
            return false; 
        } 
        // Restore the internal state even if the WebView fails to restore. 
        // This will maintain the app id, original url and close-on-exit values. 
        t.mSavedState = null;
        t.mPickerData = null;
        t.mCloseOnExit = b.getBoolean(CLOSEONEXIT);
        t.mAppId = b.getString(APPID);
        t.mOriginalUrl = b.getString(ORIGINALURL);
 
        final WebView w = t.mMainView;
        final WebBackForwardList list = w.restoreState(b);
        if (list == null) {
            return false; 
        } 
        if (b.containsKey(CURRPICTURE)) {
            final File f = new File(b.getString(CURRPICTURE));
            w.restorePicture(b, f);
            f.delete();
        } 
        return true; 
    }