I have a splash screen that i want to run before my main app screen. However, when the timer ends, the applicaiton crashes. Any ideas on why this happens? Thanks in advance.
Below is the referenced code
public class Splash extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
Thread timer = new Thread() {
// Whatever is enclosed in the {} of method run(), runs when we
// start the application
public void run() {
try {
sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
Intent openMainScreen = new Intent("com.package.Main_Screen");
startActivity(openMainScreen);
}
}
};
timer.start();
}
}
Why don't you simply use this kind of Intent,
Intent openMainScreen = new Intent(Splash.this,Main_Screen.class);
startActivity(openMainScreen);
And also make sure you you have added the Activity in your manifest like this,
<activity android:name=".Main_Screen">
</activity>
You have to call like this
Intent openMainScreen = new Intent(ClassName.this, MainActivity.class);
startActivity(openMainScreen);
And you have to register it in Manifest file
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
You are calling startActivity from different Thread.You have to run it from UI thread.What you are trying to achieve can be done easily by
public class Splash extends Activity {
Handler handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
handler = new Handler();
handler.postDelayed(new Runnable() {
public void run() {
Intent openMainScreen = new Intent(Splash.this,
Main_Screen.class);
startActivity(openMainScreen);
}
}, 2000);
}
}
Write below code
Intent openMainScreen = new Intent(this, MainActivity.class);
startActivity(openMainScreen);
instead of
Intent openMainScreen = new Intent("com.package.Main_Screen");
startActivity(openMainScreen);
And declare your MainActivity into Androidmanifest.xml file.
<activity
android:name=".MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
it will solve your problem.
Related
I am working on an android project in which there are Login, Register, Main Activity and also a Splash Activity.
So in that, except Splash Activity, all activity gets crashed.
First Splash Activity gets executed then Main Activity gets Crashed.
Here is the Splash Activity:
public class SplashActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
Thread thread = new Thread()
{
#Override
public void run() {
try
{
sleep(5000);
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
Intent mainintent = new Intent(SplashActivity.this, LoginActivity.class);
startActivity(mainintent);
}
}
};
thread.start();
}
#Override
protected void onPause() {
super.onPause();
finish();
}
}
Here is the Manifest.xml file
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name="com.example.connect2every1.MainActivity">
</activity>
<activity android:name="com.example.connect2every1.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Login Activity, Register Activity, Main Activity, must be get executed
the main motive is that
after Splash Activity Login Activity must be executed.
It is better to use the following code
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent mainintent = new Intent(SplashActivity.this, LoginActivity.class);
startActivity(mainintent);finish()
}
}, 2000);
After that remove finish() from onResume()
Did you register your every Activity in AndroidManifest.xml?
If you did, you won't be able to switch UI from a non-UI thread without a Handler.
So in order to get your code work, you'll need to initialize a Handler in UI thread and post a Runnable instance with or without delay in UI or non-UI thread.
Here is the Code
public class SplashActivity extends AppCompatActivity {
private mHander Handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
mHander = new Handler();
}
#Override
public void onPostCreate(){
mHander.postDelayed(new Runnable() {
#Override
public void run() {
startActivity(new Intent(SplashActivity.this,LoginActivity.class));
finish();
}
},5000);
}
}
and also remove finish(); from onPause() method, because your current activity automatically gets closed when Runnable executes.
Hope this helps!
You can't change UI from worker thread, only Main thread can change UI, so use runOnUiThread when starting activity.
Thread splash=new Thread(){
public void run() {
synchronized (this) {
try {
wait(2000);
runOnUiThread(new Runnable() {
#Override
public void run() {
startActivity(new Intent(getApplicationContext(),LoginActivity.class));
finish();
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
splash.start();
First change your Activity name MainActivity to LoginActivity from Manifest file.
<activity android:name="com.example.connect2every1.LoginActivity ">
</activity>
instead of
<activity android:name="com.example.connect2every1.MainActivity">
</activity>
than, Use handler Class for splash screen
Handler handler=new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
startActivity(new Intent(SplashActivity.this,LoginActivity.class));
finish();
}
},4000);
I added splash screen to my application and my code looks as follow:
public class SplashActivity extends AppCompatActivity {
public static final int DELAY_MILLIS = 2000;//for testing i use 5 seconds
private Handler handler = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
Intent intent = new Intent(SplashActivity.this, CurrencyExchangeActivity.class);
startActivity(intent);
finish();
}
}, DELAY_MILLIS);
}
#Override
protected void onStop() {
super.onStop();
handler.removeCallbacksAndMessages(null);
}
}
My Manifest :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.vdovin.currencyratesapp">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:name=".application.CurrencyApp"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".screens.splash.SplashActivity"
android:theme="#style/SplashTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".screens.main.CurrencyExchangeActivity">
</activity>
</application>
</manifest>
So I faced with next problem:
If I hide my app with home button when loading splash screen, then when I open app again, splash screen activity not call CurrencyExchangeActivity. I understand that it appears because method onCreate() invoked only once, but I can't put it in onResume() because when I open my app again it shows me the splash screen again. But I want to show CurrencyActivity, like google's apps(maps, sheets etc...)
You cannot do that simply because you're setting the splash screen image as background of theme of your Activity. That's window level background which would show up regardless of your navigation or anything.
If you really want to show splash screen only once in app lifetime then you'll have to do it in not the right way and have that image as part of your layout and inflate that layout using setContentView. Now when you come again in the app, you will call your CurrencyExchangeActivity even before setContentView of splash activity and which will just show a black window background and directly show up CurrencyExchangeActivity.
Let me know if this makes sense or not. I can elaborate more if needed
Please try this way. I haven't tested your code. My sway of using the splash will be like below:
public class SplashActivity extends Activity {
private static final String TAG = SplashActivity.class.getSimpleName();
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
loadNext();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
new Thread() {
#Override
public void run() {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
handler.sendEmptyMessage(1);
}
}.start();
}
protected void loadNext() {
Intent intent = new Intent(this, NextActivity.class);
startActivity(intent);
finish();
}
}
you have forgot to add
setContentView(R.layout.splash);
add this it will work
Maybe you could try the following:
#Override
protected void onResume() {
super.onResume();
Intent intent = new Intent(this, CurrencyExchangeActivity.class);
startActivity(intent);
finish();
}
This will skip the delay when reopening the app after pressing the home button.
I usually use a postDelayed Runnable.
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
#Override
public void run() {
Intent intent = new Intent(this, NextActivity.class);
startActivity(intent);
finish();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume() {
super.onResume();
// 5 sec
handler.postDelayed(runnable, 5000);
}
#Override
protected void onPause() {
super.onPause();
// 5 sec
handler.removeCallbacks(runnable);
}
}
I would like to suggest to keep the splash screen showing mechanism in the CurrencyActivity in your case. Here's the pseudo code.
I've added proper comments in the code. Please check.
public class CurrencyActivity extends AppCompatActivity {
public static final int DELAY_MILLIS = 2000; //for testing i use 5 seconds
private Handler handler = null;
private boolean showSplash = true; // True by default
private ImageView splashImage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.currency_activity);
// Get a image overlaying the other views in your currency layout
splashImage = (ImageView) findViewById(R.id.splash);
if(showSplash) showSplashScreen();
}
#Override
protected void onStop() {
super.onStop();
handler.removeCallbacksAndMessages(null);
}
#Override
protected void onPause() {
super.onPause();
showSplash = false; // Set the variable to false when you take this in background
}
#Override
protected void onResume() {
super.onResume();
// Check if the variable is false and then set the visibility to GONE
if(!showSplash) splashImage.setVisibility(View.GONE);
}
private void showSplashScreen() {
handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
splashImage.setVisibility(View.GONE);
showSplash = false;
}
}, DELAY_MILLIS);
}
}
Try this out--
SplashScreenActivity-
public class SplashActivity extends AppCompatActivity {
public static final int DELAY_MILLIS = 2000;//for testing i use 5 seconds
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent intent = new Intent(SplashActivity.this, CurrencyExchangeActivity.class);
startActivity(intent);
finish();
}
}, DELAY_MILLIS);
}
}
For manifest--
<?xml version="1.0" encoding="utf-8"?>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".CurrencyExchangeActivity"/>
</application>
i tested this code for if you had the problem that when the home screen button is pressed the splash screen is displayed again then this would work....
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
put this on MainActivity.java
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent= new Intent(getApplicationContext(),SignIn.class);
startActivity(intent);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
int secondsDelayed =1;
new Handler().postDelayed(new Runnable() {
public void run() {
startActivity(new Intent(SplashActivity.this,LoginActivity.class));
finish();
}
}, secondsDelayed * 1000);
}
}
There are two tags you can use against any activity which you want open when user the app to open.
LAUNCHER as <category android:name="android.intent.category.LAUNCHER" />
MAIN as <action android:name="android.intent.action.MAIN" />
<activity android:name="com.example.activity.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
To jump from one activty to other use the below code.
Intent i = new (CurrentActivityName.this , NextActivityName.class);
startActivity(i);
Dont forget to add Next in manifest.
<activity android:name="com.example.activity.NextActivityName">
then you should use following code inside your Splash Activity onCreate method:
new Timer().schedule(new TimerTask() {
#Override
public void run() {
startActivity(new Intent(SplashActivity.this, RegisterActivity.class));
}
}, 5000); //where 5000 is time in miliseconds for delay.
I've an app.
When my app start, I show and splash screen. When my splash screen finish, I start my main activity.
But I've a problem. When I rotate my app in splash screen, my app restart and four senconds later, start my new activity. If I rotate my splash screen three time, start three main activity.
I want start only one activity, how I can do it?
This is my splash screen code:
public class Splash extends Activity {
public static final int seconds=4;
public static final int miliseconds=seconds*1000;
private ProgressBar progressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
progressBar=(ProgressBar) findViewById(R.id.progressBar);
progressBar.setMax(seconds-1);
progressBar.getProgressDrawable().setColorFilter(Color.RED, PorterDuff.Mode.SRC_IN);
startAnimation();
}
public void startAnimation(){
new CountDownTimer(miliseconds,1000){
#Override
public void onTick(long millisUntilFinished) {
//progressbar update--->1 second
progressBar.setProgress(getMiliseconds(millisUntilFinished));
}
#Override
public void onFinish() {
Intent i = new Intent(Splash.this, MainActivity.class);
Splash.this.startActivityForResult(i,1);
}
}.start();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//when I return to the MainActivity, finish my app
if(requestCode==1) finish();
}
public int getMiliseconds(long milis){
return (int) ((milisegundos-milis)/1000);
}
}
Use configchanges in your activity tag in manifest.xml
Example
<activity
android:name=".Splash"
android:label="#string/app_name"
android:configChanges="keyboardHidden|orientation" />
you can use this tag on another activities as well if you want to avoid onCreate again and again
Try this
Intent i = new Intent(Splash.this, MainActivity.class);
startActivity(i);
finish();
In AndroidManifest.xml, you need to set the orientation to a specific orientation. Add in android:screenOrientation="portrait" under the stuff for your activity. For example, my activity might look like this now:
<activity
android:name=".SplashScreen"
android:label="#string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
If you are in landscape mode, use android:screenOrientation="landscape".
If this doesn't work, in your onFinish() method, use the following:
#Override
public void onFinish() {
Intent i = new Intent(Splash.this, MainActivity.class);
startActivity(i);
finish();
}
I am having an issue where the application does not load after including the Splash screen to the application. This is the code for the SplashScreen.java & the Manifest file. I am not sure what I am missing. I have gone over this several times and am unable to spot the error. I have gone thro' similar posts but could find the answer. Please help
public class SplashScreen extends Activity {
private long ms=0;
private long splashTime=2000;
private boolean splashActive = true;
private boolean paused=false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Thread mythread = new Thread() {
public void run() {
try {
while (splashActive && ms < splashTime) {
if(!paused)
ms=ms+100;
sleep(100);
}
} catch(Exception e) {}
finally {
Intent intent = new Intent(SplashScreen.this, TotalControl.class);
startActivity(intent);
}
}
};
mythread.start();
}
The Manifest file is as follows
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.tvganesh.totalcontrol.SplashScreen"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.tvganesh.totalcontrol.TotalControl"
android:label="#string/app_name" >
</activity>
</application>
After the Splash Screen which it display it is supposed to switch to TotalControl.class. But the I get the message "The Application stopped unexpectedly"
Can you let me know what I am missing?
Don't use Thread.sleep - you have no guarantee that it will start up again exactly after 100ms. Use a Handler instead:
getWindow().getDecorView().getHandler().postDelayed(new Runnable()
{
#Override
public void run()
{
Intent intent = new Intent(SplashScreen.this, TotalControl.class);
startActivity(intent);
}
}, splashTime);
I think this will work for you
Don't use threads to show the splash.
public class SplashScreen extends Activity {
protected int _splashTime = 5000;
private Thread splashTread;
MyCount counter = new MyCount(4000, 4000);
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
counter.start();
}
public class MyCount extends CountDownTimer
{
public MyCount(long csecond, long countDownInterval)
{
super(csecond, countDownInterval);
}
#Override
public void onFinish() {
finish();
Intent intent = new Intent();
intent.setClass(SplashScreen.this, TotalControl.class);
startActivity(intent);
}
#Override
public void onTick(long arg0) {
}
}
}
I have solved the problem. This appears to be a known bug in AndEngine and the fix is add the following line to the Manifest file
android:configChanges="orientation|screenSize"
Thanks for all your help.