x5android
2019-03-10 17:56:43 imsjw 阅读数 9

AndroidManifest.xml
1.添加jar包

在libs目录下添加sdk中的jar包
将Demo中的jniLibs目录复制到 main文件夹下

2.需要添加权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> 

3.build.gradle 添加配置

 ndk {
     abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
 }

4.页面

<com.tencent.smtt.sdk.WebView
        android:id="@+id/web_view"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:paddingLeft="5dp"
        android:paddingRight="5dp" />

5.Activity

package com.sykj.article.articlesystem;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import com.tencent.smtt.sdk.QbSdk;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;

public class MainActivity extends AppCompatActivity {

    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.web_view);
        initX5WebView();
        webView = findViewById(R.id.web_view);
        //防止跳转到系统浏览器
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                loadurlLocalMethod(view, url);
                return false;
            }
        });
        webView.loadUrl("http://www.baidu.com");
    }

    public void loadurlLocalMethod(final WebView webView, final String url) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                webView.loadUrl(url);
            }
        });
    }

    private void initX5WebView() {
        //搜集本地tbs内核信息并上报服务器,服务器返回结果决定使用哪个内核。
        QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {
            @Override
            public void onViewInitFinished(boolean arg0) {
                if (arg0) {
                    Log.d("ArticleSystem", "X5 内核加载成功");
                } else {
                    Log.d("ArticleSystem", "X5 内核加载失败");
                }
            }

            @Override
            public void onCoreInitFinished() {
            }
        };
        //x5内核初始化接口
        QbSdk.initX5Environment(getApplicationContext(), cb);
    }
}

完整配置
AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sykj.article.articlesystem">

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

web_view.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.tencent.smtt.sdk.WebView
        android:id="@+id/web_view"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:paddingLeft="5dp"
        android:paddingRight="5dp" />

</android.support.constraint.ConstraintLayout>

build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.sykj.article.articlesystem"
        minSdkVersion 15
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        ndk {
            abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation files('libs/tbs_sdk_thirdapp_v3.6.0.1352_43618_sharewithdownload_withoutGame_obfs_20180918_120327.jar')
}
2019-01-29 10:25:00 weixin_33826268 阅读数 3

AndroidManifest.xml
1.添加jar包
在libs目录下添加sdk中的jar包
将Demo中的jniLibs目录复制到 main文件夹下
2.需要添加权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> 

3.build.gradle 添加配置

 ndk {
     abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
 }

4.页面

<com.tencent.smtt.sdk.WebView
        android:id="@+id/web_view"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:paddingLeft="5dp"
        android:paddingRight="5dp" />

5.Activity

package com.sykj.article.articlesystem;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import com.tencent.smtt.sdk.QbSdk;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;

public class MainActivity extends AppCompatActivity {

    private WebView webView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.web_view);
        initX5WebView();
        webView = findViewById(R.id.web_view);
        //防止跳转到系统浏览器
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                loadurlLocalMethod(view, url);
                return false;
            }
        });
        webView.loadUrl("http://www.baidu.com");
    }

    public void loadurlLocalMethod(final WebView webView, final String url) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                webView.loadUrl(url);
            }
        });
    }

    private void initX5WebView() {
        //搜集本地tbs内核信息并上报服务器,服务器返回结果决定使用哪个内核。
        QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {
            @Override
            public void onViewInitFinished(boolean arg0) {
                if (arg0) {
                    Log.d("ArticleSystem", "X5 内核加载成功");
                } else {
                    Log.d("ArticleSystem", "X5 内核加载失败");
                }
            }

            @Override
            public void onCoreInitFinished() {
            }
        };
        //x5内核初始化接口
        QbSdk.initX5Environment(getApplicationContext(), cb);
    }
}

完整配置
AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sykj.article.articlesystem">

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

web_view.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.tencent.smtt.sdk.WebView
        android:id="@+id/web_view"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:paddingLeft="5dp"
        android:paddingRight="5dp" />

</android.support.constraint.ConstraintLayout>

build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "com.sykj.article.articlesystem"
        minSdkVersion 15
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        ndk {
            abiFilters "armeabi", "armeabi-v7a", "x86", "mips"
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation files('libs/tbs_sdk_thirdapp_v3.6.0.1352_43618_sharewithdownload_withoutGame_obfs_20180918_120327.jar')
}

