安卓使用腾讯webview踩坑

参考:
图片拍照封装
https://blog.csdn.net/villa_mou/article/details/78728417
弹窗
http://blog.csdn.net/baidu_25797177/article/details/51952880
项目需求原生功能,于是把之前的h5封装到安卓的webview中,本来以为稍微封装一下就行,,,唉,都是泪

原生webview,上,完犊子,页面整个垮掉,换方案
1.xwalk
提供一个包地址,剩下的自行百度吧,一开始搜的时候感觉是相对最好的解决方案,后来应为ndk原因放弃
implementation ‘org.xwalk:xwalk_core_library:23.53.589.4’
2.腾讯webview
资源可以在官网找到
https://x5.tencent.com/docs/access.html
腾讯的文档真的是一言难尽。。。
开始吧

private WebView webView;
// 加载的地址
private String url = "http://192.168.11.22:5500"
@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);
   try {
   		//隐藏安卓的顶部
       if (getSupportActionBar() != null) {
           getSupportActionBar().hide();
       }
       if (webView != null) {

       } else {
           initView();
       }
   } catch (Exception e) {
       Log.e(TAG, "onCreate:e ", e);
   }

}
private void initView() {
    Log.d(TAG, "initView: ");
    //非wifi情况下,主动下载x5内核
    QbSdk.setDownloadWithoutWifi(true);
    //搜集本地tbs内核信息并上报服务器,服务器返回结果决定使用哪个内核。
    QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {
        @Override
        public void onViewInitFinished(boolean arg0) {
            //x5內核初始化完成的回调,为true表示x5内核加载成功,否则表示x5内核加载失败,会自动切换到系统内核。
        }

        @Override
        public void onCoreInitFinished() {

        }
    };
    //x5内核初始化接口
    QbSdk.initX5Environment(getApplicationContext(), cb);
    webView = findViewById(R.id.wv_task);
//        webView.getSettings().setSupportZoom(true); //支持缩放,默认为true。是下面那个的前提。
    webView.getSettings().setBuiltInZoomControls(false); //设置内置的缩放控件。若为false,则该WebView不可缩放
    webView.getSettings().setDisplayZoomControls(true); //隐藏原生的缩放控件
    webView.getSettings().setBlockNetworkImage(false);//解决图片不显示
    webView.getSettings().setLoadsImagesAutomatically(true); //支持自动加载图片
    webView.getSettings().setDefaultTextEncodingName("utf-8");//设置编码格式
    webView.getSettings().setDomStorageEnabled(true);
    webView.getSettings().setAppCacheMaxSize(1024 * 1024 * 8);
    String appCachePath = getApplicationContext().getCacheDir().getAbsolutePath();
    webView.getSettings().setAppCachePath(appCachePath);
    webView.getSettings().setAllowFileAccess(true);    // 可以读取文件缓存
    webView.getSettings().setAppCacheEnabled(true);    //开启H5(APPCache)缓存功能
    webView.getSettings().setJavaScriptEnabled(true);
    webView.getSettings().setMixedContentMode(WebSettings.LOAD_NORMAL);     // https下访问http资源
    // JS的扩展,暂时不介绍,可自行百度
    webView.addJavascriptInterface(new JsBridge(MainActivity.this), "android");
    webView.loadUrl(url);
    Log.d(TAG, "监控界面加载的url为: " + url);
    webView.setWebViewClient(new WebViewClient() {
        @Override
        public boolean shouldOverrideUrlLoading(WebView webView, String s) {
//                webView.loadUrl(url);
            return super.shouldOverrideUrlLoading(webView, s);
        }

        @Override
        public void onPageFinished(WebView webView, String s) {
            super.onPageFinished(webView, s);
        }

        @Override
        public void onReceivedSslError(WebView webView, SslErrorHandler sslErrorHandler, SslError sslError) {
            sslErrorHandler.proceed();// 接受所有网站的证书
//                super.onReceivedSslError(webView, sslErrorHandler, sslError);
        }
    });
    paxWebChromeClient = new PaxWebChromeClient(this);
    //监听网页的加载
    webView.setWebChromeClient(paxWebChromeClient);
}

