我正在测试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(){
}
}
谢谢!
答案 0 :(得分:4)
CustomTabs忽略从后台发送的mayLaunchUrl()
。这有两个原因:
避免浪费带宽的简单措施(很容易检查来自同一会话的自定义标签不是前景,只是没有这样做)
通过mayLaunchUrl()
加载的网页目前不会保留Window.sessionStorage()
,这对于App -> CustomTab
转换不是问题,但是对于在单个CustomTab中导航,这可能会破坏用户的假设导航模式如:
SiteA - &gt; SiteB - &gt;站点A
(对SiteA
的第二次访问看不到会话中的内容)。教mayLaunchUrl()
选择正确的sessionStorage()
很复杂,但目前还没有计划。