I am popping up a dialog from an Application context by calling an intent which has a transparent theme.(Similar to what is mentioned here.)
The pop is a read only.The issue is that when the pop up is shown there is a current activity going on in the background. I need to be able to access the background activity too while the popup is dispalyed. I have added the following two lines but it still is not possible for me to control the underlying activity:
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
What am I doing wrong?
you must open the dialog in a thread, you haven't explained much about what you want to do in background ,but for making a thread do this:
create a new class with name:thread1 then write down these there:
public class thread1 extends Thread {
MainActivity activity;
public thread1(MainActivity m){
activity=m;
ProgressDialog pd;
//other code maybe for specification
pd=ProgressDialog.show(activity,"", "wait for background activity");
}
#Override
public void run(){
//you code working in background here like:
activity.sucess=0;
while (activity.sucess==0){
android.os.SystemClock.sleep(300);
}
pd.dismiss();
}
}
whenever you want to open this pb you should write this,
thread1 t1=new thread1(this);
t1.start();
and when ever your work is done and you want to close the pb, you must set sucess=1 then the thread will be killed.
Related
I have an android app connected to a servlet. If the servlet is down (happened to me yesterday) the app crashes. I need to pop up a message to the user informing about some connection issues and then terminate the application.
on onCreate() method, i call an AsyncTask class, in which is done the first connection to the server. I have a try/catch(UnknownHostException e) block, which is activated if the sevlet is down.
The problem is that i cant create a pop up message there. I tried toast and AllertDialogs, but both return an exception
Java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Is there some other way i can do this? Thanks in advance, ilias
You could set a boolean and read it after the function call, at which point you should be able to show a toast/dialog. But that's hard to say without the rest of the code.
Your AsyncTask is running in a background thread. Calls to show a Toast or a Dialog must be made on the main (UI) thread. To do this from within an AsyncTask you can do this:
You'll need an activity context in your AsyncTask, so have your activity create your AsyncTask like this:
MyAsyncTask task = new MyAsyncTask(this, ...); // pass "this" so AsyncTask has an activity context
In your AsyncTask constructor, save the activity context so you can use it later:
private Activity activity;
// Constructor
MyAsyncTask(Activity activity, ...) {
this.activity = activity;
...
}
When you want to show a Dialog or a Toast, make sure the code runs on the main (UI) thread:
// Here we want to Toast
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
// Do your Toast or Dialog stuff in here
...
}
});
I am a beginner to Android and I have some confusions regarding Android UI Thread. Now, I know that no thread apart from the one that created the UI can modify it.
Great.
Here is the Activity from my first Android app which slightly confuses me.
public class NasaDailyImage extends Activity{
public ProgressDialog modalDialog = null;
//------------------------------------------------------------------------------
#Override
protected void onCreate(Bundle savedInstanceState){
//Instantiate progress dialog, skipping details.
Button b = //get reference to button
b.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
modalDialog.show(); // show modal
Toast.makeText(getApplicationContext(), "Getting feeds", 500).show();
new AsyncRetriever().execute(new IotdHandler()); // Get the feeds !!
}
});
}
//------------------------------------------------------------------------------
public synchronized void resetDisplay(boolean parseErrorOccured,
boolean imageErrorOccured,
IotdHandler newFeeds){
if(parseErrorOccured || imageErrorOccured){
// make a Toast
// do not update display
}else{
// make a Toast
// update display
// based on new feed
}
}
//------------------------------------------------------------------------------
class AsyncRetriever extends AsyncTask<IotdHandler,Void,IotdHandler>{
#Override
protected IotdHandler doInBackground(IotdHandler... arg0) {
IotdHandler handler = arg0[0];
handler.processFeed(); // get the RSS feed data !
return handler;
}
//------------------------------------------------------------------------------
#Override
protected void onPostExecute(IotdHandler fromInBackground){
resetDisplay( // call to update the display
fromInBackground.errorOccured,
fromInBackground.imageError,
fromInBackground);
}
//------------------------------------------------------------------------------
}
1. onCreate is on the UI thread so I can do whatever I want but onClick is not. Why can I make a ProgressDialog and a Toast in that method? Why no error there?
2. The AsyncTask is subclass of the the NasaDailyImage. This means it can access all the methods of NasaDailyImage including resetDisplay() which updates the display. resetDisplay() is called in the onPostExecute which runs on a different thread from UI. So, why can I update the display there and yet get no errors ?
onClick() is indeed on the UI thread. Most of what happens in an Activity happens on the UI thread.
onPostExecte() (and its counterpart onPreExecute()) runs on the UI thread as well. The AsyncTask.onPostExecte() documentation clearly states this. AsyncTask was deliberately designed such that developers could update the UI before and after they do background work.
In general, your code will be running on the UI thread unless you explicitly tell it otherwise. Once you create AsyncTasks, Runnables, or Threads, you need to ensure you understand where your code is executing. In an Activity, it is typically safe to assume you are on the UI thread.
You are extending AsyncTask class , where async task class is calling its sequential method automatically. First onPreExecute then doBackground and finally onPost. If you want to change any ui change you can use onProgressUpdate method.
To use your activity class simple call activityclass.this.resetDisplay(). Because inner class scope sometimes failed to integrate except global varible.
Thanks
Is there any function to call after activity load on screen ? I need to show AlertDialog in some occasions and if I put that in onResume it looks strange, dialog is already visible and I want to user see when AlertDialog popup.
I think maybe you want onWindowFocusChanged(). You are going to want to add some extra logic to this method call though because it will be called anytime the window gains or loses focus. Not sure what your use-case is but could just add a global boolean to see if it was the first call or not.
you can go for this
place below code in onCreate() methode
Handler handler = new Handler();
handler.postDelayed(runnable, 5000);
and implement the runnable as
public Runnable runnable = new Runnable() {
public void run() {
}
};
in the postDelayed(runnable,decide your time) this will help you.
i hope i give you answer.
onCreate(Bundle savedInstanceState){
// show dialog A if something is not correct
new Thread(){
public void run(){
if(something is wrong) {
runOnUIThread(new Runnable(){
public void run(){
showDialog(A);
}
});
}
}
}.start();
// show dialog B
showDialog(B);
}
I want to know
which dialog will be shown first, and is the order indeterminate? why?
if the order is indeterminate, how can i reproduce the case that A is shown before B?
Thanks!
Which dialog will be shown first is not defined and you should not rely on one occurring before the other as above. The thread scheduler is not identically deterministic in all situations.
You need to lock on a mutex (or any other locking device) to make sure one is shown before the other.
Your question about which dialog will show first is indeterminate. There are cases where the order will flip flop. But generally B would be shown first since 9/10 it will get to place it's event on the UI thread before your thread could detect there was a problem.
I'd suggest using AsyncTask to perform whatever mechanisms are needed to startup, then in the onPostExecute() allow your program to resume starting up so it can showDialog(B) for whatever it needs. That way if dialog A is showing you can stop the startup process there and not show b.
public class MyAsyncStartup extends AsyncTask<Integer,Integer,MyResult> {
MyActivity activity;
public MyResult handleBackground() {
if( somethingWentWrong ) return null;
}
public onPostExecute( MyResult result ) {
if( result == null ) {
showDialog(B);
} else {
activity.resumeStartupAndShowA();
}
}
}
I don't think it is possible that A is shown before B... this is because runOnUIThread adds the event TO THE END of the event queue. The code in that event (showing dialog A) is not going to get executed until after the onCreate() finishes (which means that dialog B gets shown first).
What cannot be guaranteed is the order between showing dialog B and calling runOnUIThread, but that doesn't matter. Here is a fragment from the official docs:
[runOnUIThread] Runs the specified action on the UI thread. If the current thread is the UI thread, then the action is executed immediately. If the current thread is not the UI thread, the action is posted to the event queue of the UI thread.
N/A
You can't show B until you know whether or not A will be shown. So you have to wait for the worker thread no matter what. Would it be possible to put showDialog(B) in your other thread like this?
onCreate(Bundle savedInstanceState){
// show dialog A if something is not correct
new Thread(){
public void run(){
runOnUiThread(new Runnable(){
public void run(){
if(something is wrong) {
showDialog(A);
}
showDialog(B);
}
});
}
}
}.start();
}
I am now working on an android app in which I need to display a text after some processing is done.
I'm using a Thread to run a process in the back while my progress dialog is being displayed to the user. The Thread works properly and I've followed it step by step and, apparently, it also ends fine; however, the method in which I call it does not seem to come to an end (at least, during a normal cycle) because the text I am setting afterward does display immediately, I have to wait and do some other action (like in order for it to display
Below is the piece of code I'm having trouble with:
private OnClickListener saldoDisp = new OnClickListener(){
public void onClick(View v){
int x = s2.getSelectedItemPosition();
branchSel = arrSucsId[x];
mainProc();
saldoAdminTex.setText(strSaldo); //The late one
}
};
public void mainProc(){
chekP = new Thread (null,doProc,"Background");
chekP.start();
mProgress =ProgressDialog.show(SivetaAsaldo.this, "","Obteniendo saldo...",true, false);
}
private Runnable doProc = new Runnable(){
public void run(){
if(getSaldoAdmin(levelSel,branchSel))
{
mProgress.dismis();
Log.i(TAG,"Task completed properly");
}else
handler.post(tosti);
}
};
So I do get the "Task completed properly" but seems like it still waits for something else, any clues guys?
Thanks for taking a bit of your time to check it out =).
saldoAdminTex.setText(strSaldo); //The late one
is going to get called immediately. It doesn't wait until after the Thread started in mainProc ends. You also cannot dismiss the Progress Dialog in your runnable. You can only do UI related things on the main UI thread.
It would help you to read the article on Painless Threading on the Android Dev site.
About your ProgressDialog, please see this answer about how to use a AsyncTask with a ProgressDialog.
Looking at your code, this:
saldoAdminTex.setText(strSaldo);
would potentially be executed before your thread finishes as the thread will be running in parallel to that line.
An alternative way would be to do this:
public void mainProc(){
mProgress =ProgressDialog.show(SivetaAsaldo.this, "","Obteniendo saldo...",true,false);
handler.post(new Runable(){
public void run(){
if(getSaldoAdmin(levelSel,branchSel))
{
mProgress.dismis();
saldoAdminTex.setText(strSaldo);
Log.i(TAG,"Task completed properly");
}else
handler.post(tosti);
}
});
}