引入的webview的包都是腾讯的

import com.tencent.smtt.sdk.QbSdk;
import com.tencent.smtt.sdk.ValueCallback;
import com.tencent.smtt.sdk.WebChromeClient;
import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;
import com.tencent.smtt.sdk.WebViewClient;

manifest权限,可能有多的,懒得删了

<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECORD_VIDEO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <!-- 用于进行网络定位 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- 用于访问GPS定位 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- 用于获取运营商信息,用于支持提供运营商信息相关的接口 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- 用于获取wifi的获取权限,wifi信息会用来进行网络定位 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!-- 用于访问网络,网络定位需要上网 -->
<uses-permission android:name="android.permission.INTERNET" /> <!-- 用于读取手机当前的状态 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <!-- 用于写入缓存数据到扩展存储卡 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- 用于申请调用A-GPS模块 -->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />

布局用的webView也是腾讯的

<com.tencent.smtt.sdk.WebView
    android:id="@+id/wv_task"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:visibility="visible"
    app:layout_constraintBottom_toTopOf="parent"
    app:layout_constraintEnd_toStartOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

监听返回啥的后面再说吧,先第一个坑,webview的文件上传
webview的选择图片事件会触发webview的
webView.setWebChromeClient
还有,选择图片和拍照需要两个不同的方法,这里用弹窗实现
implementation ‘com.guoqi.widget:actionsheet:1.0’

public class PaxWebChromeClient extends WebChromeClient implements ActionSheet.OnActionSheetSelected, DialogInterface.OnCancelListener {
    private static int CHOOSE_REQUEST_CODE;
    private Activity mActivity;
    private ValueCallback<Uri> uploadFile;//定义接受返回值
    private ValueCallback<Uri[]> uploadFiles;

//    拍照 or 相册
    private Boolean Flag = true;

    public PaxWebChromeClient(@NonNull MainActivity activity) {
        this.CHOOSE_REQUEST_CODE = activity.getFilechooserResultcode();
        this.mActivity = activity;
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    @Override
    public void onPermissionRequest(PermissionRequest request) {
        //                super.onPermissionRequest(request);//必须要注视掉
        request.grant(request.getResources());
    }

    // For Android 3.0+
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
        this.uploadFile = uploadFile;
        if (Flag) {
            takePhoto();
        } else {
            openFileChooseProcess();
        }
    }

    // For Android < 3.0
    public void openFileChooser(ValueCallback<Uri> uploadMsgs) {
        this.uploadFile = uploadFile;
        if (Flag) {
            takePhoto();
        } else {
            openFileChooseProcess();
        }
    }