2016-09-21 16:47:00 weixin_33769207 阅读数 102

1、浏览器内核:

主流浏览器内核介绍(前端开发值得了解的浏览器内核历史)

浏览器内核历史介绍:

在android 4.4之前,浏览器用的还是webkit

在android 4.4之后,google就抛弃了webkit,只是保留了webkit中关于排版渲染方面的代码,同时还把Browser应用给去掉了引擎方面已经换成了一个叫​C​h​ro​m​i​u​m​的内核。

Blink 其实是 WebKit 的分支,如同 WebKit 是 KHTML 的分支

Trident(IE内核)

Gecko(Firefox 内核)

WebKit 前身是 KDE 小组的 KHTML 引擎,可以说 WebKit 是 KHTML 的一个开源的分支。当年苹果在比较了 Gecko 和 KHTML 后,选择了后者来做引擎开发,是因为 KHTML 拥有清晰的源码结构和极快的渲染速度。

2、腾讯x5浏览器内核:

X5是腾讯QQ浏览器产品部推出的,面向第三方开放X5内核引擎的产品服务。从目前来看,微信、手Q、空间和QQ浏览器都已经内置了X5内核,基本上所有的手机用户手机里都有QQ浏览器X5内核了。所以第三方只要通过很小的sdk就可以调用到这些app里面的X5。

TBS(腾讯浏览服务)

官方接入文档

运行条件:

1) 手机ROM版本高于或等于2.2版本

2) 手机RAM大于500M,该RAM值通过手机 /proc/meminfo 文件的MemTotal动态获取

注:如果不满足上述条件,SDK会自动切换到系统WebView,SDK使用者不用关心该切换过程。

接入x5,有两种:

1、Android SDK(Share Only)

  这种接入方式,减少包的大小,但是需要手机本身安装了微信(6.1版本以上)、手Q、空间。

2、Android SDK(With download)

     这种接入方式,需要复制“Android SDK(With download)”的jar包到工程的libs目录下。

在Android工程的AndroidManifest.xml中申明腾讯X5服务所需的权限:

1     <!-- 申请腾讯X5所需权限 -->  
2     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
3     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />  
4     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />  
5     <uses-permission android:name="android.permission.INTERNET" />  
6     <uses-permission android:name="android.permission.READ_PHONE_STATE" />  

辨别是否使用x5webview的方法:

显示网页文字时,可通过长按选择文字的标识判断,如下水滴状选择效果是x5webview 的标志

基于腾讯X5内核的混合APP开发模式

2019-01-15 17:13:58 qq_34468274 阅读数 125

腾讯x5内核 可替换android自带的webview,优化打开速度,相比之下 腾讯内核比跟原声的比真的6到飞起   

腾讯X5内核官方sdk地址

首先导入项目的jar和os文件 

导入文件后 引入jar后 在 Application 初始化腾讯内核服务

QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {
            @Override
            public void onViewInitFinished(boolean arg0) {
                // TODO Auto-generated method stub
                //x5內核初始化完成的回调,为true表示x5内核加载成功,否则表示x5内核加载失败,会自动切换到系统内核。
                Log.d("app", " onViewInitFinished is " + arg0);
            }

            @Override
            public void onCoreInitFinished() {
                // TODO Auto-generated method stub
            }
        };
        //x5内核初始化接口
        QbSdk.initX5Environment(getApplicationContext(), cb);
还需要一个x5的工具类 来替换webview的工具   直接复制到项目中 备用
public class X5WebView extends WebView {
	TextView title;
	private Context context;
	private WebViewClient client = new WebViewClient() {
		/**
		 * 防止加载网页时调起系统浏览器
		 */
		public boolean shouldOverrideUrlLoading(WebView view, String url) {
			if (url.startsWith("http:") || url.startsWith("https:")){
				view.loadUrl(url);

				Map<String, String> extraHeaders = new HashMap<String, String>();
				extraHeaders.put("Referer", "");//这里可换成自己域名 不写也没事
				view.loadUrl(url, extraHeaders);
				return false;
			}else {
				if (url.startsWith("weixin://wap/pay?")) {//这里拦截了支付 不跳转支付页面直接打开支付功能
					Intent intent = new Intent();
					intent.setAction(Intent.ACTION_VIEW);
					intent.setData(Uri.parse(url));
					context.startActivity(intent);
				}
				return true;
			}
		}
	};

