I have 2 methods in onCreate which I need to run one after the other ie...the second method will start once the first method is complete irrespective of how much time it takes.Please help me.
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
populateList();
// close this activity
//finish();
}
}, 20000);getContactList();
populateList() method
** public void populateList() {
Log.i("Populate List","Entered");
Toast.makeText(this,String.valueOf(Common.selectedContactNos.size()),Toast.LENGTH_LONG).show();
displayRecyclerAdapter = new DisplayRecyclerAdapter(DisplayContacts.this);
LinearLayoutManager mLinearLayoutManager = new LinearLayoutManager(this);
recyclerView_contacts.setAdapter(displayRecyclerAdapter);
recyclerView_contacts.setLayoutManager(mLinearLayoutManager);
displayRecyclerAdapter.notifyDataSetChanged();
}**
just use AsyncTask
call TaskOne class like-
new TaskOne().execute();
private class TaskOne extends AsyncTask<Void,Void,Void>
{
#Override
protected Void doInBackground(Void... params) {
getContactList();
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
populateList();
}
}
Call both method inside run method with the sequence you want. Replace your code with below code
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
populateList();
getContactList();
// close this activity
//finish();
}
}, 20000);
Related
In the onCreate() method of my activity I have a Timer + TimerTask that will schedule a ParseQuery. On The ParseQuery callback, which is on mainThread, I delegate an interface callback to make a simple UI update. This works when I let the Activity unchanged. But if I exit from the activity and enter again it (A new timer will NOT be created here, because it gets created only when starting the activity from a certain point) wouldn't work. I think is something with Activity instances but I cannot handle it.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
....
uiTimer = new Timer();
uiTask = new TimerTask() {
#Override
public void run() {
doParseTask();
}
};
uiTimer.schedule(uiTask, shortCodeLeft);
}
doParseTask(){
Utils.doParseQuery(this, new MyListener{
#Override
public void onSuccess() {
updateUI();
}
});
}
updateUI(){
Log.i(TAG, "Show changed layout"); //This is always shown, this way I ensure it gets here!!
mTextView.setText(foo); //this doesn't work
mLayout.setVisibility(View.GONE); //this doesn't work
}
The ParseQuery is executed in done() callback method, I call the function that updates the UI:
public class Utils{
.......
doParseQuery(Context ctx, MyListener listener){
.......
query.saveInBackground(new SaveCallback() {
#Override
public void done(ParseException e) {
if(e == null){
....
listener.onSuccess();
}
}
});
}
}
What I have tried, with no success:
1. make the `uiTimer` and `uiTask` static global variables; // I thought that maybe it gets leaked into activity instances
2. update the UI using
runOnUiThread(new Runnable() {
#Override
public void run() {}
});
OR
mLayout.post(new Runnable() {
#Override
public void run() {
mLayout.setVisibility(View.GONE);
}
});
3. android:launchMode= "singleInstance" //in Manifest
If you want that your UITimer to gets executed every time your activity goes to foreground, you should implement the onStart or onResume method and move your uiTimer implementation to one of both method. Even your activity being already started these two methods are called after exiting the activity and reopening it again.
A better explanation of Android Activity lifecycle is well explained by google documentation https://developer.android.com/guide/components/activities/activity-lifecycle.html.
Your code would look like this:
#Override
protected void onStart() {
super.onStart();
....
uiTimer = new Timer();
uiTask = new TimerTask() {
#Override
public void run() {
doParseTask();
}
};
uiTimer.schedule(uiTask, shortCodeLeft);
}
doParseTask(){
Utils.doParseQuery(this, new MyListener{
#Override
public void onSuccess() {
updateUI();
}
});
}
When you exit from your activity, the instances mTextView and mLayout will be destroyed.
Then, when you create a new activity, the activity creates new instances of the text view and layout.
Your timer goes off and tries to update the original elements, which are now invalid as the activity has been closed (but the log still works as this is separate to your activity).
You should initialise the timer & task in onCreate(), and then in order to stop updating the old UI elements:
#Override
protected void onStop() {
if (uiTimer != null) {
uiTimer.cancel();
}
super.onStop();
}
I have an AsyncTask inside a fragment, which is being executed every second using a Timer. The AsyncTask loads data into a ListView, and when the user clicks on a ListView item, it switches to another fragment.
The timer doesn't stop, so it keeps executing itself and finally, gives me an error when it tries to load the data into the ListView.
I already tried looking for answers, and have implemented those in my code-
class HttpGetAsyncTask extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected void onCancelled() {
Log.d("PORTS Cancelled","cancelled");
}
#Override
protected String doInBackground(String... q) {
String v = null, c = null;
for(int countervar=0;countervar<1;countervar++){
if(load.isCancelled())
break;
//All my code here
}
return c;
}
protected void onPostExecute(String result) {
if(isCancelled()||!isAdded()){
return;
}
else{
SimpleAdapter adapter = new SimpleAdapter(getActivity(),
ports, R.layout.playout, new String[] { "name",
"code", "type" }, new int[] { R.id.portn, R.id.portc,
R.id.portv });
adapter.notifyDataSetChanged();
lv.setAdapter(adapter);
}
}
}
#Override
public void onPause() {
super.onPause();
timer.cancel(); //timer is the name of the Timer
doAsynchronousTask.cancel(); //doAsynchronousTask is the TimerTask
if(load!=null) //load is the AsyncTask
if(!load.isCancelled())
load.cancel(true);
}
#Override
public void onDestroy() {
super.onDestroy();
timer.cancel();
doAsynchronousTask.cancel();
if(load!=null)
if(!load.isCancelled())
load.cancel(true);
}
The timer (Called in onCreateView)-
handler = new Handler();
doAsynchronousTask = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
load = new HttpGetAsyncTask();
load.execute();
} catch (Exception e) {
// TODO Auto-generated catch block
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 10000);
Please let me know where I'm going wrong and what I can do to fix this problem. Thanks.
When the doAsynchronousTask task is scheduled the load variable is replaced with a new HttpGetAsyncTask. So more than one AsyncTask can run a the same time, and when you stop the task, calling:
load.cancel(true);,
you are only cancelling the AsyncTask referenced by load variable, but others tasks can continue to work in backgroud (without any handle for stopping them).
A solution can be, to stop the AsyncTask before start another one.
What about adding a boolean flag in the loop as the condition controlling the loop?
Then you can set it to false to stop the task in onPause()
I am trying to implement an app in which I have to initially download a file, and only then can I proceed. So I don't want to make the screen idle for N number of seconds for the duration of downloads, I want to cover it with a splash screen. So basically downloading all the files, and it will be covered by the splash activity.
This is the code I generally use for splash activity, then jumping to the main activity after the delay.
The real problem is that I have the AsyncTask in the main_activity, I want to show the splash screen, while I can download the file in the AsyncTask . Then I can move to the main activity
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
Intent i = new Intent(Splash_Screen.this, MainActivity.class);
startActivity(i);
// close this activity
finish();
}
}, 3000);
}
I recommande you to choose the AsyncTask, where you can do a task in the backGround in your example downloading the file, and in the post execution wich mean after your file is downloaded you can do what ever you want.
private class Asyn_DownLoadFile extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
//download your file here
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
/*this function is called automatically by the doInBackground when
it finish it's work*/
}
}
Just remenber AsyncTask must be subClassed, that's mean call implement the AsyncTask in the Splash screen Activity and in the onPostExecution do what you want
to start the AsyncTask use
new Asyn_DownLoadFile().execute(null,null,null);
EDIT:
here what you have to do:
suppose this your Splash class
public class SplashActivity extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
context = this;
//.......................
new Asyn_DownLoadFile().execute(null,null,null);
}
//this is your function that downLoad the file
public void downLoadFile(){
//............................
}
private class Asyn_DownLoadFile extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
downLoadFile();
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
Intent i = new Intent (context, MainActivity.class)
startActivity(i);
}
}
}
I'm making an activity where I'm planning to display a progress bar and move to a second activity after five seconds. I used Thread.sleep to do this.
Here is the code for the activity with the spinner.
public class WaitScreen extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.waitscreen);
}
#Override
public void onStart() {
// TODO Auto-generated method stub
super.onStart();
try{
for(int i=0;i<5;i++){
Thread.sleep(1000);
}
Toast.makeText(getApplicationContext(), "Spinner complete!", Toast.LENGTH_LONG).show();
}
catch(InterruptedException e){
}
Intent i = new Intent("emergency.app.NEWACTIVITY");
startActivity(i);
}
}
My main activity only has a button that leads to this page on being clicked. Problem is, it displays the main activity for five seconds, then this activity very briefly and then the third activity. How do I make the thread start after WaitScreen is fully loaded? As you can see, I tried using the onStart method to do the trick. Or if you could tell me another way to introduce a five second delay, that would be helpful too!
Use a Handler to post a Runnable, like so:
public class WaitScreen extends Activity {
private Runnable task = new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "Spinner complete!", Toast.LENGTH_LONG).show();
Intent i = new Intent("emergency.app.NEWACTIVITY");
startActivity(i);
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.waitscreen);
Handler handler = new Handler();
handler.postDelayed(task, 5000);
}
}
The Runnable task will execute after 5 seconds.
http://developer.android.com/reference/android/os/Handler.html
My application fetches some html code from the internet and when done , displays it on the devices screen. Since it takes about 3-4 seconds to do that , in this time the screen stays black , I'd like to use a progress dialog. This is my code :
package com.nextlogic.golfnews;
// ALL THE IMPORTS ....
public class Activity1 extends Activity {
private ProgressDialog progressDialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main2);
progressDialog = ProgressDialog.show(Activity1.this, "", "Loading...");
new Thread()
{
public void run()
{
try
{
sleep(2000);
// HERE I'VE PUT ALL THE FUNCTIONS THAT WORK FOR ME
}
catch (Exception e)
{
Log.e("tag",e.getMessage());
}
// dismiss the progressdialog
progressDialog.dismiss();
}
}.start();
The program works but it doesn't display anything anymore. I have one error in logcat :
Only the original thread that created a view hierarchy can touch its views.
Could you please help me ? Thanks in advance.
The error is explicative enough. To update one visual object you must run the changes inside main thread. A quick and dirty fix could be calling the update code inside runOnUiThread().
However in your case I would use an AsyncTask to download and update the progress of the progress bar. The task has the property to run on UI thread when it ends (so you can update the views there, such as dismissing the progress dialog)
Here is an example how to use an AsyncTask to display a download progress dialog.
Update
Stackoverflow already has the answers to all your question. Here is an example of an AsyncTask to download some content and display the download progress. Just what you want.
Update 2
Ok here is your code using an AsyncTask:
public class Activity1 extends Activity
{
private ProgressDialog progressDialog;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new AsyncTask<Integer, Integer, Boolean>()
{
ProgressDialog progressDialog;
#Override
protected void onPreExecute()
{
/*
* This is executed on UI thread before doInBackground(). It is
* the perfect place to show the progress dialog.
*/
progressDialog = ProgressDialog.show(Activity1.this, "",
"Loading...");
}
#Override
protected Boolean doInBackground(Integer... params)
{
if (params == null)
{
return false;
}
try
{
/*
* This is run on a background thread, so we can sleep here
* or do whatever we want without blocking UI thread. A more
* advanced use would download chunks of fixed size and call
* publishProgress();
*/
Thread.sleep(params[0]);
// HERE I'VE PUT ALL THE FUNCTIONS THAT WORK FOR ME
}
catch (Exception e)
{
Log.e("tag", e.getMessage());
/*
* The task failed
*/
return false;
}
/*
* The task succeeded
*/
return true;
}
#Override
protected void onPostExecute(Boolean result)
{
progressDialog.dismiss();
/*
* Update here your view objects with content from download. It
* is save to dismiss dialogs, update views, etc., since we are
* working on UI thread.
*/
AlertDialog.Builder b = new AlertDialog.Builder(Activity1.this);
b.setTitle(android.R.string.dialog_alert_title);
if (result)
{
b.setMessage("Download succeeded");
}
else
{
b.setMessage("Download failed");
}
b.setPositiveButton(getString(android.R.string.ok),
new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dlg, int arg1)
{
dlg.dismiss();
}
});
b.create().show();
}
}.execute(2000);
new Thread()
{
#Override
public void run()
{
// dismiss the progressdialog
progressDialog.dismiss();
}
}.start();
}
}
You need to do this way
runOnUiThread(new Runnable() {
public void run() {
// Do Your Stuff
}});
Dismiss your dialog like this:
Handler handler = new Handler();
handler.post(new Runnable(){
public void run(){
progressDialog.dismiss();
}
});
Create a UI thread after completing network operation
runOnUiThread(new Runnable() {
#Override
public void run() {
progressDialog.dismiss();
}
});
The top answer works great, so here is an example to implement an AsyncTask in MonoDroid (thanks to Greg Shackels): http://mono-for-android.1047100.n5.nabble.com/AsyncTask-td4346647.html