Pause UI, while update data on postExecute in AsyncTask - java

I'm using sockets in my app. I created a class SocketClient with methods: onConnect, onSendData, onReadData. Method onReadData extends AsyncTask. It waits for a string message from the server inside doInBackground and then makes a new task to listen for the incoming message. Now I want to pause the UI in my MainActivity class while the message is loading and get it, but don't know how to do that. My Async Task looks like:
public void ReadMyData() {
mt = new ReadDataAsync();
mt.execute();
}
class ReadDataAsync extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
// a lot of work
return message;
}
#Override
protected void onPostExecute(String result) {
ReadMyData();
}
}
and MainActivity:
public SocketClient mySocketClient = new SocketClient();
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mySocketClient.onConnect();
//there I need wait message load and take it
setContentView(R.layout.activity_game);
WorkWithMessage(message);}

Create a progress DIALOG and start it when you know the message is loading, than take it off when the message is loaded.
You can create a progress DIALOG like this:
ProgressDialog pd = New ProgressDialog();
pd.setTitle(”title”);
pd.setMessage(”messgae”);
pd.setCancleable(false);
Than call
pd.show();
When you wish to load the message, and
pd.dismiss();
When you’r done.

Related

Showing ProgressDialog only once in a recursive AsyncTask

In the Java code I have executed an AsyncTask class and with the returned result I have done a recursive call to itself in the onPostexecute method. Example:
MainActivity.java
public void button_clicked(){
UploadAsync send_data = new UploadAsync(MainActivity.this);
send_data.execute("send first data", user_data, file_path);
}
UploadAsync.java
#Override
protected String doInBackground(String... params) {
String task = params[0];
if(task.equals("send first data"){
String user_data = params[1];
String file_path = params[2];
//send in the user_data to a php file
}else if(task.equals("send file"){
String file_path = params[1];
//send the file_path to another php file
}
}
#Override
protected void onPreExecute() {
ProgressDialog pd = ProgressDialog.show(context, "Sending", "Please wait");
}
#Override
protected void onPostExecute(String result) {
if(result.equals("data sent"){
UploadAsync send_data = new UploadAsync(context);
send_data.execute("send file", file_path);
}else{
//show error
}
pd.dismiss();
}
The code above is only an example made. Now the thing is, implementing this example will run the progress dialog twice. I have tried many ways to only show the progress dialog once while the AsyncTask is sending the user data and the file path but I'm not succeeding. Is there any suggestions on how to implement this correctly?
Can't you call pd.dismiss() and dismiss ProgressDialog for the current UploadAsync before executing new UploadAsync?
In onPostExecute first, dismiss the dialog and then start new asynctask like this:
#Override
protected void onPostExecute(String result) {
pd.dismiss();
if(result.equals("data sent"){
UploadAsync send_data = new UploadAsync(context);
send_data.execute("send file", file_path);
}else{
//show error
}
}
I hope this will help you.
Let ProgressDialog as global data .
private ProgressDialog pd;
#Override
protected void onPreExecute() {
// show the ProgressDialog
if (pd == null) {
pd = ProgressDialog.show(context, "Sending", "Please wait");
}
}
#Override
protected void onPostExecute(String result) {
if (result.equals("data sent") {
UploadAsync send_data = new UploadAsync(context);
send_data.execute("send file", file_path);
}else{
//show error
}
// edited here ,make the ProgressDialog dismiss
if (pd.isShowing() && pd != null) {
pd.dismiss();
pd = null;
}
}
In that case use callback mechanism between the async task and the caller(here, MainActivity).
Implement as I explained below.
Define an interface with showProgressDiaglog() and
DismissProgressDialog() methods.
MainActivity implements this interface and implements the two
methods to show and dismiss progress dialog respectively.
Define setter method in your AsyncTask class and call this setter
method from the MainActivity by passing this(this refers to
MainActivity) after creating the AsyncTask instance and before
calling execute method. store the passed interface implementation in
the AsyncTask class as an instance variable.
Modify AsyncTask constructor to pass the task type instead of passing
in the execute method and store this task type in the AsyncTask as an
instance variable.
Now from within the AsyncTask constructor, in onPreExecute()
method, call showProgressDialog() method based on the task type.
and in onPostEecute() method call dismissProgressDialog()
depending on the task type.

How can I modify a variable declared in the UI Thread, from an other thread?

I'm currently working on my first Android application.
The application accesses a database to get some informations that I want to print on the screen. To send requests and get answers on the network, I need to use a new thread (I'll name it "N thread"), different from the UI Thread. This part is ok.
Now, I want to modify the variable eventList to get the values stored in a collection, in the N thread.
public class MainActivity extends AppCompatActivity {
public List<Event> eventList = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/* I fill the list in an other thread */
new Thread(new Runnable() {
public void run(){
eventList = new WebService().getEvents(); //returns a list
}
// if I check here, eventList contains elements
}).start();
/* I check the result */
TextView respView = (TextView) findViewById(R.id.responseView);
if(eventList != null)
{
respView.setText("Ok");
} else {
respView.setText("Not ok");
}
...
}
The problem is : eventList is not modified. How can modify this variable and print it from the UI thread ?
Thank you for your help.
You can use runOnUiThread function or Handler to update UI from other thread. I suggest you reading the below tutorial first: AndroidBackgroundProcessing
Try this
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params)
{
eventList = new WebService().getEvents();
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView respView = (TextView) findViewById(R.id.responseView);
if(eventList != null)
{
respView.setText("Ok");
} else {
respView.setText("Not ok");
}
}
});
}
}.execute();
private class EventsDownloader extends AsyncTask<Void, Void, Void> {
protected Long doInBackground(Void... params) {
eventList = new WebService().getEvents()
}
protected void onPostExecute(Void result) {
TextView respView = (TextView) findViewById(R.id.responseView);
if(eventList != null)
{
respView.setText("Ok");
} else {
respView.setText("Not ok");
}
}
}
This AsyncTask does what you want, the doInBackground runs on a thread and the 'onPostExecute' runs on the UI thread, and it's only called after the doInBackground finishes. This class is "managed" by the OS. To run it you just need to instantiate it and call 'execute'. I recommend doing something like this
The thing with your code is that the thread runs at the same time as the rest of your code (the calls to the setText), this means when it runs the setText the Thread is still getting the events.

Show DialogFragment on AsyncTask.onPostExecute when activity is in background;

I got a java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState when trying to show a dialog after the Activity goes to background, I need to show this message to the user, is there any methods to show the dialog when activity is resumed. My code is something like this:
public class MyTask extends AsyncTask<String,String,String>{
ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
#Override
protected void onPreExecute() {
progressDialog.setMessage(getString(R.string.dialog_progress_message));
progressDialog.setCancelable(false);
progressDialog.show();
}
#Override
protected String doInBackground(String... params) {
// HTTP POST user action
// App goes to background (user press home button i.e.)
// Getting message from server
return message;
}
#Override
protected void onPostExecute(String message) {
progressDialog.dismiss();
DialogAlert dialogAlert = DialogAlert.newInstance(message);
dialogAlert.setCancelable(false);
//App crash here
dialogAlert.show(getSupportFragmentManager(), TAG);
}
}
I have tried with AsyncTaskLoader but the dialog doesn't show up when activity resumes. Any ideas.
Try with below code snippets,
Replace
dialogAlert.show(getSupportFragmentManager(), TAG);
with
getSupportFragmentManager().beginTransaction().add(dialogAlert, "tag")
.commitAllowingStateLoss();

ProgressDialog not being displayed in Activity with custom View

I am developing an Android app which has 2 classes. Game, which extends Activity, and GameView, which extends View.
When the game is loaded, it sets the content view to GameView, which is just a drawing class that uses a canvas to display the game.
I am trying to create a ProgressDialog in the Game class which will show a spinner after a certain action has been done, as this takes a long time to complete. So far I have the following:
setContentView(R.layout.activity_game);
ProgressDialog pd = new ProgressDialog(this);
pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pd.setMessage("Calculating hint");
pd.show();
AsyncTask<String[][], Void, SudokuSquare> nextSquareThread = new GetNextSquare().execute(puzzleNumbers);
next = nextSquareThread.get();
pd.dismiss();
setContentView(gameView);
And my AsyncTask class looks like this:
private class GetNextSquare extends AsyncTask<String[][], Void, SudokuSquare> {
private ProgressDialog dialog = new ProgressDialog(Game.this);
#Override
protected void onPreExecute() {
this.dialog.setMessage("Finding next number");
this.dialog.show();
}
#Override
protected SudokuSquare doInBackground(final String[][]... args) {
try {
SudokuAdvancedSolver solver = new SudokuSolver(args[0]);
return solver.getOneValue();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
#Override
protected void onPostExecute(final SudokuSquare result) {
if (dialog.isShowing()) {
dialog.dismiss();
}
}
}
At the moment I have two ProgressDialogs, one inside the AsyncTask and one outside. Which one is correct? Also, the spinner is not being displayed at all. What am I overlooking which is causing this to be the case?
only the one outside is correct. because you are trying the main thread (the UI thread of your activity) by another thread (your asychronic task). you should use a handler in place of this :
1/ you show the progress bar
2/ you load the game in a thread
3/ when the game is loaded you send a message to the handler which will stop the progress bar.
See this exemple . you should dismiss your dialog in the handler (when the handler receives the message from the thread) .
If you don't implement a listener on Asynctask, i could suggest you to dismiss your progress dialog onPostExecute
private ProgressDialog dialog;
public void setProgressDialog(ProgressDialog dialog){
this.dialog = dialog;
}
#Override
protected void onPostExecute(final SudokuSquare result) {
dialog.dismiss();
}
and before you executing Asynctask add this code
nextSquareThread.setProgressDialog(pd);

Show ProgressDialog, Retrieve Data, and WAIT FOR IT

I'm writing an app that at many points will attempt to retrieve account information from a website. I'd like to write a single function ("getAccount()") to do the following:
Show a ProgressDialog
Make the call to the website
Wait for a response
Clear the ProgressDialog
Return control to the calling function after the first four steps are done
I'm not having a problem with getting the data from the page; the problem I have is with the whole "show dialog / wait for completion / return control to the calling function" portion. Either the ProgressDialog doesn't show at all, or the function returns to the caller immediately after making the data request from the site, without giving it enough time to retrieve the data.
Any help would be most appreciated.
EDIT: I'm adding a bit of code below for what I have with AsyncTask. Notice that I have the line MsgBox("done") inside grabURL(); this is simply a Toast call. When I run this code, "done" pops up while the HTTP request is still being made. This MsgBox line only exists so I can see if grabURL is properly waiting for GrabURL to finish (which it isn't).
public void grabURL() {
new GrabURL().execute();
MsgBox("done");
}
private class GrabURL extends AsyncTask<String, Void, Void> {
private ProgressDialog Dialog = new ProgressDialog(MyContext);
protected void onPreExecute() {
Dialog.setTitle("Retrieving Account");
Dialog.setMessage("We're retrieving your account information. Please wait...");
Dialog.show();
}
protected Void doInBackground(String... urls) {
try {
// Get account info from the website
String resp = GetPage(ThePage); // I have this classed out elsewhere
// Some other code that massages the data
AccountRetrievalSuccess = true;
} catch (Exception e) {
AccountRetrievalSuccess = false;
}
return null;
}
protected void onPostExecute(Void unused) {
Dialog.dismiss();
}
}
The message box done appears because AsyncTask is using a separate thread(s) to run doInBackground. The call to execute does NOT block. You could move message box done to onPostExecute following the call to dismiss. Tip. You may want to call progress.cancel in onPause or you may get unwanted behaviour on orientation change. Finally, if you are retrieving info in doInBackground, consider returning the info in doInBackground. The info will be passed to onPostExecute. So if the info is object MyInfo consider:
private class GrabURL extends AsyncTask<String, Void, MyInfo> {
Can't say for sure without seeing some code but sounds like you are making a asynchronous call to the website when you want to make a synchronous call (which will block and wait for return data) to the website instead.
You want to use an AsyncTask, generate a non-user-cancellable ProgressDialog in the onPreExecute, do your work in doInBackground, and dismiss it in onPostExecute.
Something like this:
public class MyApp extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// blah blah blah
URL url;
try
{
url = new URL("http://example.com");
new MyTask().execute(url);
}
catch (MalformedURLException e)
{
}
}
protected void doSomeStuff()
{
// stuff to do after the asynctask is done
}
protected void throwAWobbly()
{
// stuff to do if you didn't get the data
}
// inner class to do the data getting off the UI thread,
// so android doesn't "not responding" kill you
private class MyTask extends AsyncTask<URL, Void, Boolean>
{
private ProgressDialog dialog;
private boolean gotData = false;
protected void onPreExecute()
{
// create a progress dialog
dialog = ProgressDialog.show(MyApp.this, "",
"Doing stuff. Please wait...", false, false);
}
protected Boolean doInBackground(URL... urls)
{
// get your data in here!
return gotData;
}
protected void onPostExecute(Boolean result)
{
// get rid of the progress dialog
dialog.dismiss();
if (true == result)
{
// got all data!
doSomeStuff();
}
else
{
// oops!
throwAWobbly();
}
}
}
}

Categories

Resources