	@SuppressLint("SetJavaScriptEnabled")
	public X5WebView(Context arg0, AttributeSet arg1) {
		super(arg0, arg1);
		this.context=arg0;
		this.setWebViewClient(client);
		// this.setWebChromeClient(chromeClient);
		// WebStorage webStorage = WebStorage.getInstance();
		initWebViewSettings();
		this.getView().setClickable(true);
	}
//这是一些设置文件  具体的意思 可以百度 或者翻看我之前的博客 这里设置可以打开图片 视频还有自适应的主要功能
	private void initWebViewSettings() {
		WebSettings webSetting = this.getSettings();
		webSetting.setJavaScriptEnabled(true);
		webSetting.setJavaScriptCanOpenWindowsAutomatically(true);
		webSetting.setAllowFileAccess(true);
		webSetting.setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS);
		webSetting.setSupportZoom(true);
		webSetting.setBuiltInZoomControls(true);
		webSetting.setUseWideViewPort(true);
		webSetting.setSupportMultipleWindows(true);
		// webSetting.setLoadWithOverviewMode(true);
		webSetting.setAppCacheEnabled(true);
		// webSetting.setDatabaseEnabled(true);
		webSetting.setDomStorageEnabled(true);
		webSetting.setGeolocationEnabled(true);
		webSetting.setAppCacheMaxSize(Long.MAX_VALUE);
		// webSetting.setPageCacheCapacity(IX5WebSettings.DEFAULT_CACHE_CAPACITY);
		webSetting.setPluginState(WebSettings.PluginState.ON_DEMAND);
		// webSetting.setRenderPriority(WebSettings.RenderPriority.HIGH);
		webSetting.setCacheMode(WebSettings.LOAD_NO_CACHE);

		// this.getSettingsExtension().setPageCacheCapacity(IX5WebSettings.DEFAULT_CACHE_CAPACITY);//extension
		// settings 的设计
	}

	@Override
	protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
		boolean ret = super.drawChild(canvas, child, drawingTime);
	
		return ret;
	}

	public X5WebView(Context arg0) {
		super(arg0);
		setBackgroundColor(85621);
	}

}

现在准备工作就完成了  接下来创建一个新的activity文件 

先创建xml  主要就是一个framelayout 其他的导航栏什么的 根据自己的写 一般导航栏的名字 可根据网页的title修改 在java里面会给到代码 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"

    android:orientation="vertical"> 
<RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical">

        <FrameLayout
            android:id="@+id/webView1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"></FrameLayout>

    


    </RelativeLayout>
</LinearLayout>

java文件代码  代码主要来源于官方dome 这里增加了 打开本地相册 还有一些提示框的相关功能

public class BrowserActivity extends BaseActivity {
    /**
     * 作为一个浏览器的示例展示出来,采用android+web的模式
     */



    private X5WebView mWebView;
    private ViewGroup mViewParent;
    private ImageButton mBack;
    private ImageButton mForward;
    private ImageButton mExit;
    private ImageButton mHome;
    private ImageButton mMore;
    private Button mGo;
    private EditText mUrl;

    private static final String mHomeUrl = "url";
    private static final String TAG = "SdkDemo";
    private static final int MAX_LENGTH = 14;
    private boolean mNeedTestPage = false;

    private final int disable = 120;
    private final int enable = 255;

    private ProgressBar mPageLoadingProgressBar = null;

    public final static int FILE_CHOOSER_RESULT_CODE_FOR_ANDROID_5 = 2;
    private final static int FILE_CHOOSER_RESULT_CODE = 1;// 表单的结果回调
    public ValueCallback<Uri[]> mUploadMessageForAndroid5;
    private ValueCallback<Uri> uploadFile;
    TitleBar mTitleBar;
    public URL mIntentUrl;
    public static final String URLS = "url";
    public static final String TITLE = "title";
    private String weiuri;
    private Intent intent;
    KeyMapDailog dialogs;
    private String stringExtra;

