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();
Related
I want to make a pause between two lines of code, Let me explain a bit:
-> the user clicks a button (a card in fact) and I show it by changing the background of this button:
thisbutton.setBackgroundResource(R.drawable.icon);
-> after let's say 1 second, I need to go back to the previous state of the button by changing back its background:
thisbutton.setBackgroundResource(R.drawable.defaultcard);
-> I've tried to pause the thread between these two lines of code with:
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
However, this does not work. Maybe it's the process and not the Thread that I need to pause?
I've also tried (but it doesn't work):
new Reminder(5);
With this:
public class Reminder {
Timer timer;
public Reminder(int seconds) {
timer = new Timer();
timer.schedule(new RemindTask(), seconds*1000);
}
class RemindTask extends TimerTask {
public void run() {
System.out.format("Time's up!%n");
timer.cancel(); //Terminate the timer thread
}
}
}
How can I pause/sleep the thread or process?
One solution to this problem is to use the Handler.postDelayed() method. Some Google training materials suggest the same solution.
#Override
public void onClick(View v) {
my_button.setBackgroundResource(R.drawable.icon);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
my_button.setBackgroundResource(R.drawable.defaultcard);
}
}, 2000);
}
However, some have pointed out that the solution above causes a memory leak because it uses a non-static inner and anonymous class which implicitly holds a reference to its outer class, the activity. This is a problem when the activity context is garbage collected.
A more complex solution that avoids the memory leak subclasses the Handler and Runnable with static inner classes inside the activity since static inner classes do not hold an implicit reference to their outer class:
private static class MyHandler extends Handler {}
private final MyHandler mHandler = new MyHandler();
public static class MyRunnable implements Runnable {
private final WeakReference<Activity> mActivity;
public MyRunnable(Activity activity) {
mActivity = new WeakReference<>(activity);
}
#Override
public void run() {
Activity activity = mActivity.get();
if (activity != null) {
Button btn = (Button) activity.findViewById(R.id.button);
btn.setBackgroundResource(R.drawable.defaultcard);
}
}
}
private MyRunnable mRunnable = new MyRunnable(this);
public void onClick(View view) {
my_button.setBackgroundResource(R.drawable.icon);
// Execute the Runnable in 2 seconds
mHandler.postDelayed(mRunnable, 2000);
}
Note that the Runnable uses a WeakReference to the Activity, which is necessary in a static class that needs access to the UI.
You can try this one it is short
SystemClock.sleep(7000);
WARNING: Never, ever, do this on a UI thread.
Use this to sleep eg. background thread.
Full solution for your problem will be:
This is available API 1
findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View button) {
button.setBackgroundResource(R.drawable.avatar_dead);
final long changeTime = 1000L;
button.postDelayed(new Runnable() {
#Override
public void run() {
button.setBackgroundResource(R.drawable.avatar_small);
}
}, changeTime);
}
});
Without creating tmp Handler. Also this solution is better than #tronman because we do not retain view by Handler.
Also we don't have problem with Handler created at bad thread ;)
Documentation
public static void sleep (long ms)
Added in API level 1
Waits a given number of milliseconds (of uptimeMillis) before returning. Similar to sleep(long), but does not throw InterruptedException; interrupt() events are deferred until the
next interruptible operation.
Does not return until at least the specified number of milliseconds has elapsed.
Parameters
ms to sleep before returning, in milliseconds of uptime.
Code for postDelayed from View class:
/**
* <p>Causes the Runnable to be added to the message queue, to be run
* after the specified amount of time elapses.
* The runnable will be run on the user interface thread.</p>
*
* #param action The Runnable that will be executed.
* #param delayMillis The delay (in milliseconds) until the Runnable
* will be executed.
*
* #return true if the Runnable was successfully placed in to the
* message queue. Returns false on failure, usually because the
* looper processing the message queue is exiting. Note that a
* result of true does not mean the Runnable will be processed --
* if the looper is quit before the delivery time of the message
* occurs then the message will be dropped.
*
* #see #post
* #see #removeCallbacks
*/
public boolean postDelayed(Runnable action, long delayMillis) {
final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
return attachInfo.mHandler.postDelayed(action, delayMillis);
}
// Assume that post will succeed later
ViewRootImpl.getRunQueue().postDelayed(action, delayMillis);
return true;
}
I use this:
Thread closeActivity = new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(3000);
// Do some stuff
} catch (Exception e) {
e.getLocalizedMessage();
}
}
});
I use CountDownTime
new CountDownTimer(5000, 1000) {
#Override
public void onTick(long millisUntilFinished) {
// do something after 1s
}
#Override
public void onFinish() {
// do something end times 5s
}
}.start();
You probably don't want to do it that way. By putting an explicit sleep() in your button-clicked event handler, you would actually lock up the whole UI for a second. One alternative is to use some sort of single-shot Timer. Create a TimerTask to change the background color back to the default color, and schedule it on the Timer.
Another possibility is to use a Handler. There's a tutorial about somebody who switched from using a Timer to using a Handler.
Incidentally, you can't pause a process. A Java (or Android) process has at least 1 thread, and you can only sleep threads.
This is what I did at the end of the day - works fine now :
#Override
public void onClick(View v) {
my_button.setBackgroundResource(R.drawable.icon);
// SLEEP 2 SECONDS HERE ...
final Handler handler = new Handler();
Timer t = new Timer();
t.schedule(new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
my_button.setBackgroundResource(R.drawable.defaultcard);
}
});
}
}, 2000);
}
In addition to Mr. Yankowsky's answers, you could also use postDelayed(). This is available on any View (e.g., your card) and takes a Runnable and a delay period. It executes the Runnable after that delay.
This is my example
Create a Java Utils
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
public class Utils {
public static void showDummyWaitingDialog(final Context context, final Intent startingIntent) {
// ...
final ProgressDialog progressDialog = ProgressDialog.show(context, "Please wait...", "Loading data ...", true);
new Thread() {
public void run() {
try{
// Do some work here
sleep(5000);
} catch (Exception e) {
}
// start next intent
new Thread() {
public void run() {
// Dismiss the Dialog
progressDialog.dismiss();
// start selected activity
if ( startingIntent != null) context.startActivity(startingIntent);
}
}.start();
}
}.start();
}
}
Or you could use:
android.os.SystemClock.sleep(checkEvery)
which has the advantage of not requiring a wrapping try ... catch.
If you use Kotlin and coroutines, you can simply do
GlobalScope.launch {
delay(3000) // In ms
//Code after sleep
}
And if you need to update UI
GlobalScope.launch {
delay(3000)
GlobalScope.launch(Dispatchers.Main) {
//Action on UI thread
}
}
I know this is an old thread, but in the Android documentation I found a solution that worked very well for me...
new CountDownTimer(30000, 1000) {
public void onTick(long millisUntilFinished) {
mTextField.setText("seconds remaining: " + millisUntilFinished / 1000);
}
public void onFinish() {
mTextField.setText("done!");
}
}.start();
https://developer.android.com/reference/android/os/CountDownTimer.html
Hope this helps someone...
class MyActivity{
private final Handler handler = new Handler();
private Runnable yourRunnable;
protected void onCreate(#Nullable Bundle savedInstanceState) {
// ....
this.yourRunnable = new Runnable() {
#Override
public void run() {
//code
}
};
this.handler.postDelayed(this.yourRunnable, 2000);
}
#Override
protected void onDestroy() {
// to avoid memory leaks
this.handler.removeCallbacks(this.yourRunnable);
}
}
And to be double sure you can be combined it with the "static class" method as described in the tronman answer
Right now in my application downloading code is working but when i download multiple files it download randomly not in queue, i need it download in queue and this current download is not displaying in notification bar only display in activity.
I want to know how to possible multiple downloading with displaying in notification bar and also display progress bar in current activity.
Thank you
Looper
By using looper you download multiple file in queue one by one.
Steps 1: Lets create DownloadThreadListener.java interface which will be used to get thread updates.
package com.example.looper;
public interface DownloadThreadListener {
void handleDownloadThreadUpdate();
}
Steps 2: Lets now create a class named DownloadTask.java which will simulate the downloading. We will be using random time sleep to simulate the download time.
package com.example.looper;
import java.util.Random;
import android.util.Log;
/**
* This is not a real download task. It just sleeps for some random time when
* it's launched. The idea is not to require a connection and not to eat it.
*
*/
public class DownloadTask implements Runnable {
private static final String TAG = DownloadTask.class.getSimpleName();
private static final Random random = new Random();
private int lengthSec;
public DownloadTask() {
lengthSec = random.nextInt(3) + 1;
}
#Override
public void run() {
try {
Thread.sleep(lengthSec * 1000);
// it's a good idea to always catch Throwable
// in isolated "codelets" like Runnable or Thread
// otherwise the exception might be sunk by some
// agent that actually runs your Runnable - you
// never know what it might be.
} catch (Throwable t) {
Log.e(TAG, "Error in DownloadTask", t);
}
}
}
Steps 3: Now lets create the thread subclass which will act as pipeline. First we will call Looper.prepare() to make this Thread act as pipeline. Next new Handler() will be called to handle message queue on this thread. Finally Looper.loop() will be called to start running the message loop. New tasks will be added using enqueueDownload(final DownloadTask task).
package com.example.looper;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
public final class DownloadThread extends Thread {
private static final String TAG = DownloadThread.class.getSimpleName();
private Handler handler;
private int totalQueued;
private int totalCompleted;
private DownloadThreadListener listener;
public DownloadThread(DownloadThreadListener listener) {
this.listener = listener;
}
#Override
public void run() {
try {
// preparing a looper on current thread
// the current thread is being detected implicitly
Looper.prepare();
Log.i(TAG, "DownloadThread entering the loop");
// now, the handler will automatically bind to the
// Looper that is attached to the current thread
// You don't need to specify the Looper explicitly
handler = new Handler();
// After the following line the thread will start
// running the message loop and will not normally
// exit the loop unless a problem happens or you
// quit() the looper (see below)
Looper.loop();
Log.i(TAG, "DownloadThread exiting gracefully");
} catch (Throwable t) {
Log.e(TAG, "DownloadThread halted due to an error", t);
}
}
// This method is allowed to be called from any thread
public synchronized void requestStop() {
// using the handler, post a Runnable that will quit()
// the Looper attached to our DownloadThread
// obviously, all previously queued tasks will be executed
// before the loop gets the quit Runnable
handler.post(new Runnable() {
#Override
public void run() {
// This is guaranteed to run on the DownloadThread
// so we can use myLooper() to get its looper
Log.i(TAG, "DownloadThread loop quitting by request");
Looper.myLooper().quit();
}
});
}
public synchronized void enqueueDownload(final DownloadTask task) {
// Wrap DownloadTask into another Runnable to track the statistics
handler.post(new Runnable() {
#Override
public void run() {
try {
task.run();
} finally {
// register task completion
synchronized (DownloadThread.this) {
totalCompleted++;
}
// tell the listener something has happened
signalUpdate();
}
}
});
totalQueued++;
// tell the listeners the queue is now longer
signalUpdate();
}
public synchronized int getTotalQueued() {
return totalQueued;
}
public synchronized int getTotalCompleted() {
return totalCompleted;
}
// Please note! This method will normally be called from the download
// thread.
// Thus, it is up for the listener to deal with that (in case it is a UI
// component,
// it has to execute the signal handling code in the UI thread using Handler
// - see
// DownloadQueueActivity for example).
private void signalUpdate() {
if (listener != null) {
listener.handleDownloadThreadUpdate();
}
}
}
Steps 4: Now add full functionality to MainActivity.java . Here also we will create handler so that we can post events on main thread.
package com.example.looper;
import java.util.Random;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Vibrator;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
public class MainActivity extends Activity implements DownloadThreadListener,
OnClickListener {
private DownloadThread downloadThread;
private Handler handler;
private ProgressBar progressBar;
private TextView statusText;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create and launch the download thread
downloadThread = new DownloadThread(this);
downloadThread.start();
// Create the Handler. It will implicitly bind to the Looper
// that is internally created for this thread (since it is the UI
// thread)
handler = new Handler();
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
statusText = (TextView) findViewById(R.id.status_text);
Button scheduleButton = (Button) findViewById(R.id.schedule_button);
scheduleButton.setOnClickListener(this);
}
#Override
protected void onDestroy() {
super.onDestroy();
// request the thread to stop
downloadThread.requestStop();
}
// note! this might be called from another thread
#Override
public void handleDownloadThreadUpdate() {
// we want to modify the progress bar so we need to do it from the UI
// thread
// how can we make sure the code runs in the UI thread? use the handler!
handler.post(new Runnable() {
#Override
public void run() {
int total = downloadThread.getTotalQueued();
int completed = downloadThread.getTotalCompleted();
progressBar.setMax(total);
progressBar.setProgress(0); // need to do it due to a
// ProgressBar bug
progressBar.setProgress(completed);
statusText.setText(String.format("Downloaded %d/%d", completed,
total));
// vibrate for fun
if (completed == total) {
((Vibrator) getSystemService(VIBRATOR_SERVICE))
.vibrate(100);
}
}
});
}
#Override
public void onClick(View source) {
if (source.getId() == R.id.schedule_button) {
int totalTasks = new Random().nextInt(3) + 1;
for (int i = 0; i < totalTasks; ++i) {
downloadThread.enqueueDownload(new DownloadTask());
}
}
}
}
Steps 5: Add Vibrate permission
<uses-permission android:name="android.permission.VIBRATE" />
Original Post Complete tutorial here.
EDIT: I've found that what I'm describing below only occurs on my emulated device (Nexus 5, target api 19, 4.4.2 with Intel Atom (x86) cpu), but NOT on my physical device (HTC One)....
EDIT2: Edit1 was due to an IllegalStateException that I didnt catch. Added some code to check if the thread was already running before trying to start it. This combined with the accepted answer resolved my issue.
I have implemented an activty that starts a new thread in the activity's onCreate method, like this:
...
private boolean running;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
running = true;
new Thread(null, work, "myThread").start();
}
Runnable work = new Runnable() {
#Override
public void run() {
while (running) {
//Doing work
}
}
};
I'm "pausing" my thread with my activity's onPause method, like this:
#Override
protected void onPause() {
running = false;
super.onPause();
}
So I thought that resuming it would be just as easy...ยจ
#Override
protected void onResume(){
running = true;
super.onResume();
}
but my thread isn't resuming. Any ideas why? Thankful for any help.
Marcus
All of the answers i think have some issues about your running variable because you can not write and read a variable from two different Threads without synchronized block so i post my own answer:
package com.example.threadandtoast;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
public class MonitorObject{
public boolean running = true;
public String message = "";
public boolean mustBePost = true;
}
Thread t;
int threadNameCounter = 0; // i use this variable to make sure that old thread is deleted
// when i pause, you can see it and track it in DDMS
Runnable work = new Runnable() {
boolean myRunning;
#Override
public void run() {
synchronized(mSync) {
myRunning = mSync.running;
}
while (myRunning) {
runOnUiThread(new Runnable() { // in order to update the UI (create Toast)
#Override // we must switch to main thread
public void run() {
// i want to read the message so i must use synchronized block
synchronized(mSync) {
// i use this variable to post a message just for one time because i am in an infinite loop
// if i do not set a limit on the toast i create it infinite times
if(mSync.mustBePost){
Toast.makeText(MainActivity.this, mSync.message, Toast.LENGTH_SHORT).show();
// the message post so i must set it to false
mSync.mustBePost = false;
// if i am going to pause set mSync.running to false so at the end of infinite loop
//of thread he reads it and leaves the loop
if(mSync.message.equals("Main Activity is going to pause")){
mSync.running=false;
}
}
}
}
});
synchronized(mSync) {
myRunning = mSync.running;
}
}
}
};
final MonitorObject mSync = new MonitorObject();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onPause() {
super.onPause();
synchronized(mSync) {
// mSync.running = false; you can not set it here because
// it is possible for the thread to read it and exit the loop before he posts your message
mSync.mustBePost=true;
mSync.message = "Main Activity is going to pause";
}
}
#Override
protected void onResume(){
super.onResume();
threadNameCounter++;
synchronized(mSync) {
mSync.running = true;
mSync.mustBePost=true;
mSync.message = "Main Activity is going to resume";
}
t = new Thread(work,"My Name is " + String.valueOf(threadNameCounter));
t.start();
}
}
Or you can use this code:
public class MainActivity extends ActionBarActivity {
Thread t;
int threadNameCounter = 0; // i use this variable to make sure that old thread is deleted
// when i pause, you can see it in DDMS
String message = "";
boolean isPost = false;
Runnable work = new Runnable() {
#Override
public void run() {
while (true) {
runOnUiThread(new Runnable() {
#Override
public void run() {
if(!isPost){
Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
isPost = true;
if( message.equals("Main Activity is going to pause")){
t.interrupt();
}
}
}
});
if(Thread.currentThread().isInterrupted()){
break;
}
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onPause() {
super.onPause();
message = "Main Activity is going to pause";
isPost = false;
}
#Override
protected void onResume(){
super.onResume();
message = "Main Activity is going to resume";
isPost = false;
threadNameCounter++;
t = new Thread(work,"My Name is " + String.valueOf(threadNameCounter));
t.start();
}
}
you can also use semaphore or wait-notify approach.
i put public String message = ""; and public boolean mustBePost = true; in to mSync object but it is
not necessary because only main thread have an access to them.
if you have any problem please ask.
The statement running = false; will stop execution of the Thread, instead of pausing it. Use two variables: One for stopping current Thread, and another for pausing and resuming the Thread, as follow:
boolean isThreadPause=false;
Runnable work = new Runnable() {
#Override
public void run() {
while (running) {
if (!isThreadPause) {
// Doing work
}
}
}
};
In the onPause event of the Activity, set isThreadPause to true, and in the onResume event, set isThreadPause to false.
This is because your Runnable object stops when the while loop stops. You could try this:
Runnable work = new Runnable() {
#Override
public void run() {
while () {
if(running){
//Doing work
}
}
}
};
I start studying this: Android SplashScreen
and my app works perfectly with this method.
Unfortunately, I've developed a custom splash screen (not a progress dialog like in the other post) and I'm not able to use the same approach. My splashscreen is a different activity that I starts calling it from the onCreate as a different thread.
Instead of this.pd = ProgressDialog.show(this, "Working..", "Downloading Data...", true, false); in the onCreate I do:
Thread splashThread = new Thread() {
#Override
public void run() {
// start the splash screen activity
}
};
splashThread.start();
}
The splashscreeen activity correctly starts.
So I call the AsyncTask as in the default method (doInBackground, onPostExecute) and I'm not able to end the activity that is running the splashscreen and come back to the main one, after all the variables are loaded in the doInBackground.
Any suggestion?
Well, I finally thank JPM for the suggestion to use handlers and I solved with that:
public class SplashScreen extends Activity {
private static Handler mHandler ;
private static Handler mainHandler ;
protected static final int CLOSE_SPLASH = 0 ;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen);
mHandler = new Handler(){
#Override
public void handleMessage(Message msg){
switch(msg.what){
case CLOSE_SPLASH:
finish();
break;
}
}
};
}
#Override
public void onStart(){
super.onStart();
if(mainHandler != null){
mainHandler.sendEmptyMessage(MainActivity.START_LOAD);
}
}
#Override
public boolean onKeyDown (int keyCode, KeyEvent event){
if(keyCode == KeyEvent.KEYCODE_BACK){
mainHandler.sendEmptyMessage(MainActivity.ABORT_LOAD);
}
return super.onKeyDown(keyCode, event) ;
}
public static void setMainHandler(Handler h){
mainHandler = h ;
}
public static void sendMessage(Message msg){
mHandler.sendMessage(msg);
}
public static void sendMessage(int w){
mHandler.sendEmptyMessage(w);
}
}
In the MainActivity I manage handlers back and forth:
public class MainActivity extends Activity {
private MainActivity _this;
private Handler mHandler;
protected static final int FINISH_LOAD = 0 ;
protected static final int START_LOAD = 1 ;
protected static final int ABORT_LOAD = 2 ;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
_this = this;
mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case FINISH_LOAD:
SplashScreen.sendMessage(SplashScreen.CLOSE_SPLASH);
break;
case START_LOAD:
initializing();
break;
case ABORT_LOAD:
finish();
}
}
};
startSplash();
}
private void startSplash() {
Intent intent = new Intent(this, SplashScreen.class);
SplashScreen.setMainHandler(mHandler);
startActivity(intent);
}
private void initializing() {
new Thread() {
#Override
public void run() {
long start_time = android.os.SystemClock.uptimeMillis();
doTheHeavyJob();
long duration = android.os.SystemClock.uptimeMillis() - start_time;
if (duration <=3000) {
try {
wait(3000-duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
mHandler.sendEmptyMessage(FINISH_LOAD);
}
}.start();
}
}
In this manner I can manage the doTheHeavyJob() function and finish the SplashScreen in both cases: after the job finish and at least after 3000 millis, the minimum duration of my splashscreen to be shown.
I also want to tank Teskio on the anddev italian website for the most of the job done here.
I don't know if that is the way I would have done it since Android has some nice Handler methods that can do some of what you are looking for then you can block on the thread until your items download. Here is how I make a standard Splash screen. This Splash activity is the main activity in the Manifest, and when its done calls the next activities.
import java.io.File;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;
/**
* Splash screen to start the app and maybe check if some things enabled
* If not enabled popup and if user enables then continue else close app.
*/
public class Splash extends Activity {
private static final String TAG = "Splash";
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.splash);
// load some stuff
(new Handler()).postDelayed(new splashHandler(), 2000);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(TAG, "OnActivity result code = " + resultCode);
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == -1) {
// class of the next activity you want to display after the Splash screen
Class<?> className = MainApp.class;
startActivity(new Intent(getApplication(), className ));
Splash.this.finish();
} else {
Toast.makeText(Splash.this, getResources().getText(R.string.stringSplashonActivity), Toast.LENGTH_LONG).show();
finish();
// the program...
return;
}
}
/**
* Runnable class to check if user is logged in already
* and then start the correct activity.
*
*/
class splashHandler implements Runnable{
#Override
public void run() {
.....Do something.....
}
}
}
Then don't forget to define the activity between the applicaton tags in the Android Manifest.xml (for those new to Android)
<activity android:name="Splash" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Hope this helps....
I'm not sure, what is stopping this from working. I have the code setup to cause a 3 second time delay but the View isn't working, it stays black and then after 3 seconds switches to the next screens. I think, I am doing the time delay and something hasn't been called within Android to display the layout...
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
start = System.currentTimeMillis();
setContentView(R.layout.team);
}
protected void onStart()
{
super.onStart();
while(game)
{
now = System.currentTimeMillis();
if (now - start >= 5000)
{
game = false;
Intent about = new Intent(this, SplashScreen.class);
startActivity(about);
}
}
}
I believe you want to implement a Screen with few seconds delay and then start your main Application. Just like a Splash Screen Before the Main Application Starts Right?
Then this will help you!
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/** set time to splash out */
final int welcomeScreenDisplay = 4000;
/** create a thread to show splash up to splash time */
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 < welcomeScreenDisplay) {
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(CurrentActivity.this, NextActivity.class));
finish();
}
}
};
welcomeThread.start();
}
This is a Screen for 4 seconds of Delay.
You should be using the Timer class to launch the new activity.