I am trying to create a splash screen that should show a rotating image while the next activity is being loaded.
Therefore I have two activities. The problem is that the rotation does not start, unless I add Thread.sleep before the Intent is created.
This is the first activity, where the animation should run while the second one loads.
import com.silencedut.taskscheduler.Task;
import com.silencedut.taskscheduler.TaskScheduler;
public class LaunchActivity extends AppCompatActivity {
private Task<Intent> loader;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_launcher);
loader = new LoadingTask();
TaskScheduler.execute(loader);
}
#Override
protected void onDestroy() {
super.onDestroy();
TaskScheduler.cancelTask(loader);
}
private class LoadingTask extends Task<Intent>
{
LoadingTask() {
ImageView imageLoader = findViewById(R.id.imageViewLoader);
RotateAnimation rotate = new RotateAnimation(
0,360, Animation.RELATIVE_TO_SELF,
0.5f, Animation.RELATIVE_TO_SELF,0.5f);
rotate.setRepeatCount(Animation.INFINITE);
rotate.setRepeatMode(Animation.RESTART);
rotate.setDuration(5000);
rotate.setInterpolator(new LinearInterpolator());
imageNeedle.startAnimation(rotate);
}
#Override
public Intent doInBackground() {
DemoApplication app = (DemoApplication) getApplicationContext();
return new Intent(app, MainActivity.class);
return null;
}
#Override
public void onSuccess(Intent result) {
if (result != null) {
startActivity(result);
}
finish();
}
#Override
public void onFail(Throwable throwable) {
super.onFail(throwable);
}
#Override
public void onCancel() {
super.onCancel();
}
}
}
This class uses the TaskScheduler library, and the Task class is based on Runnable.
Inside the second class I add a Thread.Sleep to make the loading last more time.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try { Thread.sleep(5000); }
catch (InterruptedException ex) { android.util.Log.d("Exception", ex.toString()); }
...
}
...
}
My problem is that during these 5 seconds while MainActivity is loading, the animated image does not show or rotate. If I copy the same Thread.sleep block inside doInBackground (LoadingTask), then I can see the animation:
#Override
public Intent doInBackground() {
DemoApplication app = (DemoApplication) getApplicationContext();
// this makes the animation run
try { Thread.sleep(5000); }
catch (InterruptedException ex) { android.util.Log.d("Exception", ex.toString()); }
return new Intent(app, MainActivity.class);
return null;
}
So, how do I make it that the animation runs without using an unnecessary Thread.sleep inside doInBackground? I understand that if the second activity loads quickly, the animation won't show, but it doesn't work even when making it take more time.
You can do this Broadcast Receiver.
You don't need to use thread.
Simply start both the activity simultaneously.
In Splash Activity, register for broadcast reciver.and is Second activity send broadcast when all the data loaded. And then finish your splash activity.
If you didn't understand then I can give you an example.
Let me know.
Related
I would like to use the same button to start and stop playing some sounds with a for loop inside function play().
I thought to use lock variable to do this, but button after click remains pressed till the function play end is execution.
Can you suggest some solution?
I have a situation like this:
public class MainActivity extends Activity {
private static SoundPool sound;
static int lock=1;
int s;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sound=new SoundPool(20, AudioManager.STREAM_MUSIC, 100);
s=sound.load(this,R.raw.bipsound, 0);
Button button = (Button) findViewById(R.id.button);
}
public void onClick(View v) {
switch(lock) {
case 0:
lock=1;
break;
case 1:
lock=0;
play();
break;
}
}
public void play(){
for(int i=0;i<10;i++){
sound.play(s,1.0f, 1.0f, 1, 0, 1);
if(lock==1)
return;
try {Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
This is a problem try {Thread.sleep(1000); inside play(). You are telling the main Thread to sleep which is almost always a bad idea. The Button becomes pressed and remains in that state until the sleep() time has finished.
Remove that line. And I'm not sure what you are trying to accomplish there but you can run it in a separate Thread with things like TimerTask, use a handler or other such features. If you need more help then please explain what you are trying to do with that.
That's normal because you're using try {Thread.sleep(1000); and it stop the main thread during 1 seconde.
You've to use an AsyncTask to do that :)
Here's an example.
private void goToMainActivity() {
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Intent intent = new Intent(fa, Main.class);
startActivity(intent);
}
}.execute();
}
My app has the following Activities:
DashboardActivity
SplashActivity
MainActivity
This how the flow is required:
The dash board has a button that starts up the MainActivity. The onCreate() method of the main activity checks if a user-profile was previously created, if yes, then it starts normally (this is fast, no GUI delay).
If no user-profile is found, then it's required to display a splash screen having instructions/how-to for the mainActivity, meanwhile the onCreate() of the main activity creates a new user-profile file(slow and GUI blocking).
What I'm currently see is the splash/instructions showing delayed after the slow user-profile creation ends.
Here is a code snippet from MainActivity.
private void showUsage(){
Thread splashTread = new Thread() {
public void run() {
try {
Intent instructionIntent = new Intent(MainActivity.this,
InstructionsActivity.class);
startActivity(instructionIntent);
} catch (Exception e) {
e.printStackTrace();
}
}
};
splashTread.start();
}
#Override //MainActivity
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
if (!IsProfileExists()){
showUsage();
try{
createUserProfile(); //slow!
} catch (Exception e) { }
}
/*Continue with MainActivity*/
}
The Splash dismisses itself by a click:
public class InstructionsActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.instructions_layout);
ImageView instructions = (ImageView) findViewById(R.id.ivInstructions);
instructions.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
finish();
}
});
}
}
The problem:
The Instructions Activity (splash) shows after the GUI gets block from the MainActivity onCreate().
Any clues?
Do the condition check (IsProfileExists()) from dashBoardActivity and call the Splash activity if profile doesn't exist.
This code of mine is not working... I have checked all the links on this site and also tried animation listener but still its not working.
public class SplashScreenPage extends Activity implements Runnable{
Thread splash;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen_page_layout);
splash = new Thread(this);
splash.start();
}
#SuppressWarnings("static-access")
#Override
public void run() {
try {
splash.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Intent intent = new Intent(SplashScreenPage.this,LoginPage.class);
startActivity(intent);
finish();
SplashScreenPage.this.overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
}
#Override
protected void onPause() {
overridePendingTransition(R.anim.slide_in_right, R.anim.slide_out_left);
super.onPause();
}
}
The problem is with your device's default settings. Go to settings > display > animation > allow "all animations". This will allow overridePendingTransition to work properly.
The problem I see is that you're using your animation in a different Thread of the main thread. That main thread is also known as the UI Thread. So, you need to get back to that UI Thread. This should work (I use overridePendingTransition(0, 0) to remove any animation, you can experiment with others:
public class SplashActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setContentView(R.layout.activity_splash);
presentLogo();
}
/** Called to present the Splash image for an amount of time */
private void presentLogo() {
final SplashActivity splashActivity = this;
new Thread() {
public void run() {
synchronized (splashActivity) {
try {
sleep(Constants.SPLASH_PRESENTATION_DURATION);
} catch (InterruptedException e) {
} finally {
runOnUiThread(new Runnable() {
public void run() {
finish();
overridePendingTransition(0, 0);
// After splash, go to the new activity
Intent intent = new Intent();
intent.setClass(splashActivity, LoginActivity.class);
startActivity(intent);
}
});
}
}
}
}.start();
}
}
Try this:
Intent intent = new Intent(SplashScreenPage.this,LoginPage.class);
startActivity(intent);
finish();
overridePendingTransition(R.anim.slide_in_left, R.anim.slide_out_right);
I have an activity that contains many UI views. In its onCreate method, I found single line of setContentView takes 8-12 seconds to be complete. So I want to show my logo image while it's loading. I tried many things but without any success. I suspect main reason might be that before finishing setContentView, nothing can be shown.
Any help would be appreciated.
UPDATE:
I think many people do not know that you cannot show any dialog before finishing setContentView. So using another splash activity does not help me at all.
UPDATE2
I forgot to update this question after I found cause of the problem. Please refer to following question: setContentView taking long time (10-15 seconds) to execute
use AsyncTask
put splash in onPreExecute()
and do your work in doInBackground()
and close splash in onPostExecute()
Below is the simple code for creating splash screen using CountDownTimer class
public class SplashDialogActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// Be sure to call the super class.
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.layout);
counter.start();
}
MyCount counter = new MyCount(5000, 1000);
public class MyCount extends CountDownTimer{
public MyCount(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override
public void onFinish() {
go_back();
}
#Override
public void onTick(long millisUntilFinished) {
}
}
public void go_back()
{
counter.cancel();
Intent i=new Intent(this,account.class);
i.putExtra("first_time", true);
startActivity(i);
this.finish();
}
}
try this code for splash page
private Thread mSplashThread;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splesh);
final Splash sPlashScreen = this;
mSplashThread = new Thread(){
#Override
public void run(){
try {
synchronized(this){
wait(5000);
}
}
catch(InterruptedException ex){
}
finish();
Intent intent = new Intent();
intent.setClass(sPlashScreen,Login.class);
startActivity(intent);
stop();
}
};
mSplashThread.start();
}
// Processes splash screen touch events
#Override
public boolean onTouchEvent(MotionEvent evt) {
if(evt.getAction() == MotionEvent.ACTION_DOWN)
{
synchronized(mSplashThread){
mSplashThread.notifyAll();
}
}
return true;
}
I have a start screen with a short delay, after the delay it moves onto the splashscreen however I cant seem to override the transition and I cant see why...Although the transition does work in debug mode which is very strange
package com.example.android.bubblestrouble;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
public class Team extends Activity{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
final int delay = 3000;
setContentView(R.layout.team);
Thread welcomeThread = new Thread()
{
int wait = 0;
#Override
public void run()
{
try {
super.run();
/**
* use while to get the splash time. Use sleep() to increase
* the wait variable for every 100L.
*/
while (wait < delay)
{
sleep(100);
wait += 100;
}
}
catch (Exception e)
{
System.out.println("EXc=" + e);
}
finally
{
/**
* Called after splash times up. Do some action after splash
* times up. Here we moved to another main activity class
*/
startActivity(new Intent(Team.this, SplashScreen.class));
Team.this.finish();
Team.this.overridePendingTransition(R.anim.fade, R.anim.hold);
}
}
};
welcomeThread.start();
}
}
Straight solution. Show your splash image immediately on activity start and replace in with the needed layout by timer. Something like this(onCreate event of Team activity):
ImageView splashImage = new ImageView(this);
splashImage.setImageBitmap(splashBitmap); // or drawable/resource - as you like
setContentView(splashImage);
Thread timerThread = new Thread() {
#Override
public void run() {
sleep(3000);
Team.runOnUiThread(new Runnable() {
#Override
public void run() {
setContentView(R.layout.team);
}
});
}
}
timerThread.start();