    @Override
    protected int getLayoutID() {//设置xml路径 
        return R.layout.activity_main;
    }

    public static Intent newIntent(Activity fromActivity, String url, String title) {
        Intent intent = new Intent(fromActivity, BrowserActivity.class);
        intent.putExtra(mHomeUrl, url);
        intent.putExtra(TITLE, title);

        return intent;
    }

    String[] mPermissionList = new String[]{Manifest.permission.CAMERA,
            Manifest.permission.READ_EXTERNAL_STORAGE};

   

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
     
     
        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        stringExtra = getIntent().getStringExtra(mHomeUrl);
       
        if (null == stringExtra) {
            return;
        }
        weiuri = new String(Urls.BASE_URL + "article/view?arcId=" + stringExtra);
        Intent intent = getIntent();
        if (weiuri.length() == 0) {
            return;
        }

        if (intent != null) {
            try {
                mIntentUrl = new URL(intent.getData().toString());
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (NullPointerException e) {

            } catch (Exception e) {
            }
        }
        //
        try {
            if (Integer.parseInt(android.os.Build.VERSION.SDK) >= 11) {
                getWindow()
                        .setFlags(//硬件加速
                                android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
                                android.view.WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
            }
        } catch (Exception e) {
        }

        /*
         * getWindow().addFlags(
         * android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN);
         */
        //setContentView(R.layout.activity_mains);
        mViewParent = (ViewGroup) findViewById(R.id.webView1);

        initBtnListenser();

        mTestHandler.sendEmptyMessageDelayed(MSG_INIT_UI, 10);

    }


    private void changGoForwardButton(WebView view) {
        if (view.canGoBack())
            mBack.setAlpha(enable);
        else
            mBack.setAlpha(disable);
        if (view.canGoForward())
            mForward.setAlpha(enable);
        else
            mForward.setAlpha(disable);
        if (view.getUrl() != null && view.getUrl().equalsIgnoreCase(weiuri)) {
            mHome.setAlpha(disable);
            mHome.setEnabled(false);
        } else {
            mHome.setAlpha(enable);
            mHome.setEnabled(true);
        }
    }

    private void initProgressBar() {
        mPageLoadingProgressBar = (ProgressBar) findViewById(R.id.progressBar1);// new
        mPageLoadingProgressBar.setMax(100);
        mPageLoadingProgressBar.setProgressDrawable(this.getResources()
                .getDrawable(R.drawable.color_progressbar));
    }

    public View init() {

        mWebView = new X5WebView(this, null);

        mViewParent.addView(mWebView, new FrameLayout.LayoutParams(
                FrameLayout.LayoutParams.FILL_PARENT,
                FrameLayout.LayoutParams.FILL_PARENT));

        initProgressBar();

        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
//这里可拦截web的连接 进行相关操作 
//给个简单的例子 
   if (url.startsWith("http:") || url.startsWith("https:")) { 
                    view.loadUrl(url);
                    Map<String, String> extraHeaders = new HashMap<String, String>();
                    extraHeaders.put("Referer", "");
                    view.loadUrl(url, extraHeaders);
                    return false;
                } else {
                     if (url.contains("jxz://h5share")) { //这里拦截了url包换jxz://h5share 这段代码 然后从连接里面 找到sharedesc 等的一些参数 可以做相关操作
                        Uri uri = Uri.parse(url);
                        String sharedesc = uri.getQueryParameter("sharedesc");
                    
                    }//
}
                return true;
            }


            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                if (view.getTitle().length() != 0) {
                    mTitleBar.setTitle(view.getTitle());
                }
       
                mTestHandler.sendEmptyMessageDelayed(MSG_OPEN_TEST_URL, 5000);// 5s?
                if (Integer.parseInt(android.os.Build.VERSION.SDK) >= 16)
                    changGoForwardButton(view);
              
            }
        });


        mWebView.setWebChromeClient(new WebChromeClient() {

            @Override
            public boolean onJsConfirm(WebView arg0, String arg1, String arg2,
                                       JsResult arg3) {
                return super.onJsConfirm(arg0, arg1, arg2, arg3);
            }

            View myVideoView;
            View myNormalView;
            CustomViewCallback callback;

            // /////////////////////////////////////////////////////////
            //

            /**
             * 全屏播放配置
             */
            @Override
            public void onShowCustomView(View view,
                                         CustomViewCallback customViewCallback) {
                FrameLayout normalView = (FrameLayout) findViewById(R.id.web_filechooser);
                ViewGroup viewGroup = (ViewGroup) normalView.getParent();
                viewGroup.removeView(normalView);
                viewGroup.addView(view);
                myVideoView = view;
                myNormalView = normalView;
                callback = customViewCallback;
            }

            @Override
            public void onHideCustomView() {
                if (callback != null) {
                    callback.onCustomViewHidden();
                    callback = null;
                }
                if (myVideoView != null) {
                    ViewGroup viewGroup = (ViewGroup) myVideoView.getParent();
                    viewGroup.removeView(myVideoView);
                    viewGroup.addView(myNormalView);
                }
            }

            @Override
            public boolean onJsAlert(WebView arg0, String arg1, String arg2,
                                     JsResult arg3) {
                /**
                 * 这里写入你自定义的window alert
                 */
                return super.onJsAlert(null, arg1, arg2, arg3);
            }
        });

        mWebView.setDownloadListener(new DownloadListener() {

            @Override
            public void onDownloadStart(String arg0, String arg1, String arg2,
                                        String arg3, long arg4) {
                TbsLog.d(TAG, "url: " + arg0);
                new AlertDialog.Builder(BrowserActivity.this)
                        .setTitle("allow to download?")
                        .setPositiveButton("yes",
                                new DialogInterface.OnClickListener() {
                                    @Override
                                    public void onClick(DialogInterface dialog,
                                                        int which) {
                                        Toast.makeText(
                                                BrowserActivity.this,
                                                "fake message: i'll download...",
                                                Toast.LENGTH_SHORT).show();
                                    }
                                })
                        .setNegativeButton("no",
                                new DialogInterface.OnClickListener() {

                                    @Override
                                    public void onClick(DialogInterface dialog,
                                                        int which) {
                                        // TODO Auto-generated method stub
                                        Toast.makeText(
                                                BrowserActivity.this,
                                                "fake message: refuse download...",
                                                Toast.LENGTH_SHORT).show();
                                    }
                                })
                        .setOnCancelListener(
                                new DialogInterface.OnCancelListener() {

                                    @Override
                                    public void onCancel(DialogInterface dialog) {
                                        // TODO Auto-generated method stub
                                        Toast.makeText(
                                                BrowserActivity.this,
                                                "fake message: refuse download...",
                                                Toast.LENGTH_SHORT).show();
                                    }
                                }).show();
            }
        });

        WebSettings webSetting = mWebView.getSettings();
        webSetting.setAllowFileAccess(true);
        webSetting.setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS);
        webSetting.setSupportZoom(true);
        webSetting.setBuiltInZoomControls(true);
        webSetting.setUseWideViewPort(true);
        webSetting.setSupportMultipleWindows(false);
        // webSetting.setLoadWithOverviewMode(true);
        webSetting.setAppCacheEnabled(true);
        // webSetting.setDatabaseEnabled(true);
        webSetting.setDomStorageEnabled(true);
        webSetting.setJavaScriptEnabled(true);
        webSetting.setGeolocationEnabled(true);
        webSetting.setMixedContentMode(android.webkit.WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);

        webSetting.setAppCacheMaxSize(Long.MAX_VALUE);
        webSetting.setAppCachePath(this.getDir("appcache", 0).getPath());
        webSetting.setDatabasePath(this.getDir("databases", 0).getPath());
        webSetting.setGeolocationDatabasePath(this.getDir("geolocation", 0)
                .getPath());
        // webSetting.setPageCacheCapacity(IX5WebSettings.DEFAULT_CACHE_CAPACITY);
        webSetting.setPluginState(WebSettings.PluginState.ON_DEMAND);
        // webSetting.setRenderPriority(WebSettings.RenderPriority.HIGH);
        // webSetting.setPreFectch(true);
        long time = System.currentTimeMillis();
        if (mIntentUrl == null) {
            mWebView.loadUrl(weiuri);
        } else {
            mWebView.loadUrl(mIntentUrl.toString());
        }
        TbsLog.d("time-cost", "cost time: "
                + (System.currentTimeMillis() - time));
        CookieSyncManager.createInstance(this);
        CookieSyncManager.getInstance().sync();


        //H5界面加载进度监听
        mWebView.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onProgressChanged(WebView view, int newProgress) {
                super.onProgressChanged(view, newProgress);
            }

            // For Android < 5.0
            public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
                openFileChooserImpl(uploadMsg);
            }

            // For Android => 5.0
            public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> uploadMsg,
                                             WebChromeClient.FileChooserParams fileChooserParams) {
                onenFileChooseImpleForAndroid(uploadMsg);
                return true;
            }

        });

        return null;
    }


    /**
     * android 5.0 以下开启图片选择(原生)
     * <p>
     * 可以自己改图片选择框架。
     */
    private void openFileChooserImpl(ValueCallback<Uri> uploadMsg) {
        uploadFile = uploadMsg;
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("image/*");
        startActivityForResult(Intent.createChooser(i, "File Chooser"), FILE_CHOOSER_RESULT_CODE);
    }

    /**
     * android 5.0(含) 以上开启图片选择(原生)
     * <p>
     * 可以自己改图片选择框架。
     */
    private void onenFileChooseImpleForAndroid(ValueCallback<Uri[]> filePathCallback) {
        mUploadMessageForAndroid5 = filePathCallback;
        Intent contentSelectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
        contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
        contentSelectionIntent.setType("image/*");

        Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
        chooserIntent.putExtra(Intent.EXTRA_INTENT, contentSelectionIntent);
        chooserIntent.putExtra(Intent.EXTRA_TITLE, "Image Chooser");

        startActivityForResult(chooserIntent, FILE_CHOOSER_RESULT_CODE_FOR_ANDROID_5);
    }

    private void initBtnListenser() {
        mBack = (ImageButton) findViewById(R.id.btnBack1);
        mForward = (ImageButton) findViewById(R.id.btnForward1);
        mExit = (ImageButton) findViewById(R.id.btnExit1);
        mHome = (ImageButton) findViewById(R.id.btnHome1);
        mGo = (Button) findViewById(R.id.btnGo1);
        mUrl = (EditText) findViewById(R.id.editUrl1);
        mMore = (ImageButton) findViewById(R.id.btnMore);
        if (Integer.parseInt(android.os.Build.VERSION.SDK) >= 16) {
            mBack.setAlpha(disable);
            mForward.setAlpha(disable);
            mHome.setAlpha(disable);
        }
    

      


       

       
    }

    boolean[] m_selected = new boolean[]{true, true, true, true, false,
            false, true};

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (mWebView != null && mWebView.canGoBack()) {
                mWebView.goBack();
                if (Integer.parseInt(android.os.Build.VERSION.SDK) >= 16)
                    changGoForwardButton(mWebView);
                return true;
            } else
                return super.onKeyDown(keyCode, event);
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        TbsLog.d(TAG, "onActivityResult, requestCode:" + requestCode
                + ",resultCode:" + resultCode);

        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case 0:
                    Uri result;
                    if (null != uploadFile) {
                        result = data == null || resultCode != RESULT_OK ? null
                                : data.getData();
                        uploadFile.onReceiveValue(result);
                        uploadFile = null;
                    }
                    break;
                case FILE_CHOOSER_RESULT_CODE:  //android 5.0以下 选择图片回调
                    result = (intent == null || resultCode != Activity.RESULT_OK) ? null : intent.getData();
                    if (null == uploadFile)
                        return;
                    uploadFile.onReceiveValue(result);
                    uploadFile = null;

                    break;

                case FILE_CHOOSER_RESULT_CODE_FOR_ANDROID_5:  //android 5.0(含) 以上 选择图片回调
                    result = data.getData();
                    if (null == mUploadMessageForAndroid5)
                        return;
                    if (result != null) {
                        mUploadMessageForAndroid5.onReceiveValue(new Uri[]{result});
                    } else {
                        mUploadMessageForAndroid5.onReceiveValue(new Uri[]{});
                    }
                    mUploadMessageForAndroid5 = null;

                    break;
                default:
                    break;
            }
        } else if (resultCode == RESULT_CANCELED) {
            if (null != uploadFile) {
                uploadFile.onReceiveValue(null);
                uploadFile = null;
            }

        }

    }

    @Override
    protected void onNewIntent(Intent intent) {
        if (intent == null || mWebView == null || intent.getData() == null)
            return;
        mWebView.loadUrl(intent.getData().toString());
    }

    @Override
    protected void onDestroy() {
        if (mTestHandler != null)
            mTestHandler.removeCallbacksAndMessages(null);
        if (mWebView != null)
            mWebView.destroy();
        super.onDestroy();
    }


    public static final int MSG_OPEN_TEST_URL = 0;
    public static final int MSG_INIT_UI = 1;
    private final int mUrlStartNum = 0;
    private int mCurrentUrl = mUrlStartNum;
    private Handler mTestHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_OPEN_TEST_URL:
                    if (!mNeedTestPage) {
                        return;
                    }

                    String testUrl = "file:///sdcard/outputHtml/html/"
                            + Integer.toString(mCurrentUrl) + ".html";
                    if (mWebView != null) {
                        mWebView.loadUrl(testUrl);
                    }

                    mCurrentUrl++;
                    break;
                case MSG_INIT_UI:
                    init();
                    break;
            }
            super.handleMessage(msg);
        }
    };

    private void startAlipayActivity(String url) {

        Intent intent;
        try {
            intent = Intent.parseUri(url,
                    Intent.URI_INTENT_SCHEME);
            intent.addCategory(Intent.CATEGORY_BROWSABLE);
            intent.setComponent(null);
            startActivity(intent);

        } catch (Exception e) {
            e.printStackTrace();

        }
    }


}

 

