当腾讯X5启动失败时,很有可能是你WebView 的创建在X5初始化完成之前

最近一个小伙伴用腾讯X5时总是出错,所以有了这篇文章,就像标题写的,你的WebView的使用及创建,一定要在腾讯X5初始化完成之后。


说下他的场景,MainActivity直接就打开X5WebView 去加载网页。导致使用的是原生WebView。


http://res.imtt.qq.com/TES/x5%20api%20-simple_1493283262924.pdf


但是,很重要一点,如果我们按照官方Demo的写法,Application中去初始化X5内核的时候,初始化的过程是在子线程中进行的,回调是主线程回调的


源码简单分析一波



首先我们想一下,回调onViewInitFinished()函数肯定是在 initX5Environment() 这个函数 内被回调的,那么如果initX5Environment()  内所有函数均是主线程中运行,那么就不会出现 官方文档说的 我们使用的 WebView要在回调之后使用了。


所以在initX5Environment()这个函数内部一定有子线程。


先看 h 类


函数名称 onInstallFinish  函数名就表达了一切,接着看 preInit


有 MainLooper()所以 f 应该就是 handler,看内部回调,没问题,我们接着看 g 类


g 是个线程,那么我们就可以得出结论,开启工作线程,工作线程使用MainLooper,初始化完成就使用 handler 发送消息,进行回调。


这里关于使用MainLooper多说一句

举个例子

如果我在子线程创建了 handler,并重写了HandlerMessage,然后Hanlder使用的是MainLooper,这时候我在子线程使用handler发送了一个消息,那么这个消息处理是主线程处理还是子线程处理????

当然是主线程

这个就涉及handler.sendMessage 和 Looper.loop 函数


步骤:

子线程handler:workHandler  

子线程发送的Message:workMsg


1、workHandler.sendMessage(workMsg)  ,经过一步一步,最终放到了 MainLooper内的MessageQueue中

2、由于主线程开启了Looper.loop,这时候Looper 取出 workMsg,记住这一点,是主线程中的函数 Looper.loop取出了workMsg。

3、那取出的这个 workMsg给谁去处理呢??

4、workMsg中有个属性  workMsg.target,这个 workMsg.target 就是 workHandler

5、然后回调 workHandler 的 callBack 或者 handleMessage


最后附上一个案例

package com.chinabim.myapplication;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
/**
 * @author 高延荣
 * @date 2018/3/1 10:47
 * 描述:  
 */
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainLooper测试";
    private Handler handler1;
    private Handler handler2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                handler1 = new Handler(Looper.getMainLooper()) {
                    @Override
                    public void handleMessage(Message msg) {
                        Log.i(TAG, Thread.currentThread().getName());
                    }
                };
            }
        }, "我是第一个子线程");


        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                handler2 = new Handler(Looper.getMainLooper()) {
                    @Override
                    public void handleMessage(Message msg) {
                        Log.i(TAG, Thread.currentThread().getName());
                    }
                };
            }
        }, "我是第二个子线程");


        thread1.start();
        thread2.start();

        try {
            Thread.sleep(3 * 1000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        handler1.sendEmptyMessage(1);
        handler2.sendEmptyMessage(2);


    }
}

谢谢大家的观看




猜你喜欢

转载自blog.csdn.net/qq_26030147/article/details/79413303