I'm trying to launch a splash screen for a few seconds and then close it and launch the second screen.
For some reason, the code executes the "sleep" before showing the splash page and the splash page appears only for a fraction of a second and the second screen appears immediately. In other words when I click on the app icon, it waits for 2 seconds, then shows and immediately hides splash and jumps to HomeScreen.
I've tried many different combinations including invokeAndWait(), call backs and threads inside the Splash class but to no avail.
I've gone through many posts on SO as well.
Please note that I do not want the splash page to open the next screen; the launcher of the splash page (AppStart) should launch the next screen.
Please suggest a solution.
Code:
public class AppStart extends UiApplication
{
public static void main(String[] args) {
AppStart app = new AppStart();
app.enterEventDispatcher();
}
public AppStart() {
final Splash splashscreen = new Splash();
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().pushScreen(splashscreen);
}
});
Thread waitthread = new Thread()
{
public void run()
{
try {
sleep(2000);
} catch (InterruptedException e) {
}
finally
{
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().popScreen(splashscreen);
}
});
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().pushScreen(new HomeScreen());
}
});
}
}
};
waitthread.run();
}
}
Splash
public class Splash extends MainScreen {
public Splash()
{
Bitmap bgImg = Bitmap.getBitmapResource("480x320-SplashScreen.png");
Background bg = BackgroundFactory.createBitmapBackground(bgImg);
getMainManager().setBackground(bg);
}
}
waitthread.run();
That is the problem. You are not starting a new thread, but hogging the main thread instead by callyng a method that sleeps it. Replace that line with this one:
waitthread.start();
And it should work.
Related
Initial Issue
I need to register ProcessLifecycleOwner as described here Xamarin.Android Architecture Components in my Application.OnCreate method.
But it had resulted in the error with 6.2.2 version of MvvmCross:
MvvmCross.Exceptions.MvxIoCResolveException: Failed to resolve type MvvmCross.ViewModels.IMvxAppStart occurred
or just stuck on the Splash Screen with 6.2.3.
Fix
Those problems were fixed by advice from Xamarin.Android mvvmcross app crashes when launching with intent filter.
[Application]
public class App : MvxAndroidApplication<Setup, Core.App>
{
public App(IntPtr reference, JniHandleOwnership transfer) :
base(reference, transfer) { }
public override void OnCreate()
{
MvxAndroidSetupSingleton
.EnsureSingletonAvailable(ApplicationContext)
.EnsureInitialized();
base.OnCreate();
}
}
Current Issue
However Splash Screen dissapeared too, only blue background from default theme was left.
A workaround I've found:
public override void OnCreate()
{
Task.Run(() => MvxAndroidSetupSingleton
.EnsureSingletonAvailable(ApplicationContext)
.EnsureInitialized());
base.OnCreate();
}
But due to parallelism it is not reliable, sometimes works, sometimes crashes.
Question
How Splash Screen can be restored?
Your approach is most likely blocking on the UI thread which us causing the UI to block during the time that the expected splash screen is suppose to show.
Try using an async event handler to allow for a non blocking UI call
[Application]
public class App : MvxAndroidApplication<Setup, Core.App> {
public App(IntPtr reference, JniHandleOwnership transfer) :
base(reference, transfer) {
EnsureInitialized = onEnsureInitialized; //Subscribe to event
}
private event EventHandler EnsureInitialized = delegate { };
private async void onEnsureInitialized(object sender, EventArgs args) {
await Task.Run(() => MvxAndroidSetupSingleton.EnsureSingletonAvailable(ApplicationContext)
.EnsureInitialized());
}
public override void OnCreate() {
EnsureInitialized(this, EventArgs.Empty); //Raise event
base.OnCreate();
}
}
When my app is running in background and I click its icon, it comes from background to foreground. Which function is triggered at first? I searched, after coming from background it triggers the public void activate() in the class which is extended by Application.
Now I have a GUI class, lets say Login.java, which extends UiApplication. What should I write in this class to see that Application has come from background to foreground?
And when going to Background I use this code
public boolean onClose() {
UiApplication.getUiApplication().invokeAndWait(new Runnable() {
public void run() {
MyScreen.setBackgroundFlag("true");
UiApplication.getUiApplication().requestBackground();
};
});
//Application.getApplication().requestForeground();
//System.exit(0);
return true;
}
I push the pop screen using following code, what pop screen not displays.
Please tell me what I missed.?
LabelField statusMsg = new LabelField("Hello");
PopupScreen statusScreen = new PopupScreen((fieldHFM));
UiApplication app = UiApplication.getUiApplication();
app.pushScreen(statusScreen);
Try
to do in following way
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().pushScreen(statusScreen);
}
});
I need to display a splash screen when I app instantiate, I wrote a class for splashScreen based on blackberry develpers knowlwdebase (link).
And its invoked from my following class.My problem is the splashscreen appears only after a deley,How can I solve it,If any one have idea Please help me,Thanks
class Test extends MainScreen{
Test(){
UiApplication.getUiApplication().invokeLater(new Runnable()
{
public void run() {
UiApplication app=(UiApplication)getApplication();
Bitmap image = Bitmap.getBitmapResource("splah.png");
ListView listView = new ListView();
new SplashScreen(app, listView );
}
}
Try synchronized (UiApplication.getEventLock()). It is faster than invokeLater.
Test(){
synchronized (UiApplication.getEventLock()) {
UiApplication app=(UiApplication)getApplication();
Bitmap image = Bitmap.getBitmapResource("splah.png");
ListView listView = new ListView();
new SplashScreen(app, listView );
}
}
For my Blackberry application I am using a start up screen with progress bar. I am filling the progress bar using a timer and after the progress bar is complete, I need to navigate to another screen.
I am checking like this, where 'i' is time, increasing from 0 to 100.
timer.cancel();
if(i>=99)
UiApplication.getUiApplication().pushScreen(new TipCalculatorScreen());
This code is not working.
For progress bar I am using code like this:
private GaugeField percentGauge;
percentGauge = new GaugeField(null, 0, 100,50, GaugeField.PERCENT);
timer=new Timer();
timer.scheduleAtFixedRate(new TimerTask(){
int i=0;
public void run() {
percentGauge.setValue(i);
i++;
if(i>=99)
{
timer.cancel();
//for page navigating i am given like this here screen is not navigating getting error
UiApplication.getUiApplication().pushScreen(new nextscreen());
}
}
}, 100,100);
You need to make changes to the UI on the UI thread. The TimerTask is executing on its own thread. Instead of
UiApplication.getUiApplication().pushScreen(new nextscreen());
you should use
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication()..pushScreen(new nextscreen());
}
});
The update to your gauge control probably needs the same treatment.