    // For Android  > 4.1.1
//    @Override
    public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
        this.uploadFile = uploadFile;
        if (Flag) {
            takePhoto();
        } else {
            openFileChooseProcess();
        }
    }

    // For Android  >= 5.0
    @Override
    public boolean onShowFileChooser(WebView webView,
                                     ValueCallback<Uri[]> filePathCallback,
                                     WebChromeClient.FileChooserParams fileChooserParams) {
                    this.uploadFiles = filePathCallback;
        ActionSheet.showSheet(mActivity,this,this);
        return true;
    }


    private void openFileChooseProcess() {
        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
        i.addCategory(Intent.CATEGORY_OPENABLE);
        i.setType("image/*");
        mActivity.startActivityForResult(Intent.createChooser(i, "Choose"), CHOOSE_REQUEST_CODE);
    }

    private Uri imageUri;
    
    /**
     * 拍照
     */
    private void takePhoto() {
        File fileUri = new File(Environment.getExternalStorageDirectory().getPath() + "/" + SystemClock.currentThreadTimeMillis() + ".jpg");
        imageUri = Uri.fromFile(fileUri);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            String auth = mActivity.getPackageName() + ".fileprovider";
            imageUri = FileProvider.getUriForFile(mActivity, auth , fileUri);//通过FileProvider创建一个content类型的Uri
        }
        PhotoUtils.takePicture(mActivity, imageUri, CHOOSE_REQUEST_CODE);
    }


    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        Log.d("myTag:requestCode===",requestCode+"====");
        if (resultCode == Activity.RESULT_OK) {
            if (requestCode == CHOOSE_REQUEST_CODE) {
                if (null != uploadFile) {
                    Uri result = data == null || resultCode != Activity.RESULT_OK ? null
                            : data.getData();
                    uploadFile.onReceiveValue(result);
                    uploadFile = null;
                }
                if (null != uploadFiles) {
                    Uri result = data == null || resultCode != Activity.RESULT_OK ? null
                            : data.getData();
                    if(result == null){
                        // 一些机型无法从getData中获取uri,则需手动指定拍照后存储照片的Uri
                        uploadFiles.onReceiveValue(new Uri[]{imageUri});
                    }else {
                        uploadFiles.onReceiveValue(new Uri[]{result});
                    }
                    uploadFiles = null;
                }
            }
        } else if (resultCode == Activity.RESULT_CANCELED) {
            if (null != uploadFile) {
                uploadFile.onReceiveValue(null);
                uploadFile = null;
            }
            if (null != uploadFiles) {
                uploadFiles.onReceiveValue(null);
                uploadFiles = null;
            }
        }
    }

    @Override
    public void onClick(int whichButton) {
        switch (whichButton) {
            case ActionSheet.CHOOSE_PICTURE:
                //相册
                openFileChooseProcess();
                break;
            case ActionSheet.TAKE_PICTURE:
                //拍照
                takePhoto();
                break;
            case ActionSheet.CANCEL:
                //取消按钮取消
                Log.d("myTag", "ActionSheet.CANCEL: ");
                uploadFiles.onReceiveValue(null);
                break;
        }
    }

//    点击其他地方取消
    @Override
    public void onCancel(DialogInterface dialogInterface) {
        uploadFiles.onReceiveValue(null);
        Log.d("myTag", "onCancel: ");
    }
}

代码太多就不一一贴了,PhotoUtil在第一个链接里面有
先到这,待续

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
腾讯X5内核是一款支持多进程、支持硬件加速、支持自定义内核扩展的WebView内核。在Android开发中,使用腾讯X5内核可以提高WebView的性能和稳定性,下面是一些优化和实践总结: 1. 引入腾讯X5内核 引入腾讯X5内核需要在项目中添加相应的依赖库,然后在代码中进行初始化和使用。具体步骤可以参考腾讯官方文档。 2. 启用硬件加速 在使用腾讯X5内核时,可以启用硬件加速来提高WebView的渲染速度。具体可以通过设置WebView的LayerType属性来实现,例如: ``` webView.setLayerType(View.LAYER_TYPE_HARDWARE, null); ``` 3. 使用预加载 预加载可以在用户点击链接之前就开始加载下一页的内容,以提高用户体验和减少页面加载时间。腾讯X5内核提供了预加载功能,可以通过设置WebView的预加载模式来实现,例如: ``` webView.getX5WebViewExtension().setPageCacheCapacity(5); // 设置最大缓存页面数为5 webView.getX5WebViewExtension().setPreload(true); // 开启预加载模式 ``` 4. 优化JSBridge通信 JSBridge是一种用于WebView和Native代码之间通信的技术,但是在使用过程中容易出现性能问题。为了优化JSBridge通信,可以使用腾讯X5内核提供的基于V8引擎的JSBridge,它可以提高通信效率和稳定性。 5. 避免WebView内存泄漏 在使用WebView时,需要注意避免内存泄漏问题。具体可以通过以下方式来避免: - 及时释放WebView对象 - 使用静态内部类或弱引用来持有WebView对象 - 在Activity的onDestroy()方法中调用WebView的destroy()方法 总之,腾讯X5内核是一款非常强大的WebView内核,可以帮助我们优化WebView的性能和稳定性。在使用中,需要注意以上几点优化和实践。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值