How to change the main task between two activities? - java

I'm so begineer level of Android.. so I need you guy's advice..
I have two activities
A -> MainActivity
B -> LoadingActivity
My problem is,
when I execute my application, firstly, A is started and it takes 4 seconds to do database task.. So I thought it would be better to make another activity just for showing loading page..
So in the MainActivity, I wrote this code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startActivity(new Intent(this, LoadingActivity.class)); <-- this
setContentView(R.layout.activity_main);
What I intended is, the LoadingActivity should be started, before this MainActivity is started, so that LoadingActivity shows the loading image on the screen for 4 seconds to cover MainActivity database task.
So, my intended sequence is,
B(show up on screen for 4sec) -> A(started almost same with B, working behind the B activity screen) -> B is killed (call finish() method) -> than, use the app.
please, give any advice, would be very appreciate..
And, here is my LoadingActivity class code..
public class LoadingActivity extends FragmentActivity{
private static int SPLASH_TIME_OUT = 6000;
private String tag = "LoadingSplash";
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.start_up);
String localUrl ="file:///android_asset/loading_gif.gif";
WebView wv=(WebView) findViewById(R.id.startup);
//wv.getSettings().setJavaScriptEnabled(true);
wv.getSettings().setPluginState(PluginState.ON);
//wv.getSettings().setAllowFileAccess(true);
Log.i(tag, "WebView get Setting finish....");
wv.setPadding(0, 0, 0, 0);
wv.setInitialScale(getScale());
//wv.getSettings().setLoadWithOverviewMode(true);
//wv.getSettings().setUseWideViewPort(true);
wv.loadUrl(localUrl);
new Handler().postDelayed(new Runnable() {
/*
* Showing splash screen with a timer. This will be useful when you
* want to show case your app logo / company
*/
#Override
public void run() {
// This method will be executed once the timer is over
// Start your app main activity
Log.i(tag, "Here is Runnable Method...");
finish();
}
}, SPLASH_TIME_OUT);
#SuppressLint("NewApi")
private int getScale(){
Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
Point p = new Point();
display.getSize(p);
int width = p.x;
Double val = new Double(width)/new Double(800);
val = val * 100d;
return val.intValue();
}
}

You don't need two separate activities, you can execute an AsyncTask thread to do your database works and in "onPreExecute" method of AsyncTask class start to show your "desired custom view"(probably containing progressBar) and do your stuff in "doInBackground" method and in "onPost" method of AsyncTask class just set that "desired custom view"'s visibility to Gone.
Hope this works.

you can use Asynctask For Background processing. After Processing complete you can start next activity.You Should use progress dialog on async task :)
if you are not understanding then u can ask to me...
Regards
Asim

Related

How to write code between onCreate and onStart?

Several times I've had problems writing code on onCreate(). Mostly because the UI has not been sized and laid out on the screen yet (even if I place my code at the end of the function). I've looked over the activity life-cycle to see if there's anything that runs after onCreate(). There is onStart(), but the problem is that onRestart() recalls onStart(), I don't want that. So is there a way to write code between onCreate() and onStart()? OR where should I write code that runs after the UI is placed and only runs once during its process?
Not sure what exactly you need but you can "cheat" and simply store whether you have run code or not:
private boolean mInit = false;
void onStart() {
if (!mInit) {
mInit = true;
// do one time init
}
// remaining regular onStart code
}
The other way of running code when UI is placed is to use the global layout listener:
public class FooActivity extends Activity implements ViewTreeObserver.OnGlobalLayoutListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_content);
View content = findViewById(android.R.id.content);
content.getViewTreeObserver().addOnGlobalLayoutListener(this);
}
#Override
public void onGlobalLayout() {
// unregister directly, just interested once.
View content = findViewById(android.R.id.content);
content.getViewTreeObserver().removeOnGlobalLayoutListener(this);
// do things here.
}
}

Call a method when fragment is visible to user

I need execute a method when the fragment is visible (to the user).
Example:
I have 2 buttons (button 1 and button 2) ,
2 fragments(fragment 1 and fragment 2)
and the method loadImages() inside the class fragment 2.
when I press "button2" I want to replace fragment 1 by fragment 2
and then after the fragment 2 is visible (to the user) call loadImages().
I tried to use onResume() in the fragment class but it calls the method before the fragment is visible and it makes some delay to the transition.
I tried setUserVisibleHint() too and did not work.
A good example is the Instagram app. when you click on profile it loads the profile activity first and then import all the images.
I hope someone can help me. I will appreciate your help so much. Thank you.
Use the ViewTreeObserver callbacks:
#Override
public void onViewCreated(View v, Bundle savedInstanceState) {
super.onViewCreated(v, savedInstanceState);
final View view = v;
// Add a callback to be invoked when the view is drawn
view.getViewTreeObserver().addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
#Override
public void onDraw() {
// Immediately detach the listener so it only is called once
view.getViewTreeObserver().removeOnDrawListener(this);
// You're visible! Do your stuff.
loadImages();
}
});
}
I'm a little confused by what you are trying to do. It sounds like the images are loading too fast for you... so does that mean that you have the images ready to display? And that is a bad thing?
My guess (and this is just a guess) is that Instagram does not have the profile pictures in memory, so they have to make an API call to retrieve them, which is why they show up on a delay. If the same is the case for you, consider starting an AsyncTask in the onResume method of the fragment. Do whatever loading you need to do for the images in the background, and then make the images appear in the onPostExecute callback on the main thread. Make sure you only start the task if the images are not already loaded.
However, if you already have the images loaded in memory, and you just want a delay before they appear to the user, then you can do a postDelayed method on Handler. Something like this:
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
loadImages();
}
}, 1000);
Edit
As kcoppock points out, the handler code is pretty bad. I meant it to be a quick example, but it is so wrong I should not have included it in the first place. A more complete answer would be:
private Handler handler;
public void onResume(){
super.onResume();
if(handler == null){
handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
loadImages();
}
}, 1000);
}
}
public void onDestroyView(){
super.onDestroyView();
handler.removeCallbacksAndMessages(null);
handler = null;
}
Use the onActivityCreated() callBck

