I have a program that used async task everytime the button is clicked... I dont want to keep typing the WHOLE AsyncTask everytime it is clicked.. That will be to tedious. What is a better way i can do this?
Here is some source code.
new AsyncTask<Void, Integer, Void>(){
#Override
protected Void doInBackground(Void... arg0) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
text1.setText("Nice to meet you "+name);
dismissDialog(typeBar);
}
#Override
protected void onPreExecute() {
typeBar = 0;
showDialog(typeBar);
}
}.execute((Void)null);
}
});
}
Create a new class that extends AsyncTask:
public class MyTask extends AsyncTask<Void, Integer, Void>
{
#Override
protected Void doInBackground(Void... arg0)
{
}
}
Then whereever you need it just do this:
new MyTask.execute();
Thats it! Have fun!
Put it in a public or private class. You can then reference/instantiate it based on the name of the newly made class.
Related
I want to run two connections using Android Native :
public class MyPublicClass extends AppCompatActivity {
here is the first class
private class GetNextQuestionIndex extends AsyncTask<String, Void, Void> {
//some code
protected Void doInBackground(String... params) {
URL url = new URL("url1");
//some code to initialize connection and get the output
MyPublicClass.this.runOnUiThread(new Runnable() {
#Override
public void run() {
mytxtview.setText(output1)
System.out.println("1");
progress.dismiss();
}
});
Here is the second class
private class GetLibelleOfQuestion extends AsyncTask<String, Void, Void> {
//some code
protected Void doInBackground(String... params) {
URL url = new URL("url2");
//some code to initialize another connection and get another output
MyPublicClass.this.runOnUiThread(new Runnable() {
#Override
public void run() {
mytxtview.setText(output2)
System.out.println("2");
progress.dismiss();
}
});
}//the end of the public class
but when i run my code its give me
2 1
how can I get
1 2
?
which means execute the run of GetNextQuestionIndex before the run of GetLibelleOfQuestion
onCreateActivity(...){
...
ShowDialog();
AsyncTask1(...).execute();
}
public void callAsyncTask2(){
AsyncTask2(...).execute();
}
class AsyncTask1(...){
....
onPostExecute(...){
activity.callAsyncTask2();
}
}
class AsyncTask2(...){
....
onPostExecute(...){
activity.dismissDialog();
}
}
Hope it helps.
This is the proper ways to call 2 asyn task .
private class GetNextQuestionIndex extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
URL url = new URL("url2");
//run your background task
return results;
}
#Override
protected void onPostExecute(String result) {
mytxtview.setText(output1)
System.out.println("1");
new GetLibelleOfQuestion ().execute("");
}
#Override
protected void onPreExecute() {
progress.dismiss();
}
#Override
protected void onProgressUpdate(Void... values) {}
}
}
//Second asyn task
private class GetLibelleOfQuestion extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
URL url = new URL("url2");
//run your background task
return results;
}
#Override
protected void onPostExecute(String result) {
mytxtview.setText(output2)
System.out.println("2");
progress.dismiss();
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
}
oncreate method call or button click , where you want
new GetNextQuestionIndex ().execute("");
You can use set the second thread to sleep for a moment (waiting for the first thread to be executed):
private class GetLibelleOfQuestion extends AsyncTask<String, Void, Void> {
...
MyPublicClass.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Thread.sleep(WAIT_TIME_IN_MILLISECONDS);
mytxtview.setText(output2)
System.out.println("2");
progress.dismiss();
}
});
}//the end of the public class
I have a progress dialog, I want it to show and dismiss when my method has finished executing. now, I have this:
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Downloading...");
progressDialog.show();
new Thread(new Runnable() {
#Override
public void run() {
try{
DownloadMethod(s);
progressDialog.dismiss();
}catch (Exception e){
Toast.makeText(prefs.this, "We can't reach the data...Try again", Toast.LENGTH_SHORT).show();
}
}
}).start();
My method DownloadMethod is executed but never shows the dialog.
Actually, It must be throwing an exception with progressDialog.dismiss(); call because you cannot update UI from a worker thread, instead use AsyncTask
e.g pass parameter to constructor
private class DownloadFilesTask extends AsyncTask<Void, Void, Void> {
TypeOf_S s;
public DownloadFilesTask(TypeOf_S s){
this.s = s;
}
#Override
protected Void doInBackground(Void... obj) {
DownloadMethod(s);
return null;
}
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
}
}
and call it like new DownloadFilesTask(s).execute();
or with generic parameter
private class DownloadFilesTask extends AsyncTask<TypeOf_S, Void, Void> {
#Override
protected Void doInBackground(TypeOf_S... obj) {
DownloadMethod(obj[0]);
return null;
}
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
}
}
and call it like new DownloadFilesTask().execute(s);
progressDialog.dismiss();is throwing an exception so move your code inside runOnUiThread() method like this:
runOnUiThread(new Runnable() {
#Override
public void run() {
progressDialog.dismiss();
}
});
as suggested by Pavneet you can use async task as follows where AsyncTask<String, void, String> corresponds to the input type progress value and last is result value you are interested so give data types accordingly.
private class DownloadFilesTask extends AsyncTask<String, void, String> {
protected String doInBackground(String... urls) {
//here do the actual downloading instead of calling the DownloadMethod(s)
}
protected void onPreExecute() {
//here show the dialog
progressDialog.show();
}
protected void onPostExecute(String result) {
//here hide the dialog
progressDialog.dismiss();
}
}
and where you are calling the download function you just call this
progressDialog = new ProgressDialog(this);
progressDialog.setMessage("Downloading...");
new DownloadFilesTask().execute(s);
//here s is assumed to be string type you can give anything
I have an IME service class and a long operation method in it. I want to run the LongOperation task in a asyncTask class that is in the IME Service class.
public class Myimeservice extends InputMethodService
implements KeyboardView.OnKeyboardActionListene {
//...
//some code here....
//...
public void setDictionary(){
//....
}
private class LongOperation extends AsyncTask<String, Void, String> {
private Myimeservice parent;
public LongOperation(Myimeservice pim){
parent = pim;
}
#Override
protected String doInBackground(String... params) {
Myimeservice tmp = new Myimeservice();
tmp.setDictionary();
return "Executed";
}
#Override
protected void onPostExecute(String result) {
//app.hideLoading();
}
#Override
protected void onPreExecute() {
//app.showLoading();
}
#Override
protected void onProgressUpdate(Void... values) {}
}
When i run it, the application forced to close. please help me.
I think the error is somewhere in your public void setDictionary() method.
I assume that you are manipulating a variable that is bound to the UIThread/MainThread, the application will crash since doInBackground is on another Thread.
Instead make the setDictionary() method return the dictionary and return it instead of "Executed" in doInBackground().
This will call the onPostExecute(Object result) which is run on UIThread/MainThread.
Something like this:
private class LongOperation extends AsyncTask<String, Void, Dictionary> {
#Override
protected Dictionary doInBackground(String... params) {
Myimeservice tmp = new Myimeservice();
Dictionary dict = tmp.setDictionary();
return dict;
}
#Override
protected void onPostExecute(Dictionary result) {
//do what ever you meant to do with it;
}
}
If you are not expecting any result from it you can just do:
AsyncTask.execute(new Runnable() {
#Override
public void run() {
tmp.setDictionary();
}
});
I use the Runnable instead of AsyncTask and the problem solved.
final Runnable r = new Runnable(){
public void run(){
setDictionary();
}
};
this code is in onCreate() method of service.
Tanks a lot Tristan Richard.
Intuitivly, I know, when it throws the IllegalStateException. But in my case, I can't, though, probably guess, where is trouble in the source. I dare say, trouble lines are there:
private class LoadMoreDataTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
if (isCancelled()) {
return null;
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
OFFSET = OFFSET + COUNT;
getWallsData();
return null;
}
#Override
protected void onPostExecute(Void result) {
mPostListAdapter.notifyDataSetChanged();
wallPostsList.onLoadMoreComplete();
super.onPostExecute(result);
}
#Override
protected void onCancelled() {
wallPostsList.onLoadMoreComplete();
}
there's a logcat message:
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(2131099757, class com.costum.android.widget.LoadMoreListView) with Adapter(class android.widget.HeaderViewListAdapter)]
The problem is fixed:the answer was found there !
what I did? I have added, the switcher, Boolean LOADMORE SWITCHER=false; as global visibility and replaced mPostListAdapter.notifyDataSetChanged(); from doInBackground() to getWallsData().
private Boolean LOADMORE SWITCHER=false;
....
private class LoadMoreDataTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
if (isCancelled()) {
return null;
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
OFFSET = OFFSET + COUNT;
LOADMORE=true;
getWallsData();
return null;
}
#Override
protected void onPostExecute(Void result) {
// mPostListAdapter.notifyDataSetChanged(); was replaced to getWallsData() body
wallPostsList.onLoadMoreComplete();
super.onPostExecute(result);
}
#Override
protected void onCancelled() {
wallPostsList.onLoadMoreComplete();
}
}
.....
getWallsData(){
...
if(LOADMORE){
mPostListAdapter.notifyDataSetChanged();
LOADMORE=false;
}
}
I'm very-very glad to say: I haven't this problem anymore:
java.lang.IllegalStateException: The content of the adapter has changed but ListView did not receive a notification. Make sure the content of your adapter is not modified from a background thread, but only from the UI thread. [in ListView(2131099757, class com.costum.android.widget.LoadMoreListView) with Adapter(class android.widget.HeaderViewListAdapter)]
I have a method searchPlace() that updates a static Arrays of custom Place Object in a class A (FindItOnMap) with a google map, and a method updateMap() that updates the various geopoints .
I invoke these methods Button.onClick and all works properly.
Since these methods use internet data this operation could take a while, I have been looking for the implementation of an inner class B(YourCustomAsyncTask) inside the class A that extends AsyncTask to show a waiting dialog during the processing of these two methods
An user suggested a solution in this form (that apparently seems valid):
public class FindItOnMap extends MapActivity {
static Place[] foundResults;
private ProgressDialog dialog;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ricerca_condominio);
mapView = (MapView)findViewById(R.id.mapView);
...........
((ImageButton) findViewById(R.id.btSearch)).setOnClickListener(mSearchListenerListener);
}
OnClickListener mSearchListener = new OnClickListener() {
public void onClick(View v) {
String location=editorLocation.getText().toString();
String name=editorName.getText().toString();
//Call the AsyncTask here
new YourCustomAsyncTask().execute(new String[] {name, location});
}
};
private class YourCustomAsyncTask extends AsyncTask <String, Void, Void> {
#Override
protected void onPreExecute() {
dialog = new ProgressDialog(Main.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
}
#Override
protected Void doInBackground(String... strings) {
try {
search(strings[0], string[1]);
return null;
} catch(Exception e) {
}
}
#Override
protected void onPostExecute(Void params) {
updateMapWithResult();
dialog.dismiss();
//result
}
.....
}
The waiting dialog is showed and the methods are invoked in background,
However for some strange reason the static list foundResults results filled with various null items...
How is this possible?
If I invoke the method search(location, name) outside the inner class all works properly and updateMapWithResult(); updates all geopoint, so these two methods are ok. Only if I try to invoke this in the inner class the json calls seem to be working but the static variable foundResults is filled with null elements and the program doesn't work properly.
Any suggestion?
I have understand where is the problem.
You have to run the search method on the UI thread.
So change this code block:
#Override
protected Void doInBackground(String... strings) {
try {
search(strings[0], string[1]);
return null;
} catch(Exception e) {
}
}
with this
#Override
protected Void doInBackground(final String... strings) {
try {
runOnUiThread(new Runnable() {
public void run() {
search(strings[0], string[1]);
return null;
}
});
} catch(Exception e) {
e.printStackTrace();
}
}
And all should works correctly.
Here is one problem:
OnClickListener mSearchListener = new OnClickListener() {
public void onClick(View v) {
String Location=editorLocation.getText().toString();
String name=editorName.getText().toString();
//Call the AsyncTask here
new YourCustomAsyncTask().execute(new String[] {name, location});
}
Your Location should be location.
Also here:
#Override
protected Void doInBackground(String... strings) {
try {
search(strings[0], string[1]);
} catch(Exception e) {
}
}
#Override
protected void onPostExecute(Void params) {
updateMapWithResult();
dialog.dismiss();
//result
}
In doInBackground you don't assign a value after you search. You might try this:
#Override
protected Void doInBackground(String... strings) {
try {
search(strings[0], string[1]);
String name = string[0];
String location = string[1]
} catch(Exception e) {
}
}
Or something else that will assign value while it runs. As it is, it appears that you just search, and then nothing else.
The reason foundResults is null is because you don't ever assign it a value.
There is nothing wrong with your AsyncTask. Please include the search() method.