Chrome自定义标签会在浏览时预加载网页吗?

时间:2016-05-24 14:34:50

标签: java android chrome-custom-tabs

我正在测试Chrome自定义标签。它应该预加载用户可能在后台单击的网页。这通过调用

来实现
session.mayLaunchUrl(uri, null, null); 

当MainActivity处于活动状态时,网页会预先加载,并且在启动URL时,网页会按预期快速加载。 但是,我想在用户时自动为其他网页提供服务(因此活动在后台)。然后,预加载网页似乎不再加快加载过程,即使新服务的网页正在加载,这种情况也会缓慢发生。

我写了一个小应用程序来演示这种行为。手动预加载和启动URL工作得很好(因为活动是活动的,我猜),在循环中自动提供新网页的速度很慢(因为活动未激活且mayLaunchUrl方法无法按预期工作)。

在用户浏览时是否可以使用预加载机制?如果是,怎么做?

我添加了MainActivity代码,如下例所示:

public class MainActivity  extends AppCompatActivity {


private CustomTabsSession mCustomTabsSession;
private CustomTabsClient mClient;
private CustomTabsServiceConnection mConnection;

private EditText urlET;
private String TAG = "MainActivity";
private ArrayList<String> urlList;
private Thread cycleThread;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Log.v("MainActivity", "onCreate");

    urlList = new ArrayList<>();
    urlList.add("http://www.google.com");
    urlList.add("https://github.com");
    urlList.add("http://stackoverflow.com");
    urlList.add("http://www.heise.de");

    // pre launch the chrome browser, bind services etc
    warmup();

    urlET = (EditText) findViewById(R.id.urlID);

    // pre load a webpage manually 
    Button prepareBt = (Button) findViewById(R.id.prepareBt);
    assert prepareBt != null;
    prepareBt.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            mayLaunch(null);
        }
    });

    //launch webpage manually
    Button launchBt = (Button) findViewById(R.id.launchBt);
    assert launchBt != null;
    launchBt.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            launch(null);
        }
    });

    //start a loop that serves webpages every 10 seconds
    Button cycleBt = (Button) findViewById(R.id.cycleBt);
    assert cycleBt != null;
    cycleBt.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(cycleThread !=null)
                cycleThread.interrupt();

            cycleThread = new Thread(cycle);
            cycleThread.start();
        }
    });

}
private Runnable cycle = new Runnable() {
    @Override
    public void run() {
        int i = 0;
        mayLaunch(Uri.parse(urlList.get(i)));
        try {
            Thread.sleep(5000);

            while (true){
                try {
                    Log.d(TAG, "launch: "+urlList.get(i));
                    launch(Uri.parse(urlList.get(i)));
                    i++;
                    if(i>=urlList.size())
                        i=0;
                    Thread.sleep(5000);
                    Log.d(TAG, "prepare: "+urlList.get(i));
                    mayLaunch(Uri.parse(urlList.get(i)));
                    Thread.sleep(5000);

                } catch (InterruptedException e) {
                   e.printStackTrace();
                    break;
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
};


private void mayLaunch(Uri uri){
    if(uri ==null)
        uri =  Uri.parse(urlET.getText().toString());
    CustomTabsSession session = getSession();
    session.mayLaunchUrl(uri, null, null);
}
private void launch(Uri uri){
    if(uri ==null)
        uri =  Uri.parse(urlET.getText().toString());
    CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder(getSession())

            .setToolbarColor(ContextCompat.getColor(this, R.color.colorPrimaryDark))
            .setShowTitle(true)
            .setStartAnimations(this, android.R.anim.slide_in_left, android.R.anim.slide_out_right)
            .setExitAnimations(this, android.R.anim.slide_in_left, android.R.anim.slide_out_right)
            .build();

    customTabsIntent.intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
    customTabsIntent.launchUrl(this,uri);

}

public CustomTabsSession getSession() {
    if (mClient == null) {
        mCustomTabsSession = null;
    } else if (mCustomTabsSession == null) {
        mCustomTabsSession = mClient.newSession(null);
        Log.d(TAG, "getSession: created new session");
    }
    return mCustomTabsSession;
}

private void warmup(){
    if (mClient != null) return;
    String packageName = "com.android.chrome";
    if (packageName == null) return;

    mConnection = new CustomTabsServiceConnection() {
        @Override
        public void onCustomTabsServiceConnected(ComponentName componentName, CustomTabsClient customTabsClient) {
            mClient = customTabsClient;
            mClient.warmup(0L);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mClient = null;
            mCustomTabsSession = null;
        }
    };
    CustomTabsClient.bindCustomTabsService(this, packageName, mConnection);
}


private void coolDown(){
    if (mConnection == null) return;
    unbindService(mConnection);
    mClient = null;
    mCustomTabsSession = null;
    mConnection = null;
}

public void onDestroy() {
    Log.v("MainActivity", "onDestroy");
    super.onDestroy();
    coolDown();
}
@Override
public void onBackPressed(){
}

}

谢谢!

1 个答案:

答案 0 :(得分:4)

CustomTabs忽略从后台发送的mayLaunchUrl()。这有两个原因:

  1. 避免浪费带宽的简单措施(很容易检查来自同一会话的自定义标签不是前景,只是没有这样做)

  2. 通过mayLaunchUrl()加载的网页目前不会保留Window.sessionStorage(),这对于App -> CustomTab转换不是问题,但是对于在单个CustomTab中导航,这可能会破坏用户的假设导航模式如:

  3.   

    SiteA - &gt; SiteB - &gt;站点A

    (对SiteA的第二次访问看不到会话中的内容)。教mayLaunchUrl()选择正确的sessionStorage()很复杂,但目前还没有计划。