I have a problem regarding Async task
Async from android
Using 2 activities "A" and "B"
by entering a word to search from the url and and store value in DTO and then fetching values from getter and setter.
My complication is that i have implemented async in my activity "B" and that activity is fetching value from same DTO.
Problem is that how my post know that do in background have fetched value from DTO and DTO have fetched value from internet...in case of slow internet connection.
I m sending intent from "A" to "B" and showing the results on "B"
PROBLEM:
1. If i remove async then app shows black page and also freezes (in case of slow connection only) but data is displayed
2. If i use aync then sometimes progress dialog show for long time and inspite of knowing that data is already displayed in UI
code links https://www.dropbox.com/s/p27rpokz68sryv3/SearchData.java
https://www.dropbox.com/s/rm3i52djiay327u/SearchData_DTO.java
https://www.dropbox.com/s/2hpufx2a12480on/Search.java
Pls suggest me the possible solution for this
Regards
You need to listen for asyntask complete listener, For that let your activity A impliment interface and call that method from Activity B,s Asyntask,s onpostexecute method
Thus your activity A will come to know that B has finished his task and you can do next thing..
Hope this helps
public interface AsyncTaskCompletedListener {
public void OnResultSucceeded(String result);
}
public class LoginAsyncTask extends AsyncTask<String, Void, String> {
AsyncTaskCompletedListener mAsyncTaskCompletedListener;
#Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
mAsyncTaskCompletedListener.OnResultSucceeded(result);
}
}
Here is the interface Let Activity A impliment this and from Activity invoke this from onpostexecute
From Activity A
LoginAsyncTask customloginasync = new LoginAsyncTask(getActivity(),
FATCH_USER_LIST, arglist);
customloginasync.execute();
customloginasync.setOnResultsListener(new AsyncTaskCompletedListener() {
#Override
public void OnResultSucceeded(String result, int asyncTaskNo) {
Logger.logInfo("CustomLogin data=========" + result);
ParseAvailableUserData(result);
}
});
Related
so I am trying to learn how to create basic Android applications.
I am stuck on this problem:
The Home Activity has a button that once pressed does two things:
1. Call a REST-Api on my backend-server. The server returns JSON-Objects. The JSON objects are mapped to Java Objects. Finally they are added to a static list.
Start a new intent that launches an Activity with a List Layout.
OnCreate() the ListLayout is filled with data from the static List obtained in step 1.
The Problem is that step 2 does not work as intended because step 1 is asynchronous. So step 2 runs before step 1 finishes to fill the static list with data from the server, resulting in an empty List being displayed on the ListActivity.
How can I wait for step 1 to finish before starting the new Activity so the data is displayed correctly?
Thanks.
Use AsyncTask.
Inside the method doInBackground() put your code for performing API call. After the API call is completed, the method onPostExecute() gets called where you can put the code to go to the next activity.
Check detailed guide here: https://developer.android.com/reference/android/os/AsyncTask
Create an AsyncTask class and override their method as this example :
public class DownloadTask extends AsyncTask<String,String,String>{
#Override
public void onPreExecute()
super.onPreExecute();
{
/// initialize loading animation if you want
}
#Override
public String doInbackGround(String... params)
{
///call your rest request
return resulofyourrequest;
}
#Override
public void onPostExecute(String result)
{
super.onPostExecute(result);
// stop loading animation if you already started one in onPreExecute
///do the stuff you need after you get the result and start your activity here
}
}
and to run your class
new DownloadTask().execute(your_url);
I am working on to speech to text with translation. What I want to do is when the user inputs his/her voice, there will be an automatic translation based on what it is selected in the spinner.
This is the code from my project, I am receiving an error android.os.NetworkOnMainThreadException. And the solution that I found was to put it in async.
I tried searching around the internet and even asked forums, I cannot find a solution to put this code inside a asynctask. This is the code where I want to put in async.
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
Translate translate = TranslateOptions.getDefaultInstance().getService();
TextView translatedText = view.findViewById(R.id.translatedText);
switch (position){
case 1:
Translation enTranslation = translate
.translate(translatedText
.getText()
.toString(), TranslateOption.sourceLanguage("en"), TranslateOption.targetLanguage("en"));
translatedText.setText(enTranslation.getTranslatedText());
break;
case 2:
Translation filTranslation = translate
.translate(translatedText
.getText()
.toString(), TranslateOption.sourceLanguage("en"), TranslateOption.targetLanguage("fil"));
translatedText.setText(filTranslation.getTranslatedText());
break;
case 3:
Translation cebTranslation = translate
.translate(translatedText
.getText()
.toString(), TranslateOption.sourceLanguage("en"), TranslateOption.targetLanguage("ceb"));
translatedText.setText(cebTranslation.getTranslatedText());
break;
}
}
I expected that I won't get android.os.NetworkOnMainThreadException. Thanks in advance :)
Using AsyncTask
You can use an AsyncTask. It has 3 steps to it.
1. onPreExecute() - things you want to do before running doInBackground(). This happens in the UI main thread.
2. doInBackground()- the AsyncTask, will do operations in a background thread (the background thread is created by Android so you don't need to worry about it).
3.onPostExecute() - here you can receive any data from the doInBackground method. The postExecute method is executed again, in the UI main thread.
So you can do any I/O operations in doInBackground(), and return the value you received from the server or any other data source.
How to Declare
To use AsyncTask, you need to extend the Android AsyncTask.
So your own AsyncTask declaration will look like this:
private class MyAsyncTask extends AsyncTask<Void, Void, Void> { ... }
What are the 3 generic arguments you ask?
1. Params - the type of the parameters sent to the task upon execution.
2. Progress - the type of the progress units published during the background computation. (Almost always will be Void, unless you care about the actual progress of the operation. Notice this is Void with a capital letter, and not void as the return type).
3. Result - the type of the result of the background computation.
Full Example
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.interrupted();
}
}
return "Executed";
}
#Override
protected void onPostExecute(String result) {
TextView txt = findViewById(R.id.output);
txt.setText(result);
}
}
In the example, I create a fake, long operation, that you can not run on the UI main thread (because it is a blocking operation).
When the operation is finished, it returns a String, and that same String is received in the onPostExecute() method (and remember, onPostExecute() runs on the UI main thread again). So you can change your UI with the String value you received from the long,blocking operation.
If you want the documentation, here it is:
https://developer.android.com/reference/android/os/AsyncTask
I am getting all the dates between two given dates and then creating fragments for each date in between. The problem is when I use Asynctask and put the method in the doinbackground sometime it works and sometime it doesn't.
Specially when I open Asynctask containing activity from another activity. But on button click inside activity it works with a progressbar.
public class WaitForLoad extends AsyncTask<String, Integer, String>{
#Override
protected void onPreExecute() {
super.onPreExecute();
pro_bar.setVisibility(View.VISIBLE);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
pro_bar.setVisibility(GONE);
}
#Override
protected String doInBackground(String... strings) {
get_con_fro_sta_to_end(dat_ran_sta, dat_ran_end);
return null;
}
}
So according to Asynctask documentation it should be 3 sec. But if I put a entire year in the method it takes about 8 sec to load or so.
So is there any workthrough Asynctask or Can you suggest me an example alternative Like maybe using a handler or so.
I think you're changing Interface from your "get_con_fro_sta_to_end()" method...This is not allowed from a Background Thread and then it should be changed somehow.
AsyncTasks have the "void onProgressUpdate()" that is used to execute code in the UiThread/MainThread every time "publishProgress()" is called from "doInBackground()".
DoInBackground() should NOT touch Interface but just prepare Data/Things to be displayed using "onPostExecute()" (which runs code in the UiThread/MainThread)
I'm developing an app which connects to a server to download location data in order to add some markers to a Map (Google Map).
My problem is that the map is setted before I download my data, so it is completly empty (with no markers).
That data download is performed in another Thread by an AsyncTask and I don't know how to set up my map AFTER all data have been gathered.
Some code, just in case it helps:
HttpGetWorker.java (in charge of get the data):
...
#Override
protected String doInBackground(String... urls) {
try {
return process(urls[0]); //Private method to get data
} catch (IOException ioe) {
Log.e("HttpGetWorker:", ioe.getLocalizedMessage(), ioe);
return "Unable to retrieve web page. URL may be invalid.";
}
}
#Override
protected void onPostExecute(String result) {
for(AsyncTaskListener<String> listener : listeners) {
/**
* Activities which need the server data have to be listeners
* of this task. this processResult method comes from an own
* interface(AsyncTaskListener) and it is implemented in my "main"
* activity (see below)
*/
listener.processResult(result);
}
progressDialog.dismiss(); //just a progress dialog set in onPreExecute method
}
...
Then the listener of this task, my "main" activity MapsActivity.java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
initData(); //Here it is where I get the server Data, complete method below
setUpMapIfNeeded(); // These method set up my map, but before my data is retrieved,
mMap.setOnMarkerClickListener(this);
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
}
private void initData() {
/**
* This HttpDispatcher just creates an instance of the previous
* HttpGetWorker with its execute() to download the data. The "this"
* argument is refered to the current activity to register it in my
* listeners list, as said before
*/
HttpDispatcher dispatcher = new HttpDispatcher(this);
dispatcher.doGet(this);
}
...
// Interface method, here my net data is process
#Override
public void processResult(String result) {
//stuff to process the result, it does it well, but too late.
}
Hope I explain myself.
Thanks everyone!
EDIT:
Relating to the specific problem, sometimes the easiest solutions are the hardest to see...or my head was just a mess when I posted this. I just change an addMarkers() method to my proccessResult(String s), after all data have been fetched...
Anyway, I think the question itself could be interesting for others (synchronization between an AsyncTask and any other activity which calls it). So I let it here.
Cheers!
Don't set the marker before is AsyncTask finished. When task is finished, set marker from onPostExecute().
public class Calculate extends AsyncTask<Void, Integer, Integer> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Integer doInBackground(Void... arg0) {
int a = 1;
int b = 2
return a+b;
}
#Override
protected void onPostExecute(Integer result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}
my app use asynctask class (below), and a function to call this class,
my question is how to know when this class is finished ? every time i check, its always Running !
In your onPostExecute(...) method, you could simply call a method in your caller Activity which would set a boolean terminated_activity to true. You can do this in several ways, most probably the easiest ones are Intents combined with a Handler, or a local BroadcastReceiver.
An example on Handlers and Intents is in an answer I posted today in other question, here.
A nice explaination on local BroadcastReceivers is here.
onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
Directly from the docs