I'm having trouble putting this problem into searchable terms. I'm working on an Android application, and specifically the splash screen for my app. The app needs to fetch data from an external web service (a blocking function call), while it does this the user gets a nice title, image and progress bar. When the data arrives the user is redirected to the main menu. Its a simple screen, everything being defined in the xml layout file, my problem is that I just get a black screen for a few seconds and then the main menu. If I press back I get the splash screen with the progress bar spinning away happily.
Here is what I have so far:
public class SplashActivity extends Activity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
}
#Override
public void onStart(){
super.onStart();
DatabaseManager db = new DatabaseManager(this.getBaseContext());
db.fetchExternCatalog(); //doesnt return until data arrives
Intent intent = new Intent().setClass(this, MainMenuActivity.class);
startActivity(intent);
}
}
It seems the screen isnt actually drawn until the activity is running (after onCreate(), onStart(), etc). I thought onStart() would be the perfect place to put this, but apparently not.
So how do I draw everything on the screen and make my blocking function call after so the user actually sees the splash screen while the data is downloaded?
You're going to be locking up the UI thread which is why i believe you are seeing a black screen. Use an AsyncTask or create your own thread pool for DB operations.
As far as hitting the back button and seeing your old activity, You need to tell android not to store the activity in it's stack. This should help:
http://developer.android.com/guide/topics/fundamentals/tasks-and-back-stack.html
you need to use the ProgressDialog class to build the dialog, and then run the blocking method inside a thread.
I'll post an example in a minute (gotta get near a PC :p)
private void showSplash(){
progressDialog = ProgressDialog.show(this, "Hello! ima title", "Im the message you see.");
progressDialog.show();
Thread t = new Thread(new Runnable(){
public void run(){
// Put your blocking method here.
// You may need to build in a "hey, im done downloading" variable to get it to close down right
progressDialog.dismiss();
}
});
t.start();
}
Related
I am very new to android and trying to add a splash screen I am half way succeeded. But a weird think happening that surely an easy one. here i have tried :-
I wanted to stop the SplashScreen for some time. This splash screen layout contain a ImageView that show the appLogo.
public class SplashActivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.SplashScreen);
ImageView splashScreenImage = FindViewById<ImageView>(Resource.Id.appLogo);
splashScreenImage.SetImageResource(Resource.Drawable.splLogo);
Thread.Sleep(30000);
StartActivity(typeof(MainActivity));
}
}
Actualy my splash screen waiting stopping for some time but ImageView is not showing it come out at the last moment when new activity is going to start.
Why is this happening ? any help is appreciated :)
problem:
Thread.Sleep(30000);
It is not showing because you are blocking your UI thread to process the SetContentView to display in the screen thus it is not showing.
What it is really doing is that it will wait for 30 second without the display/black screen and change activity.
Solution:
Use a timer or Handler instead of sleeping the thread.
I have created an android application which should run on my Android based phone. As soon as the application is installed on the phone it proceeds with the task it is designed for. I want that as application is installed it should first open a welcome page displaying information about the product and on clicking OK button it should proceed to it's task.
To do this you have to create a Splash Screen layout and associated activity. You have to use a Timer or Thread to handle it. First create a splash.xml file and also create an activity SplashActivity.java.
public class SplashActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash.xml);
Timer timer = new Timer();
timer.schedule(new TimerTask() {
#Override
public void run() {
startHomeActivity(); // start home after 3 seconds
}
}, 3000); // three seconds wait, you can change it
}
}
Hope it will help you.
Since you are very much new to android development, i suggest you to learn more on android from Android developer website, you will get all api level explanation with examples. And here the link to know step by step implementation of creating splash screen in you android application. Keep leaning, try to search from website, you will get plenty of references. :)
Well basically, I press a button, this opens up your default camera app by using the camera intent. After a picture is taken, it will save the things needed and redirect to another activity.
In this activity, I have an AsyncTask that can succesfully upload pictures. So what is my problem you may ask. My problem is that it re-creates my activity and therefore reset my ProgressDialog together with it. ( It runs the activity, does the aSyncTask, dies before it can finish it and re-creates my Activity to do the asynctask once again. )
It does not always do this. I think it does this because it changes the Orientation from the phone from Landscape to Portrait. ( I have a Samsung. When I go to the Camera it changes to landscape and when I finish it, it goes back to portrait. )
I've already done my homework and added these things to my manifest:
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait" >
I've made sure to "lock" my app in the portrait orientation but I still see my app change orientation and I believe this is why my activity gets re-created.
I was planning to add all kinds of checks but I believe this is not the right way to handle this situation, since it sometimes does not re-create the activity.
The check I am talking about is to use:
protected void onSaveInstanceState(Bundle outState) {
outState.putString("started", "1");
}
Anyway, can somebody help me out? I just want it to load the activity without it self-destructing on me.
PS: The VM doesn't have any problems. The VM loads the activity and finishes it without re-creating it.
PPS: Did extra testing, on my Samsung if I keep it on landscape-mode it will work. So it is definately the camera that is destroying my activity with it's orientation change.
I had the same issue, turns out you also need to listen for screen size changes in API level 13 or higher as explained here; https://stackoverflow.com/a/11483806
android:configChanges="orientation|screenSize"
For this to fix, I had to use following in my manifest file:
android:screenOrientation="portrait"
android:launchMode="singleTop"
android:configChanges="keyboardHidden|orientation|screenSize"
Try creating a fragment activity to handle displaying and updating the progress dialog
In the fragment activity make sure and set "setRetainInstance(true);" This will make sure it isn't destroyed when the main activity gets created/destroyed.
It's probably a good idea to put the entire image capture process inside this fragment, including the asynctask. Make sure you don't reference the parent activity's context from within the doInBackground() in the AsyncTask. If you do this and the orientation changes (i.e. the activity is destroyed) it will throw an error.
here's a rough example:
public class MyFragment extends FragmentActivity {
private ProgressBar mProgressBar;
private boolean mAsyncTaskActive = false;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);
// grab reference to progress bar
mProgressBar = (ProgressBar) getActivity().findViewById(R.id.my_progress_bar);
// check to see if the async task is active and set the progress bar visibility accordingly
if (mAsyncTaskActive) {
mProgressBar.setVisibility(View.VISIBLE);
mProgressBarText.setVisibility(View.VISIBLE);
}
}
// this method is called from your main activity when the user does something (i.e. clicks a button)
// make sure you have already instantiated the fragment
public void startSomething() {
if (mAsyncTaskActive == false) {
mProgressBar.setVisibility(View.VISIBLE);
new MyAsyncTask().execute();
mAsyncTaskActive = true;
}
}
private class MyAsyncTask extends AsyncTask<Void, Void, Void> {
Context applicationContext;
#Override
protected Void doInBackground(String... params) {
// do stuff
publishProgress(//some number);
return null;
}
#Override
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
}
You should also take a look at how to implement fragments if you're not already familiar. The Android dev blog has a good post on DialogFragments, same priniciples. http://android-developers.blogspot.com/2012/05/using-dialogfragments.html
Im working on a little game and having some issues.
There is the Menu
public void onClick(View arg0) {
// TODO Auto-generated method stub
switch (arg0.getId()){
case R.id.bStartGame:
Intent a = new Intent(Menu.this, Action.class);
startActivityForResult(a, 1);
break; }
then the activity which starts a surfaceview
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new GameView(this));
}
and then the the surfaceView with the game mechanics.
Most of my code is in this view.
Now I have the problem to find a good solution for the gameoverscreen.
If I start a new activity inside the surfaceview, it works - but i dont get the result() which is the score achieved during a session.
So now I wanted to ask you guys how to solve this issue.
I thought of a way, but dont know how to implement it.
It would be to pass the highscore from the surfaceview to the activity and set it as a result(which the menu activity gets back) there.
And start an xml file via dialog, which would be the gameoverscreen and as soon as the player touches the back button he gets back to the menu where he can see his achieved score.
Can you please tell me how to code this?
Kind regards
Denis
There's a number of ways to solve this:
-use startActivityForResult and then send it back from your new activity, catching it in the old activity using onActivityResult (check https://developer.android.com/reference/android/app/Activity.html)
-do what i did (the lazy, hacky way :): start the new activity with startActivity() and add the highscore as extra data added to the intent. In your new activity, use getIntent().getInt (ow whatever) to get the sent score data and do with it what you will. Then close that activity and you'll return to the previous one holding your surfaceview.
NOW THE TRICK: before you start your new activity with it's score added to the intent, just run the same score calculation in your surfaceview's activity as you would in your new activity! That way, when you return to your surfaceview's activity, you will still have the correct, new score (if stored/onresume'd correctly; don't forget to add it to your save/restore state and/oror the surfaceview's private variables)!
The only downside is that you'll have two location you have to update your scoring mechanics at. And it's not good programming. But it works and it's easy.
I have a simple application, it starts, loads xml feed from the net, you can browse a list of news and then read details for a chosen news item. What I would like to do is have a splash screen, meaning as soon as you click application, it should display an image (app name in my case) and then display news list only after they've loaded.
I read about similar (I think) problems, and usually people say to use FrameLayout, but I can't really sort it out. I'm not sure if this can be done in the first activity that is launched, maybe I should just display this splash image in one activity and only then call activity displaying my news list?
I know that on iPhone you can set splash screen in app settings while developing, would be nice to have this functionality in android's app's manifest...
Android suggests you take advantage of using a splash screen when performing lengthy calculations on start up. Here's an excerpt from the Android Developer Website - Designing for Responsiveness:
"If your application has a time-consuming initial setup phase, consider showing a splash screen or rendering the main view as quickly as possible and filling in the information asynchronously. In either case, you should indicate somehow that progress is being made, lest the user perceive that the application is frozen." -- Android Developer Site
You can create an activity that shows a Progress Dialog while using an AsyncTask to download the xml feed from the net, parse it, store it to a db (if needed) and then start the Activity that displays the News Feeds. Close the splash Activity by calling finish()
Here's a skeleton code:
public class SplashScreen extends Activity{
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
// set the content view for your splash screen you defined in an xml file
setContentView(R.layout.splashscreen);
// perform other stuff you need to do
// execute your xml news feed loader
new AsyncLoadXMLFeed().execute();
}
private class AsyncLoadXMLFeed extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute(){
// show your progress dialog
}
#Override
protected Void doInBackground(Void... voids){
// load your xml feed asynchronously
}
#Override
protected void onPostExecute(Void params){
// dismiss your dialog
// launch your News activity
Intent intent = new Intent(SplashScreen.this, News.class);
startActivity(intent);
// close this activity
finish();
}
}
}
hope that helps!
I know this is old but for those of you who are still facing this problem, you can use this simple android-splash library to show your splash screen.
SplashBuilder
.with(this, savedInstanceState)
.show();
You can set SplashTask that will execute while the splash screen is displayed.