2017-05-02 09:32:08 qq_33972942 阅读数 3474


1、浏览器内核:

主流浏览器内核介绍(前端开发值得了解的浏览器内核历史)

浏览器内核历史介绍:

在android 4.4之前,浏览器用的还是webkit

在android 4.4之后,google就抛弃了webkit,只是保留了webkit中关于排版渲染方面的代码,同时还把Browser应用给去掉了引擎方面已经换成了一个叫​C​h​ro​m​i​u​m​的内核。

Blink 其实是 WebKit 的分支,如同 WebKit 是 KHTML 的分支

Trident(IE内核)

Gecko(Firefox 内核)

WebKit 前身是 KDE 小组的 KHTML 引擎,可以说 WebKit 是 KHTML 的一个开源的分支。当年苹果在比较了 Gecko 和 KHTML 后,选择了后者来做引擎开发,是因为 KHTML 拥有清晰的源码结构和极快的渲染速度。

2、腾讯x5浏览器内核:

X5是腾讯QQ浏览器产品部推出的,面向第三方开放X5内核引擎的产品服务。从目前来看,微信、手Q、空间和QQ浏览器都已经内置了X5内核,基本上所有的手机用户手机里都有QQ浏览器X5内核了。所以第三方只要通过很小的sdk就可以调用到这些app里面的X5。

TBS(腾讯浏览服务)

官方接入文档

运行条件:

1) 手机ROM版本高于或等于2.2版本

2) 手机RAM大于500M,该RAM值通过手机 /proc/meminfo 文件的MemTotal动态获取

注:如果不满足上述条件,SDK会自动切换到系统WebView,SDK使用者不用关心该切换过程。

接入x5,有两种:

1、Android SDK(Share Only)

  这种接入方式,减少包的大小,但是需要手机本身安装了微信(6.1版本以上)、手Q、空间。

2、Android SDK(With download)

     这种接入方式,需要复制“Android SDK(With download)”的jar包到工程的libs目录下。

在Android工程的AndroidManifest.xml中申明腾讯X5服务所需的权限:

复制代码
1     <!-- 申请腾讯X5所需权限 -->  
2     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
3     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />  
4     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />  
5     <uses-permission android:name="android.permission.INTERNET" />  
6     <uses-permission android:name="android.permission.READ_PHONE_STATE" />  
复制代码

辨别是否使用x5webview的方法:

显示网页文字时,可通过长按选择文字的标识判断,如下水滴状选择效果是x5webview 的标志

基于腾讯X5内核的混合APP开发模式

没有更多推荐了,返回首页