When I try to update text in my progressDialog like someone suggests here or here.
In my case, I'm trying to update the text in a loop while the progressDialog is not dismissed (?) elsewhere...
But my loop inside the runnable doesn't seems work, or better, the runnable doesn't make show the progressDialog.
So, in this way the code shows the progressDialog:
#Override
public void onDirectionFinderStart() {
String title = "PriscaLobby";
String msg = "Loading...";
progressDialog = ProgressDialog.show (MapsActivity.this,title,msg,true,false);
//--> runOnUiThread(changeMessage);
}
private Runnable changeMessage = new Runnable() {
#Override
public void run() {
progressDialog.setMessage("bruka");
while (progressDialog.isShowing()) {
try {
Thread.sleep(1500);
if (progressDialog.isShowing())
progressDialog.setMessage("Can you wait, please?");
Thread.sleep(1500);
if (progressDialog.isShowing())
progressDialog.setMessage("Here we are..");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
In this way NO:
#Override
public void onDirectionFinderStart() {
String title = "PriscaLobby";
String msg = getString(R.string.calculate_directions);
progressDialog = ProgressDialog.show (MapsActivity.this,title,msg,true,false);
runOnUiThread(changeMessage);
}
private Runnable changeMessage = new Runnable() {
#Override
public void run() {
progressDialog.setMessage("bruka");
while (progressDialog.isShowing()) {
try {
Thread.sleep(1500);
if (progressDialog.isShowing())
progressDialog.setMessage("Can you wait, please?");
Thread.sleep(1500);
if (progressDialog.isShowing())
progressDialog.setMessage("Here we are..");
} catch (InterruptedException e) {
e.printStackTrace();
}
} //Log.v(TAG, strCharacters);
}
};
Why?
Related
Right now I'm simulating the showing of a ProgressDialog for an event that is expected to take several seconds.
I'm doing it this way:
progressDialog = new ProgressDialog(getContext());
progressDialog.setMessage(getString(R.string.calendar_load));
progressDialog.setCancelable(false);
progressDialog.show();
Thread t=new Thread(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
getActivity().runOnUiThread(new Runnable()
{
#Override
public void run() {
progressDialog.cancel();
progressDialog.hide();
But even though I've checked in debug that the progressDialog.cancel() and progressDialog.hide() execute the dialog just keeps on showing apparently in an indefinite way.
What could be causing such behavior?
PROBLEM SOLVED: Thanks to everyone who has answered/commented, it looks like an emulator bug (indeed it has also worked some times on emulator).
Call progressDialog.dismiss();
Could you try this snippet?
progressDialog.show();
new Thread(new Runnable() {
#Override
public void run() {
try {
while (progressDialog.getProgress() <= progressDialog.getMax()) {
Thread.sleep(100);
handle.sendMessage(handle.obtainMessage());
if (progressDialog.getProgress() == progressDialog.getMax()) {
progressDialog.dismiss();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
Handler handle = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
progressDialog.incrementProgressBy(1);
}
};
I am having a problem which is I think that I can't access th,e ListView from the asyncTask
Actually, I really don't know the real problem here
Let me show you what is happening
I have an activity which is executing AsyncTask and creates HttpURLConnection. Sometimes I get an exception (ProtocolException) because the stream un-expectedly ends.
So, I created a handler for this exception that calls a function or a method inside the class of the activity to display a message to the user
Here is a picture so you understand what is my project.
image
the problem here whenever the exception is thrown, the same function/method that I use to add the text to the listView is called, but after it called the listView disappear, but when I minimize the soft keyboard manually the everything becomes fine.
the structure of my class is
public class MainActivity extends AppCompatActivity
{
protected void onCreate(Bundle savedInstanceState)
{
addMessageToListView()//works fin here
}
protected void addMessage(String message, int userMessage, ListView listView) // the function
{
try
{
messages.add(new Message(message,userMessage));
MessagesAdapter messagesAdapter = new MessagesAdapter(messages, getBaseContext());
messagesAdapter.notifyDataSetChanged();
listView.setAdapter(messagesAdapter);
}
catch (Exception exception)
{
}
}
private class HttpPostAsyncTask extends AsyncTask<String, Void, String>
{
...
#Override
protected void onPostExecute(String result)
{
try
{
addMessageToListView()//works fin here
}
catch (Exception exception)
{
}
}
protected String doInBackground(String... params)
{
String result = "";
for (int i = 0; i <= 0; ++i)
{
result = this.invokePost(params[i], this.postData);
}
return result;
}
private String invokePost(String requestURL, HashMap<String, String> postDataParams)// called from doInBackground
{
try
{
addMessageToListView()//works fin here
}
catch (Exception exception)
{
addMessageToListView()//not orking here
}
}
}
}
I don't know how to explain more actually.
You can change Views only in mainthread of your app. The doInBackground doesn't run in mainthread of your app.
Solved by adding:
new Thread()
{
#Override
public void run()
{
MainActivity.this.runOnUiThread(new Runnable()
{
#Override
public void run()
{
addMessageToListView()//not orking here
}
});
super.run();
}
}.start();
Editing the previous code in my question:
public class MainActivity extends AppCompatActivity
{
protected void onCreate(Bundle savedInstanceState)
{
addMessageToListView()//works fin here
}
protected void addMessage(String message, int userMessage, ListView listView) // the function
{
try
{
messages.add(new Message(message,userMessage));
MessagesAdapter messagesAdapter = new MessagesAdapter(messages, getBaseContext());
messagesAdapter.notifyDataSetChanged();
listView.setAdapter(messagesAdapter);
}
catch (Exception exception)
{
}
}
private class HttpPostAsyncTask extends AsyncTask<String, Void, String>
{
...
#Override
protected void onPostExecute(String result)
{
try
{
addMessageToListView()//works fin here
}
catch (Exception exception)
{
}
}
protected String doInBackground(String... params)
{
String result = "";
for (int i = 0; i <= 0; ++i)
{
result = this.invokePost(params[i], this.postData);
}
return result;
}
private String invokePost(String requestURL, HashMap<String, String> postDataParams)// called from doInBackground
{
try
{
addMessageToListView()//works fin here
}
catch (Exception exception)
{
new Thread()
{
#Override
public void run()
{
MainActivity.this.runOnUiThread(new Runnable()
{
#Override
public void run()
{
addMessageToListView()//not orking here
}
});
super.run();
}
}.start();
}
}
}
}
I need solution to stop my thread and display Toast.
Why doesn't stop my thread?
Why doesn't my solution display "success" by Toast?
This is my class StopperThread where I try stop by blinker my thread.
public class StopperThread implements Runnable{
private Context context;
private volatile boolean blinker;
public StopperThread(Context context){
this.context = context;
this.blinker = true;
}
#Override
public void run ()
{
Looper.prepare();
try {
while(blinker) {
Log.e("LOG","ACTIVE");
Thread.sleep(1000);
Toast.makeText(context, "success", Toast.LENGTH_SHORT).show();
}
} catch (InterruptedException e) {
e.printStackTrace();
blinker = false;
}
Looper.loop();
}
public void mystop() {
blinker = false;
}
}
This is my method clickedButton inside the Activity where I created thread.
private void clickedButton() {
final StopperThread stopperThread = new StopperThread(this);
Thread t1 = new Thread(stopperThread);
if(click)
{
t1.start();
click = false;
}
else
{
try {
stopperThread.mystop();
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
click = true;
}
}
I tried to change
/*First Try*/
final StopperThread stopperThread = new StopperThread(getApplicationContext());
/*Second Try*/
runOnUiThread(new Runnable() {
#Override
public void run() {
t1 = new Thread(stopperThread);
}
});
Other class:
SpotifyTask st = new SpotifyTask(new Closure<JSONObject>() {
#Override
public void executeOnSuccess(JSONObject result) {
track.setJson(result);
}
});
st.execute("asd");
Being SpotifyTask:
public class SpotifyTask extends AsyncTask<Object, Void, JSONObject> {
private final Closure<JSONObject> closure;
public SpotifyTask(Closure<JSONObject> closure) {
this.closure = closure;
}
public static void getTrack(Closure<JSONObject> closure) {
new SpotifyTask(closure).execute("asd");
}
#Override
protected JSONObject doInBackground(Object... params) {
JSONObject result = null;
SpotifyCall spcall = new SpotifyCall();
try {
result = spcall.getTrack();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return result;
}
#Override
protected void onPostExecute(JSONObject result) {
System.out.println("ASD: on post execute "+result);
closure.executeOnSuccess(result);
}
}
So... doInBackground is running OK, and and returning a JSONObject all right; I know because Im debbuging it and "result" IS a JSONObject.
But onPostExecute is never executed, the debugger never gets there and "ASD: on postexecute "+result is never logged.
Any suggestions?
Thanks in advance!
The problem was that I was "holding" the UI Thread:
this.status = "loading";
final Track track = new Track();
SpotifyTask.getTrack(new Closure<JSONObject>() {
#Override
public void executeOnSuccess(JSONObject result) {
track.setJson(result);
}
});
while (this.status.equals("loading")) {
if (track.getJson() != null) {
this.trackUno = track.getJson();
this.status = "ready";
} else {
try {
System.out.println("Not ready, waiting.");
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
As soon I removed the while block, it worked perfectly.
I would have to find another way to "wait" for the call to be complete.
Thanks for your time fellas!
I test the following code and the Toast message did not appear and the "TestMethod" did not call "Catch" method , please help me ?
public void TestMethod()
{
Test= new Thread(new Runnable() {
public void run() {
try{
Catch();
}
catch (Exception ioe)
{
}
}
});
Test.start();
}
public void Catch()
{
Test2= new Thread(new Runnable() {
public void run() {
try{
Toast.makeText(getApplicationContext(), "Yes", Toast.LENGTH_SHORT).show();
}
catch (Exception ioe)
{
}
}
});
Test2.start();
}
May be runOnUiThread helpful to you.
runOnUiThread lets you ride on the UI thread and let s you to perform action on UI thread.
Try this:
runOnUiThread(new Runnable()
{
public void run()
{
Toast.makeText(getApplicationContext(), "Yes", Toast.LENGTH_SHORT).show();
}
});
You should call Toast.makeText on UI thread. Read this for more details.
You can make a toast only from the UI Thread. If you have access to the activity, you can change your code like thi
public void TestMethod()
{
Test= new Thread(new Runnable() {
public void run() {
try{
Catch();
}
catch (Exception ioe)
{
}
}
});
Test.start();
}
public void Catch()
{
activity.runOnUiThread(new Runnable() {
public void run() {
try{
Toast.makeText(getApplicationContext(), "Yes", Toast.LENGTH_SHORT).show();
}
catch (Exception ioe)
{
}
}
});
}
This is the complete solution and it should work perfectly
Some methods will only run on the uithread, (runOnUiThread is a method on the activity, so if you can't reach it, than just put a variable
private final Activity activity = this;
and call the runOnUiThread from there
public void TestMethod() {
Test= new Thread(new Runnable() {
public void run() {
try{
Catch();
}
catch (Exception ioe) {
//always log your exceptions
Log.e("simpleclassname", ioe.getMessage(), ioe);
}
}
});
Test.start();
}
public void Catch() {
Test2= new Thread(new Runnable() {
public void run() {
try{
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "Yes", Toast.LENGTH_SHORT).show();
});
catch (Exception ioe) {
//always log your exceptions
Log.e("simpleclassname", ioe.getMessage(), ioe);
}
}
});
Test2.start();
}
The thread you are using does not allows toast to show. You must do UI related stuff on a UI thread. If you are not on Main Thread, then you need to use runOnUiThread.