在 Android 的视频启动画面期间预加载 WebView
Pre-load WebView during the Video Splash Screen in Android
我在 Android 应用程序中工作,我想在 webView 加载网页时预加载启动画面 但是 我有一个本地 .mp4 视频而不是一张照片。
所以一旦用户点击应用程序,.mp4 将开始播放(4 秒)。在那 4 秒内,webView 应该 pre-load 网页 SO 当视频完成时显示我的网页(如果网页已经加载), 否则在启动画面中等待,直到网页准备就绪,然后加载它。
这是我的 MainActivity:
public class MainActivity extends AppCompatActivity {
private WebView webView;
public static final Object SPLASH_LOCK = new Object();
@Override
protected void onCreate(Bundle savedInstanceState) {
String myURL = "https://www.testpage.com";
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setAllowContentAccess(true);
/** tell the webView to enable javascript execution */
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setDatabaseEnabled(true);
webSettings.getAllowFileAccessFromFileURLs();
webSettings.getAllowUniversalAccessFromFileURLs();
/** Load the HTML page */
webView.loadUrl(myURL);
/** Call the JavaScriptInterface within the WebView */
webView.addJavascriptInterface(this, "jsinterface");
startActivity(new Intent(this, AnimationScreenActivity.class));
/** Enable Javascript in WebView
/ callback for browser events */
webView.setWebViewClient(new WebViewClient(){
@Override
public void onPageFinished (WebView webView, String url) {
synchronized (SPLASH_LOCK) {
SPLASH_LOCK.notifyAll();
}
}
});
}
}
这是 AnimationScreenActivity:
public class AnimationScreenActivity extends AppCompatActivity{
private static String TAG = AnimationScreenActivity.class.getName();
private static long MAX_SPLASH_TIME = 10000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.animation_screen);
try {
VideoView videoHolder = (VideoView) findViewById(R.id.videoView1);
Uri video = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.myvideo);
videoHolder.setVideoURI(video);
videoHolder.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
jump();
}
});
videoHolder.start();
} catch (Exception ex) { jump(); }
}
private void jump() {
new Thread() {
@Override
public void run() {
synchronized (MainActivity.SPLASH_LOCK) {
// wait for notify or time-out
try {
MainActivity.SPLASH_LOCK.wait(MAX_SPLASH_TIME);
} catch (InterruptedException ignored) {}
}
finish();
}
}.start();
}
}
这里是 activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="test.test_android.MainActivity">
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
这里是 animation_screen_activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/animation_screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="test.test.AnimationScreenActivity">
<VideoView
android:id="@+id/videoView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:layout_alignParentRight="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true" />
</RelativeLayout>
最后 Manifest.xml 我将 MainActivity 设置为 LAUNCHER:
<activity android:name=".MainActivity"
android:theme="@style/FullScreenTheme"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".AnimationScreenActivity"
android:theme="@style/FullScreenTheme"
android:screenOrientation="portrait"/>
所以我现在所知道的是,一旦用户启动应用程序,.mp4 就会启动,当 .mp4 完成时 THEN 它会在 AnimationScreenActivity 中等待 10 秒,并且然后 加载网页。
任何帮助将不胜感激!
我的建议是避免进行 2 项活动,我怀疑这是你的问题之一。
只有一个 Activity,其中 VideoView
和 WebView
都在 RelativeLayout 中,因此 VideoView 位于 WebView 之上。
当 WebView 准备就绪后,只需 VideoView.setVisibity(View.GONE)
您可以拥有一个包含 2 个 Activity 的内容的单个 Activity,方法是使用 ViewSwitcher(或 ViewAnimator)在布局之间切换。
这也将消除对 SPLASH_LOCK 对象的需要。
在加载时,将 ViewSwitcher(或 ViewAnimator)切换到视频布局,当您完成页面加载后,将其切换到 WebView 布局。
我编写了一个简单的代码,可以更轻松地在视图之间切换。如果你愿意,你可以使用它:
public static void setViewToSwitchTo(@NonNull final ViewAnimator viewAnimator, @NonNull final View viewToSwitchTo) {
if (viewAnimator == null)
return;
if (viewAnimator.getCurrentView() == viewToSwitchTo)
return;
for (int i = 0; i < viewAnimator.getChildCount(); ++i)
if (viewAnimator.getChildAt(i) == viewToSwitchTo) {
viewAnimator.setDisplayedChild(i);
break;
}
}
public static void setViewToSwitchTo(@NonNull final ViewAnimator viewAnimator, @IdRes final int viewIdToSwitchTo) {
if (viewAnimator == null)
return;
if (viewAnimator.getCurrentView().getId() == viewIdToSwitchTo)
return;
for (int i = 0; i < viewAnimator.getChildCount(); ++i)
if (viewAnimator.getChildAt(i).getId() == viewIdToSwitchTo) {
if (viewAnimator.getDisplayedChild() == i)
return;
viewAnimator.setDisplayedChild(i);
return;
}
}
用法:
setViewToSwitchTo(viewSwitcher, R.id.webViewLayout);
或:
setViewToSwitchTo(viewSwitcher, webViewLayout);
您甚至可以使用 "inAnimation" 和 "outAnimation" 属性在视图之间切换时制作动画。
而且,如果代码变得太大,您可以使用片段而不是视图。一个用于 WebView,另一个用于视频。
关于onPageFinished被多次调用,你需要检查哪一个是你认为真正完成的。由于每个网站都不同,并且可以有多个框架,因此您必须添加此逻辑。如果你愿意,你可以监控onPageStarted,如下所示:
顺便说一句,如果您在清单中更改方向,请注意,由于您有 WebView,因此您将不得不考虑如何处理方向更改,因为它不能很好地恢复其状态。
编辑:
这是布局文件:
<ViewSwitcher xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/viewSwitcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="test.test_android.MainActivity">
<VideoView
android:id="@+id/videoView1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
</ViewSwitcher>
在 onCreate 中,使用您的两个活动的代码,并将其添加到视频中:
setViewToSwitchTo(viewSwitcher, R.id.videoView1);
这将转到 webView(当它完成加载时,在你的情况下):
setViewToSwitchTo(viewSwitcher, R.id.webView);
在@android 开发人员(非常感谢!)和 Whosebug 帖子的大量帮助之后,我将这两项活动 MainActivity
、AnimationScreenActivity
合并为一个 activity (MainActivity).
代码如下:
public class MainActivity extends AppCompatActivity {
private String myURL = "https://www.testpage.com";
VideoView videoView;
ViewSwitcher viewSwitcher;
private WebView webView;
private boolean hasFinishedLoadingPage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
viewSwitcher = (ViewSwitcher) findViewById(R.id.viewSwitcher);
final VideoView videoView = (VideoView) findViewById(R.id.videoView1);
Uri video = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.myvideo);
videoView.setVideoURI(video);
videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
if (hasFinishedLoadingPage)
setViewToSwitchTo(viewSwitcher, webView);
// else webView.reload();
setViewToSwitchTo(viewSwitcher, webView);
}
});
videoView.start();
} catch (Exception ex) {
}
webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setAllowContentAccess(true);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setDatabaseEnabled(true);
webSettings.getAllowFileAccessFromFileURLs();
webSettings.getAllowUniversalAccessFromFileURLs();
webView.setWebViewClient(new WebViewClient() {
boolean isRedirected;
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
if (!isRedirected) {
setViewToSwitchTo(viewSwitcher, videoView);
}
isRedirected = true;
}
@Override
public void onPageFinished(WebView webView, String url) {
super.onPageFinished(webView, url);
hasFinishedLoadingPage = true;
}
});
/** Callback for web events */
webView.setWebChromeClient(new WebChromeClient() {
});
webView.loadUrl(myURL);
}
public static void setViewToSwitchTo(@NonNull final ViewAnimator viewAnimator, @NonNull final View viewToSwitchTo) {
if (viewAnimator == null)
return;
if (viewAnimator.getCurrentView() == viewToSwitchTo)
return;
for (int i = 0; i < viewAnimator.getChildCount(); ++i)
if (viewAnimator.getChildAt(i) == viewToSwitchTo) {
viewAnimator.setDisplayedChild(i);
break;
}
}
}
我在 Android 应用程序中工作,我想在 webView 加载网页时预加载启动画面 但是 我有一个本地 .mp4 视频而不是一张照片。
所以一旦用户点击应用程序,.mp4 将开始播放(4 秒)。在那 4 秒内,webView 应该 pre-load 网页 SO 当视频完成时显示我的网页(如果网页已经加载), 否则在启动画面中等待,直到网页准备就绪,然后加载它。
这是我的 MainActivity:
public class MainActivity extends AppCompatActivity {
private WebView webView;
public static final Object SPLASH_LOCK = new Object();
@Override
protected void onCreate(Bundle savedInstanceState) {
String myURL = "https://www.testpage.com";
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setAllowContentAccess(true);
/** tell the webView to enable javascript execution */
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setDatabaseEnabled(true);
webSettings.getAllowFileAccessFromFileURLs();
webSettings.getAllowUniversalAccessFromFileURLs();
/** Load the HTML page */
webView.loadUrl(myURL);
/** Call the JavaScriptInterface within the WebView */
webView.addJavascriptInterface(this, "jsinterface");
startActivity(new Intent(this, AnimationScreenActivity.class));
/** Enable Javascript in WebView
/ callback for browser events */
webView.setWebViewClient(new WebViewClient(){
@Override
public void onPageFinished (WebView webView, String url) {
synchronized (SPLASH_LOCK) {
SPLASH_LOCK.notifyAll();
}
}
});
}
}
这是 AnimationScreenActivity:
public class AnimationScreenActivity extends AppCompatActivity{
private static String TAG = AnimationScreenActivity.class.getName();
private static long MAX_SPLASH_TIME = 10000;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.animation_screen);
try {
VideoView videoHolder = (VideoView) findViewById(R.id.videoView1);
Uri video = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.myvideo);
videoHolder.setVideoURI(video);
videoHolder.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
jump();
}
});
videoHolder.start();
} catch (Exception ex) { jump(); }
}
private void jump() {
new Thread() {
@Override
public void run() {
synchronized (MainActivity.SPLASH_LOCK) {
// wait for notify or time-out
try {
MainActivity.SPLASH_LOCK.wait(MAX_SPLASH_TIME);
} catch (InterruptedException ignored) {}
}
finish();
}
}.start();
}
}
这里是 activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="test.test_android.MainActivity">
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</RelativeLayout>
这里是 animation_screen_activity.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/animation_screen"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="test.test.AnimationScreenActivity">
<VideoView
android:id="@+id/videoView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:layout_alignParentRight="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentEnd="true"
android:layout_alignParentTop="true"
android:layout_alignParentBottom="true" />
</RelativeLayout>
最后 Manifest.xml 我将 MainActivity 设置为 LAUNCHER:
<activity android:name=".MainActivity"
android:theme="@style/FullScreenTheme"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".AnimationScreenActivity"
android:theme="@style/FullScreenTheme"
android:screenOrientation="portrait"/>
所以我现在所知道的是,一旦用户启动应用程序,.mp4 就会启动,当 .mp4 完成时 THEN 它会在 AnimationScreenActivity 中等待 10 秒,并且然后 加载网页。
任何帮助将不胜感激!
我的建议是避免进行 2 项活动,我怀疑这是你的问题之一。
只有一个 Activity,其中 VideoView
和 WebView
都在 RelativeLayout 中,因此 VideoView 位于 WebView 之上。
当 WebView 准备就绪后,只需 VideoView.setVisibity(View.GONE)
您可以拥有一个包含 2 个 Activity 的内容的单个 Activity,方法是使用 ViewSwitcher(或 ViewAnimator)在布局之间切换。 这也将消除对 SPLASH_LOCK 对象的需要。
在加载时,将 ViewSwitcher(或 ViewAnimator)切换到视频布局,当您完成页面加载后,将其切换到 WebView 布局。
我编写了一个简单的代码,可以更轻松地在视图之间切换。如果你愿意,你可以使用它:
public static void setViewToSwitchTo(@NonNull final ViewAnimator viewAnimator, @NonNull final View viewToSwitchTo) {
if (viewAnimator == null)
return;
if (viewAnimator.getCurrentView() == viewToSwitchTo)
return;
for (int i = 0; i < viewAnimator.getChildCount(); ++i)
if (viewAnimator.getChildAt(i) == viewToSwitchTo) {
viewAnimator.setDisplayedChild(i);
break;
}
}
public static void setViewToSwitchTo(@NonNull final ViewAnimator viewAnimator, @IdRes final int viewIdToSwitchTo) {
if (viewAnimator == null)
return;
if (viewAnimator.getCurrentView().getId() == viewIdToSwitchTo)
return;
for (int i = 0; i < viewAnimator.getChildCount(); ++i)
if (viewAnimator.getChildAt(i).getId() == viewIdToSwitchTo) {
if (viewAnimator.getDisplayedChild() == i)
return;
viewAnimator.setDisplayedChild(i);
return;
}
}
用法:
setViewToSwitchTo(viewSwitcher, R.id.webViewLayout);
或:
setViewToSwitchTo(viewSwitcher, webViewLayout);
您甚至可以使用 "inAnimation" 和 "outAnimation" 属性在视图之间切换时制作动画。
而且,如果代码变得太大,您可以使用片段而不是视图。一个用于 WebView,另一个用于视频。
关于onPageFinished被多次调用,你需要检查哪一个是你认为真正完成的。由于每个网站都不同,并且可以有多个框架,因此您必须添加此逻辑。如果你愿意,你可以监控onPageStarted,如下所示:
顺便说一句,如果您在清单中更改方向,请注意,由于您有 WebView,因此您将不得不考虑如何处理方向更改,因为它不能很好地恢复其状态。
编辑:
这是布局文件:
<ViewSwitcher xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/viewSwitcher"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="test.test_android.MainActivity">
<VideoView
android:id="@+id/videoView1"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen" />
</ViewSwitcher>
在 onCreate 中,使用您的两个活动的代码,并将其添加到视频中:
setViewToSwitchTo(viewSwitcher, R.id.videoView1);
这将转到 webView(当它完成加载时,在你的情况下):
setViewToSwitchTo(viewSwitcher, R.id.webView);
在@android 开发人员(非常感谢!)和 Whosebug 帖子的大量帮助之后,我将这两项活动 MainActivity
、AnimationScreenActivity
合并为一个 activity (MainActivity).
代码如下:
public class MainActivity extends AppCompatActivity {
private String myURL = "https://www.testpage.com";
VideoView videoView;
ViewSwitcher viewSwitcher;
private WebView webView;
private boolean hasFinishedLoadingPage;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
viewSwitcher = (ViewSwitcher) findViewById(R.id.viewSwitcher);
final VideoView videoView = (VideoView) findViewById(R.id.videoView1);
Uri video = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.myvideo);
videoView.setVideoURI(video);
videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
if (hasFinishedLoadingPage)
setViewToSwitchTo(viewSwitcher, webView);
// else webView.reload();
setViewToSwitchTo(viewSwitcher, webView);
}
});
videoView.start();
} catch (Exception ex) {
}
webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setAllowContentAccess(true);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setDatabaseEnabled(true);
webSettings.getAllowFileAccessFromFileURLs();
webSettings.getAllowUniversalAccessFromFileURLs();
webView.setWebViewClient(new WebViewClient() {
boolean isRedirected;
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return false;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
if (!isRedirected) {
setViewToSwitchTo(viewSwitcher, videoView);
}
isRedirected = true;
}
@Override
public void onPageFinished(WebView webView, String url) {
super.onPageFinished(webView, url);
hasFinishedLoadingPage = true;
}
});
/** Callback for web events */
webView.setWebChromeClient(new WebChromeClient() {
});
webView.loadUrl(myURL);
}
public static void setViewToSwitchTo(@NonNull final ViewAnimator viewAnimator, @NonNull final View viewToSwitchTo) {
if (viewAnimator == null)
return;
if (viewAnimator.getCurrentView() == viewToSwitchTo)
return;
for (int i = 0; i < viewAnimator.getChildCount(); ++i)
if (viewAnimator.getChildAt(i) == viewToSwitchTo) {
viewAnimator.setDisplayedChild(i);
break;
}
}
}