android async splash screen not showing content view

in my app the main page contains, quite a few images to load on my upload manager activity so it can take a few seconds, depending on how many images there are. i planned on creating a splashscreen to do this loading while displaying an image which is not as bad as the default blank screen with title. i have done this, which should work and does, except the setcontentview() does run but does not display.
public class SplashScreen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_screen);
load l=new load();
l.execute(this);
}
class load extends AsyncTask<Activity, Object, Object>{
#Override
protected Object doInBackground(Activity... a) {
// TODO Auto-generated method stub
Log.i("ss", "splash");
Intent intent = new Intent(a[0], UploadManager.class);
startActivity(intent);
a[0].finish();
return null;
}
}
}
does anybody have any suggestions?
and feel free to ask for details i don't think i have explained it all too well.
edit:
thank you guys for the quick responses.
however i believe the problem was that i wasn't using a splash screen for the correct purpose,
the processes involved in:
Intent intent = new Intent(a[0], UploadManager.class);
startActivity(intent);
a[0].finish();
seem to finish instantly, meaning the images in my onCreate method weren't executing until after the splash screen. what i did instead is changed the loading of my grid into an asynktask, as apposed to just doing my images in there.
i now have it loading fast with the images appearing after a few seconds. i shall be implementing a progress dialog of some sort.
anyone else with a similar problem should prioritize making the loading more efficient as i have.
You are passing Context as this in l.execute(this) and in class load you've passed Activity instance.
You can do it in this way and it works like a charm for me
public class SplashScreen extends Activity{
private static int SLPASH_TIME_OUT = 3000;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Intent i = new Intent(SplashScreen.this, MainActivity.class);
startActivity(i);
finish();
}
}, SLPASH_TIME_OUT);
}
}
Override onPostExecute method in class load extends AsyncTask<Activity, Object, Object>{ class, which will run when your doInBackground method finishs image downloading.
In onPostExecute you can open your next activity
like
protected void onPostExecute(Void unused) {
Intent intent= new Intent(this, next.class);
startActivity(intent);
}

add progress spinner to app boolean

In my code i have a boolean to install information to the database via preference. It works fine but the issue is now that have alot of information to add to the app and i get a black screen while the information is being added to the sqlite (only during installation). How can i add a progress spinner so the users will know the app is in the installation process. I am afraid they will think the app is broken when they stare at the black screen.
/** Insert list into db once */
if (pref.getBoolean("isFirst", true)) {
readBLContactsfromAssetsXMLToDB("list.xml");
pref.edit().putBoolean("isFirst", false).commit();
}
addQuickActions();
}
First you may use AsyncTask for doing processes that take long time. If you are not aware of it, it allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
But if you insist not to use that, then since you are blocking the UI thread, you cannot show the dialog and do your stuff at the same time. You need to have a background thread for the lengthy process, and show the progress dialog on the UI thread.
There are lots of examples of AsyncTaks online. Just for sample:
private class OuterClass extend Activity{
//....
#Override
public void onCreate(Bundle savedInstanceState) {
new performBackgroundTask ().execute();
}
//....
private class performBackgroundTask extends AsyncTask < Void, Void, Void >
{
private ProgressDialog dia;
// This method runs in UI thread before the background process starts.
#Override
protected void onPreExecute(){
// Show dialog
dia = new ProgressDialog(OuterClass.this);
dia.setMessage("Installing...");
dia.show();
}
#Override
protected Void doInBackground(Void... params) {
// Do all the stuff here ...
addQuickActions();
}
// Ececutes in UI thread after the long background process has finished
#Override
protected void onPostExecute(Void result){
// Dismiss dialog
dia.dismiss();
}
}
}
You may see How to display progress dialog before starting an activity in Android?
Hope this helps.

Best way to implement "check if app comes from background" in android

I have been reading the answers in other post about this topic, but i have not found what is the best of all the approaches.
This is my approach i have now, but i do not know if it worst all the time (as far as i tested every worked for my) or if there is a better way.
public class FatherClass extends Activity {
private static int activities = 0;
public void onCreate(Bundle savedInstanceState, String clase) {
super.onCreate(savedInstanceState);
}
protected void onRestart()
{
super.onRestart();
if(activities == 0){
Log.i("APP","BACK FROM BACKGROUND");
}
}
protected void onStop(){
super.onStop();
activities = activities - 1;
}
protected void onStart(){
super.onStart();
activities = activities + 1;
}
}
Explanation: the onStart is executed one the activity is "visible" and the onStop when the activity is "not visible". So when your APP (it says APP not activity) goes to background all the activities are "not visible" so they execute the onStop method, so the idea behind this is to add one each time an activity es started, and subtract one each time an activity es hided, so if the value of the variable "activities" is 0 "zero" that means that all the activities that where started in some point are now not visible, so when you APP returns from background and executes the onRestart method on the activity in "front" you can check whether comes from background or is just restarting an activity.
I would appreciate some feedback regarding this topic.

Categories

Resources