Is it possible to do splash screen that will execute HTTP request and if this request is executing too long, i.e. 7-10 seconds, then abort the request and jump to the main activity?
The below code is what I did, but it doesn't work - the timeout isn't working, the HTTP request and jumping are working. As I understand, it's possible to use the AsyncTask's get() method or handler with delay. Get() method should be in separate thread but it doesn't work. How to do this task?
EDIT:
public class SplashActivity extends Activity {
private static final String TAG = "SplashActivity";
private Handler handler = new Handler();
private Runnable r;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_layout);
if (Helpers.isNetworkConnected(getApplicationContext())) {
Log.d(TAG, "Has Internet");
final DownloadFAQ downloadFAQ = new DownloadFAQ();
new Thread(new Runnable() {
public void run() {
try {
Log.d(TAG, "Timing...");
downloadFAQ.execute().get(1000, TimeUnit.MILLISECONDS);
SplashActivity.this.runOnUiThread(new Runnable() {
public void run() {
Log.d(TAG, "redirect");
redirect();
}
});
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
downloadFAQ.cancel(true);
Log.d(TAG, "Task has benn canceled");
if (downloadFAQ.isCancelled())
redirect();
}
}
}).start();
} else {
r = new Runnable() {
public void run() {
redirect();
}
};
handler.postDelayed(r, 2500);
}
}
private class DownloadFAQ extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
Log.d(TAG, "Execute task");
ServerAPI server = new ServerAPI(getApplicationContext());
server.serverRequest(ServerAPI.GET_FAQ, null);
return null;
}
}
private void redirect() {
Intent i = new Intent(SplashActivity.this, TabsActivity.class);
startActivity(i);
finish();
}
#Override
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacks(r);
}
}
because you are trying to start AsyncTask again inside doInBackground when it's still running . change your code as to get it work :
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.splash_layout);
downloadFAQ = new DownloadFAQ();
new Thread(new Runnable() {
public void run() {
try {
downloadFAQ.execute().get(2000, TimeUnit.MILLISECONDS);
SplashActivity.thisrunOnUiThread(new Runnable() {
public void run() {
// start Activity here
Intent i = new Intent(SplashActivity.this,
TabsActivity.class);
SplashActivity.this.startActivity(i);
SplashActivity.this.finish();
}
});
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
and you will need to remove downloadFAQ.get(2000, TimeUnit.MILLISECONDS); from doInBackground method change your AsyncTask as
private class DownloadFAQ extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
ServerAPI server = new ServerAPI(getApplicationContext());
server.serverRequest(ServerAPI.GET_FAQ, null);
return null;
}
protected void onPostExecute(Void result) {
}
}
consider using asyncTask status:
AsyncTask.Status
Related
I have tried updating my user interface using the text view what i have done is a run a while loop indefinitely and left the thread for sleep for one second..
int i;
while(true)
{
Thread.Sleep(1000);
textView.setText(updateTime);
}
Use runOnUiThread and surround with try catch for Thread.sleep(1000)
int i;
while(true)
{
try {
Thread.sleep(1000);
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
textView.setText(updateTime);
}
});
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Try this one arnab...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView textView = (TextView) findViewById(R.id.displayid);
handler = new Handler() {
#Override
public void handleMessage(Message msg) {
bundle = msg.getData();
textView.setText(bundle.getString("mKey"));
}
};
}
public void press(View v) {
new Thread(new Runnable() {
#Override
public void run() {
while (true) {
synchronized (this) {
try {
wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
bundle = new Bundle();
message = handler.obtainMessage();
simpleDateFormat = new SimpleDateFormat("hh:mm:ss YYYY/mm/dd", Locale.US);
date = simpleDateFormat.format(new Date());
bundle.putString("mKey", date);
message.setData(bundle);
handler.sendMessage(message);
}
}
}
}).start();
}
Try runOnUiThread:
runOnUiThread(new Runnable() {
#Override
public void run() {
textView.setText(updateTime);
}
});
After recieving a pictures from user, putting them in an array, animate() method is called from main, this method contains Asynktask. How can I finish this AsyncTask?
This is my code:
private void animate() {
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(1000);
runOnUiThread(new Runnable() {
#Override
public void run() {
iv.setImageResource(pics[0]);
}
});
} catch (Exception ex) {
ex.printStackTrace();
}
while (true) {
try {
Thread.sleep(500);
runOnUiThread(new Runnable() {
#Override
public void run() {
iv.setImageResource(pics[pos]);
pos = (pos + 1);
}
});
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
}.execute();
}
From your code, I guess what you want is to change the image you show in an ImageView periodically. I'd suggest to change your code to use a Timer:
private Timer mTimer;
private void startCarousel(){
mTimer = new Timer();
TimerTask timerTask = new TimerTask() {
public void run() {
// Your periodic task...
}
};
mTimer.schedule(timerTask, 1000, 500);
}
private void stopCarousel(){
if(mTimer != null){
mTimer.cancel();
mTimer.purge();
}
}
I have this thread wating for onTouchEvent()
private Runnable disconnectCallback = new Runnable() {
#Override
public void run() {
// Perform any required operation on disconnect
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Toast.makeText(getBaseContext(),"Your session expired Please Login again",Toast.LENGTH_SHORT).show();
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
final Logout l=new Logout();
l.setContext(Ac2.this);// passing context of Ac3.java to Logout.java
l.execute(sessid,uname);
}
});
}
};
what i want is notify this waiting thread when user touches a mobile screen..
private Runnable disconnectCallback = new Runnable() {
#Override
public void run() {
// Perform any required operation on disconnect
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Toast.makeText(getBaseContext(),
"Your session expired Please Login again",
Toast.LENGTH_SHORT).show();
try {
synchronized (disconnectCallback) {
disconnectCallback.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
final Logout l = new Logout();
l.setContext(Ac2.this);// passing context of Ac3.java to
// Logout.java
l.execute(sessid, uname);
}
});
}
};
and in onTouch event call:
disconnectCallback.notifyAll();
Try this
private Runnable disconnectCallback = new Runnable() {
#Override
public void run() {
// Perform any required operation on disconnect
runOnUiThread(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Toast.makeText(getBaseContext(),
"Your session expired Please Login again",
Toast.LENGTH_SHORT).show();
}
});
try {
synchronized(disconnectCallback){
disconnectCallback.wait();
final Logout l=new Logout();
l.setContext(Ac2.this);// passing context of Ac3.java to Logout.java
l.execute(sessid,uname);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Inside onTouch
synchronized (disconnectCallback) {
disconnectCallback.notify();
}
I have a BroadcastReceiver.
There I create a new Thread.
How can I show a toast in that thread?
Thanks
Use below code for perform UI operation from non-UI thread
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
// your stuff to update the UI
}
});
Try This code
public void start_insert() {
pDialog.show();
new Thread() {
#Override
public void run() {
int what = 0;
try {
// Do Something in Background
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
what = 1;
e.printStackTrace();
}
handler22.sendMessage(handler22.obtainMessage(what));
}
}.start();
}
private Handler handler22 = new Handler() {
#Override
public void handleMessage(Message msg) {
pDialog.dismiss();
Toast.makeText(getApplicationContext(), "SuccessFull",
10).show();
}
};
Activity_Name.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// your stuff to update the UI
}
});
Use this code to update UI thread or execute any UI related operation.
When using a wait in an AsyncTask, I get ERROR/AndroidRuntime(24230): Caused by: java.lang.IllegalMonitorStateException: object not locked by thread before wait()
Is it possible to use an Asynctask just for waiting? How?
Thanks
class WaitSplash extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... params) {
try {
wait(MIN_SPLASH_DURATION);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
protected void onPostExecute() {
waitSplashFinished = true;
finished();
}
}
Use Thread.sleep() instead of wait().
You can use Thread.sleep method
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
try {
Thread.currentThread();
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
If you're looking to just postpone execution of a method for a set amount of time, a good option is Handler.postDelayed()
define the handler and runnable...
private Handler handler = new Handler();
private Runnable runnable = new Runnable() {
finished();
};
and execute with delay...
handler.postDelayed(runnable, MIN_SPLASH_DURATION);
Use threads for this
public class SplashActivity extends Activity{
int splashTime = 5000;
private Thread splashThread;
private Context mContext;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.mContext = this;
setContentView(R.layout.splash_layout);
splashThread = new Thread(){
public void run() {
try{
synchronized (this) {
wait(splashTime);
}
}catch(InterruptedException ex){
ex.printStackTrace();
}finally{
Intent i = new Intent(mContext,LocationDemo.class);
startActivity(i);
stop();
}
}
};
splashThread.start();
}
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
synchronized (splashThread) {
splashThread.notifyAll();
}
}
return true;
}
on touch event, thread get notified.. can change according to your need.
You have this way to work with asyntask and wait();
public class yourAsynctask extends AsyncTask<Void, Void, Void> {
public boolean inWait;
public boolean stopWork;
#Override
protected void onPreExecute() {
inWait = false;
stopWork = false;
}
#Override
protected Void doInBackground(Void... params) {
synchronized (this) {
while(true) {
if(stopWork) return null;
if(youHaveWork) {
//make some
} else {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
return null;
}
public void mynotify() {
synchronized (this) {
if(inWait) {
notify();
inWait = false;
}
}
}
public void setStopWork() {
synchronized (this) {
stopWork = false;
if(inWait) {
notify();
inWait = false;
}
}
}
}