I want to show a progress dialog while loading some data from remote server :
I'm using the following thread in order to get the data and it's working, but i'm not able to show the progress bar on the activity:
public class Request {
public String text ;
public boolean downloadText(String urlStr) {
final String url = urlStr;
new Thread () {
public void run() {
int BUFFER_SIZE = 2000;
InputStream in = null;
Message msg = Message.obtain();
msg.what=2;
try {
in = openHttpConnection(url);
InputStreamReader isr = new InputStreamReader(in);
int charRead;
text = "";
char[] inputBuffer = new char[BUFFER_SIZE];
while ((charRead = isr.read(inputBuffer))>0)
{
//---convert the chars to a String---
String readString =
String.copyValueOf(inputBuffer, 0, charRead);
text += readString;
inputBuffer = new char[BUFFER_SIZE];
}
Bundle b = new Bundle();
b.putString("text", text);
msg.setData(b);
in.close();
}catch (IOException e) {
e.printStackTrace();
}
}
}.start();
}
would you please tell me how can i do it !!
create the class as below and just call the object of this class.
class MyTask extends AsyncTask<Void, Void, Void> {
ProgressDialog Asycdialog = new ProgressDialog(ActivityName.this);
#Override
protected void onPreExecute() {
super.onPreExecute();
Asycdialog.setMessage("Loading...");
Asycdialog.show();
}
#Override
protected Void doInBackground(Void... arg0) {
// do the task you want to do. This will be executed in background.
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
Asycdialog.dismiss();
}
}
Use progressDialog
final ProgressDialog progress=ProgressDialog.show(youractivity.this,"","message");
new Thread()
{
public void run()
{
try{
youractivity.this.runOnUiThread(new Runnable(){
#Override
public void run() {
// TODO Auto-generated method stub
// your code
}
});
}
catch(Exception e)
{
}
progress.dismiss();
}
}.start()
Also, note that if you want to use Toast, you should use runOnUiThread
If you do not want to change the structure of your code, you can use runOnUiThread or an Handler to show and dissmiss the progress dialog. Show it when the firs line of the run method is excuted and dismiss it in the finally block.
public void run() {
runOnUiThread(new Runnable() {
public void run(){
// show progress dialog
}
});
/// your code here
try {
} catch (IOException e) {
} finally {
runOnUiThread(new Runnable() {
public void run(){
// dismiss progress dialog
}
});
}
}
Create Progress Dialog in AsyncTask
private class YourAsyncTask extends AsyncTask<Void, Void, Void> {
protected Void doInBackground(Void... args) {
// do background work here
return null;
}
protected void onPostExecute(Void result) {
// do UI work here
}
}
pDialog = ProgressDialog.show(context, null, "Loading...", true);
pDialog.setCancelable(false);
new Thread() {
public void run() {
// handle the exception somehow, or do nothing
// run code on the UI thread
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
// do yor ui part here
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}.start();
Related
i'm developing an android App.
The user registration process calls a service that sends an email so it takes several seconds, like 5 or 6 seconds,that's why I execute that task within a thread. The problem is, the Dialog is never dismissing. It stays rolling and the user can do nothing. Here's my code:
try
{
final ProgressDialog progDailog = new ProgressDialog(ActividadAltaUsuario.this);
new Thread(new Runnable()
{
#Override
public void run()
{
try
{
URL url = new URL("slowWS");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
InputStream in = new BufferedInputStream(conn.getInputStream());
String response = IOUtils.toString(in, "UTF-8");
final JSONObject jsonPrincipal = new JSONObject(response);
Boolean success = jsonPrincipal.get("status").toString() == "true";
if (success)
{
ActividadAltaUsuario.this.runOnUiThread(new Runnable() {
#Override
public void run() {
progDailog.show(ActividadAltaUsuario.this, "Sendind email");
}
});
final String idUsuario = jsonPrincipal.get("idUsuario").toString();
URL url2 = new URL("anotherSlowWS");
HttpURLConnection conn2 = (HttpURLConnection) url2.openConnection();
conn2.setRequestMethod("POST");
InputStream in2 = new BufferedInputStream(conn2.getInputStream());
String response2 = IOUtils.toString(in2, "UTF-8");
JSONObject jsonRtaMail = new JSONObject(response2);
//finish();
}
else
{
//finish();
showToast(jsonPrincipal.get("message").toString());
}
ActividadAltaUsuario.this.runOnUiThread(new Runnable() {
#Override
public void run() {
progDailog.dismiss();
}
});
}
catch (Exception e)
{
e.printStackTrace();
}
}
}).start();
}
catch(Exception e)
{
Log.e("log_tag", "Error in http connection" + e.toString());
}
Can anybody help me?
Thanks!
AsyncTask would be a better approach instead of thread, Replace your network call from thread to use AsyncTask. You can use something like this
private class LongOperation extends AsyncTask<Void, Void, Void> {
#Override
protected String doInBackground(Void... params) {
//Main stuff that needs to be done in background
}
#Override
protected void onPostExecute(Void result) {
//Post Execution this method will be called, handle result accordingly
//You can dismiss your dialog here
}
#Override
protected void onPreExecute() {
//Do initialization relative stuff here
// Initialize your dialog here.
}
}
As both onPostExecute() and onPreExecute() work on main thread you can show and dismiss your dialog in this methods.
The UI controls have to be accessed only from the UI thread.
Usually I do this in class that extends AsyncTask
Something like:
public class MyTask extends AsyncTask {
protected void onPreExecute() {
//create and display your alert here
progDialog = ProgressDialog.show(MyActivity.this,"Please wait...", "Logging ...", true);
}
protected Void doInBackground(Void... unused) {
// here is the thread's work ( what is on your method run()
...
// if we want to show some progress in UI, then call
publishProgress(item)
}
protected void onProgressUpdate(Item... item) {
// theoretically you can show the progress here
}
protected void onPostExecute(Void unused) {
//dismiss dialog here where the thread has finished his work
progDialog.dismiss();
}
}
LE:
More detalis about AsyncTask https://developer.android.com/reference/android/os/AsyncTask
check especially the Protected Methods
how to kill Async task after a specific time.
Here is My code
public class EnterTextAsyc extends AsyncTask<Integer, Integer, Integer> {
/* displays the progress dialog untill background task is completed */
#Override
protected void onPreExecute() {
progressDialog(context, "Please Wait !!!!!...");
super.onPreExecute();
}
/* Task of EnterTextAsyc performing in the background */
#SuppressLint("NewApi") #Override
protected Integer doInBackground(Integer... params) {
try {
socket = new Socket(SERVER_IP, SERVERPORT);
out = new PrintStream(socket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(
socket.getInputStream()));
out.write(("BE").getBytes());
ServerData = in.readLine();
if (ServerData == null || ServerData.equalsIgnoreCase("")) {
ServerData = "IsNull";
}
} catch (NetworkOnMainThreadException e) {
ServerData = "IsNull";
} catch (IOException ex) {
ServerData = "IsNull";
}
return null;
}
How to set a timeout message if there is no response from Server(ServerData = in.readLine();).
Handler h;
private static final int DELAY=3000; //milis
#Override
protected void onPreExecute() {
h = new Handler();
h.postDelayed(new Runnable(){
public void run() {
if(h!=null)
h.removeCallbacksAndMessages(null);
cancelAfterTimeout(true);
}
}, DELAY);
progressDialog(context, "Please Wait !!!!!...");
super.onPreExecute();
}
private void cancelAfterTimeout(boolean interrupt){
//cancel/force interrupt/dissable/remove connection here
//which you are initializing in doInBackground
cancel(interrupt);
}
#Override
protected void onPostExecute(Boolean result) {
if(h!=null)
h.removeCallbacksAndMessages(null);
}
even if you pass mayInterrupt as true the connection is still executing, you might create new method for cancelling online connections and then super.cancel(true);. more info and some methods for override here - onCanceled() and onCanceled(Boolean result) for you
PS canceling Socket connection while executing might be difficult, thread about this here . maybe try HttpClient or HTTPConnection?
I have a custom method of my class that (on my Android phone) takes 2-3 second to finish, and I would like to surround it with a progress bar.
Here is my method:
public void getQuestionsForSelectedCategory(){
ArrayList<Question> temp = (ArrayList<Question>) this.clone();
ArrayList<Question> tempGroup;
this.clear();
for(int i=0;i<2;i++){
tempGroup = new ArrayList<Question>();
for(int j=0;j<temp.size();j++)
if((temp.get(j).getGroup()==i+1)&&(temp.get(j).getCategory().contains(category)||temp.get(j).getCategory().equals("*")))
tempGroup.add(temp.get(j));
getQuestionsForSelectedGroup(tempGroup, numbersByGroup[i], pointsByGroup[i]);
}
tempGroup = new ArrayList<Question>();
for(int i=0;i<temp.size();i++){
int a = temp.get(i).getGroup();
if((a==3||a==4||a==5||a==6||a==7))
if(temp.get(i).getCategory().contains(category)||temp.get(i).getCategory().equals("*"))
tempGroup.add(temp.get(i));
}
Collections.shuffle(tempGroup);
getQuestionsForSelectedGroup(tempGroup, numbersByGroup[2], pointsByGroup[2]);
if(category.equals("C")){
tempGroup = new ArrayList<Question>();
for(int i=0;i<temp.size();i++)
if(temp.get(i).getCategory().equals(category))
tempGroup.add(temp.get(i));
getQuestionsForSelectedGroup(tempGroup, 10, 30);
}
}
And here is what I try to do:
barProgressDialog = new ProgressDialog(this);
barProgressDialog.setTitle("Preparing Test");
barProgressDialog.setMessage("Preparing Test");
barProgressDialog.setProgressStyle(barProgressDialog.STYLE_HORIZONTAL);
barProgressDialog.setProgress(0);
barProgressDialog.setMax(100);
barProgressDialog.show();
new Thread(new Runnable() {
#Override
public void run() {
try {
getQuestionsForSelectedCategory();
while (barProgressDialog.getProgress() <= barProgressDialog.getMax()) {
updateBarHandler.post(new Runnable() {
public void run() {
barProgressDialog.incrementProgressBy(2);
}
});
if (barProgressDialog.getProgress() == barProgressDialog.getMax()) {
barProgressDialog.dismiss();
}
}
} catch (Exception e) {
}
}
}).start();
}
For the current code the progress bar fills up to 100 but it does nothing.
You could use an AsyncTask to achieve this, whilst publishing your progress during the task.
AsyncTask<Void, Integer, Void> task = new AsyncTask<Void, Integer, Void>() {
#Override
protected Void doInBackground(Void... voids) {
getQuestionsForSelectedCategory();
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
barProgressDialog.setProgress(values[0]);
}
#Override
protected void onPostExecute(Void aVoid) {
barProgressDialog.dismiss();
}
}
task.execute();
Ensure your getQuestionsForSelectedCategory and getQuestionsForSelectedGroup methods are inside the AsyncTask and within the loops you can call publishProgress(int progress) to update the progress dialog.
I have that AsyncTask code
public class DiceTask extends AsyncTask<Socket, Void, int[]> {
private int[] arrayFromServer = new int[8];
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected int[] doInBackground(Socket...params) {
Socket soc = params[0];
try {
ObjectInputStream ois = new ObjectInputStream(soc.getInputStream());
int[] tempArray = (int[]) (ois.readObject());
return tempArray;
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
#Override
protected void onProgressUpdate(Void...arg1) {
}
#Override
protected void onPostExecute(int[] result) {
arrayFromServer = result;
}
public int[] getTempDice() {
return arrayFromServer;
}
}
where is called this way into my main thread.
rollDiceButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rollDiceButton.setEnabled(false);
rollDice();
task.execute(socket);
tempArray = task.getTempDice();
printDice(tempArray,pDice);
clickableDice(pDice);
}
});
where I am getting a null tempArray. If I change my onPreExecute to this
#Override
protected void onPreExecute() {
super.onPreExecute();
for(int i = 0; i < arrayFromServer.length; i++) {
arrayFromServer[i] = 1;
}
}
I am getting my dice as it should, all are one. The code I am running into the rollDice() is this
public void rollDice() {
try {
DataOutputStream sout = new DataOutputStream(socket.getOutputStream());
String line = "dice";
PrintStream out = new PrintStream(sout);
out.println(line);
} catch (UnknownHostException e1) {
e1.printStackTrace();
} catch (IOException e1) {
e1.printStackTrace();
}
}
and I can see the results in the server.
You don't need to implement onPostExecute in your AsyncTask class definition. You also don't need the getTempDice function. You just need to override onPostExecute in an anonymous class and run your UI code in it.
rollDiceButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rollDiceButton.setEnabled(false);
rollDice();
task = new DiceTask() {
#Override
public void onPostExecute(int[] result) {
tempArray = result;
printDice(tempArray,pDice);
clickableDice(pDice);
}
}.execute(socket);
}
});
Children of AsyncTask run in parallel with main Thread, you are trying access the attribute arrayFromServer right after to start the Thread. It's recommended you use a callback to retried the value wanted, making sure you get the value after Thread is done.
Making the follow changes can solve your problem. Let me know if you understand.
public class DiceTask extends AsyncTask<Socket, Void, int[]> {
public interface Callback {
void onDone(int[] arrayFromServer);
}
private Callback mCallback;
public DiceTask(Callback c) {
mCallback = c;
}
#Override
protected int[] doInBackground(Socket...params) {
Socket soc = params[0];
try {
ObjectInputStream ois = new ObjectInputStream(soc.getInputStream());
int[] tempArray = (int[]) (ois.readObject());
return tempArray;
} catch (IOException | ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
}
#Override
protected void onPostExecute(int[] result) {
mCallback.onDone(result);
}
}
rollDiceButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
rollDiceButton.setEnabled(false);
rollDice();
new DiceTask(new Callback() {
public void onDone(int[] tempArray) {
printDice(tempArray,pDice);
clickableDice(pDice);
}
}).execute(socket);
}
});
I am trying to use ProgressDialog. when i run my app the Progress Dialog box show and disappear after 1 second. I want to show it on completion of my process.. Here is my code:
public class MainActivity extends Activity {
android.view.View.OnClickListener mSearchListenerListener;
private ProgressDialog dialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new YourCustomAsyncTask().execute(new String[] {null, null});
}
private class YourCustomAsyncTask extends AsyncTask <String, Void, Void> {
protected void onPreExecute() {
dialog = new ProgressDialog(MainActivity.this);
dialog.setMessage("Loading....");
dialog.setIndeterminate(true);
dialog.setCancelable(true);
dialog.show(); //Maybe you should call it in ruinOnUIThread in doInBackGround as suggested from a previous answer
}
protected void doInBackground(String strings) {
try {
// search(strings[0], string[1]);
runOnUiThread(new Runnable() {
public void run() {
// updateMapWithResult(); //Or call it onPostExecute before progressDialog's dismiss. I believe this method updates the UI so it should run on UI thread
}
});
} catch(Exception e) {
}
}
#Override
protected void onPostExecute(Void params) {
dialog.dismiss();
//result
}
#Override
protected Void doInBackground(String... params) {
// TODO Auto-generated method stub
return null;
}
}
}
Updated Question:
#Override
public void onCreate(SQLiteDatabase db) {
mDatabase = db;
Log.i("PATH",""+mDatabase.getPath());
mDatabase.execSQL(FTS_TABLE_CREATE);
loadDictionary();
}
/**
* Starts a thread to load the database table with words
*/
private void loadDictionary() {
new Thread(new Runnable() {
public void run() {
try {
loadWords();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}).start();
}
private void loadWords() throws IOException {
Log.d(TAG, "Loading words...");
for(int i=0;i<=25;i++)
{ //***//
final Resources resources = mHelperContext.getResources();
InputStream inputStream = resources.openRawResource(raw_textFiles[i]);
//InputStream inputStream = resources.openRawResource(R.raw.definitions);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
try {
StringBuilder sb = new StringBuilder();
while ((word = reader.readLine()) != null)
{
sb.append(word);
// Log.i("WORD in Parser", ""+word);
}
String contents = sb.toString();
StringTokenizer st = new StringTokenizer(contents, "||");
while (st.hasMoreElements()) {
String row = st.nextElement().toString();
String title = row.substring(0, row.indexOf("$$$"));
String desc = row.substring(row.indexOf("$$$") + 3);
// Log.i("Strings in Database",""+title+""+desc);
long id = addWord(title,desc);
if (id < 0) {
Log.e(TAG, "unable to add word: " + title);
}
}
} finally {
reader.close();
}
}
Log.d(TAG, "DONE loading words.");
}
I want to show ProgressDialogue box untill all words are not entered in the database. This code is in inner calss which extends SQLITEHELPER. so how to can i use ProgressDialogue in that inner class and run my addWords() method in background.
You cannot have this
runOnUiThread(new Runnable() {
public void run() {
// updateMapWithResult(); //Or call it onPostExecute before progressDialog's dismiss. I believe this method updates the UI so it should run on UI thread
}
});
in your doInBackground().
Progress dialog doesn't take priority when there is some other action being performed on the main UI thread. They are intended only when the actions are done in the background. runonUIthread inside doInBackground will not help you. And this is normal behavior for the progressdialog to be visible only for few seconds.
You have two doInBackground() methods inside your AsyncTask Class. Remove the runOnUiThread() from First doInBackground() and move it to second doInBackground() which has #Override annotation.
I don't know whether you wantedly written two doInBackground() methods or by mistake but it is not good to have such confusion between the Method. Your AsyncTask is not calling the first doInBackground() and it will call doInBackground() which has #Override annotation. So your ProgressDialog is dismissed in 1 second of time as it returns null immediately.