I want to use same AsyncTask in more than 2 activities. It is not practical solution to write same code in every activity. My question is,
How can I create class with AsyncTask GLOBALLY and use it any where?
My second IMPORTANT question is:
How can I get return value from onPostExecution() to every activity?
To run the asynctask from anywhere you could use otto:
If you are using android studio you add it the dependency or eclipse you download it as a jar : refer to this link : http://square.github.io/otto/
First you declare the singltone:
public class MyBus {
private static final Bus BUS = new Bus();
public static Bus getInstance() {
return BUS;
}
}
Then you create a separate asynctask class :
public class MyAsyncTask extends AsyncTask<Void, Void, String> {
#Override protected String doInBackground(Void... params) {
Random random = new Random();
final long sleep = random.nextInt(10);
try {
Thread.sleep(sleep * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "Slept for " + sleep + " seconds";
}
#Override protected void onPostExecute(String result) {
MyBus.getInstance().post(new AsyncTaskResultEvent(result));
}
}
Then from inside the activity : you register the Bus and call new MyAsyncTask().execute();
Do not forget to unregister the bus on destroy:
Refer to this tutorial for more help: http://simonvt.net/2014/04/17/asynctask-is-bad-and-you-should-feel-bad/
public class MyAsyncTask extends AsyncTask<Void, Void, String> {
private OnResultReceived mListner;
public MyAsyncTask(OnResultReceived listner){
this.mListner=listner;
}
#Override protected String doInBackground(Void... params) {
//DO YOUR STUFF
String data="Test";
return data;
}
#Override protected void onPostExecute(String result) {
if(mListner!=null)mListner.onResult(result);
}
public interface OnResultReceived{
public void onResult(String result);
}
}
in Activity
new MyAsyncTask(new OnResultReceived{
public void onResult(String data){
//Your Result from AsyncTask
}
}).execute();
I want to do background tasks in Android to send a request to an API, but I can't get it to work the way I want.
These are my scripts:
Activity class
public class SampleActivity extends Activity {
private ApiRequest ar;
private String parameters;
...
private void callApi() {
this.ApiRequest = new ApiRequest(this.parameters);
}
}
ApiRequest class
public class ApiRequest {
private String response;
public ApiRequest(parameters) {
new BackgroundTask().execute(parameters);
}
protected class BackgroundTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... args) {
// Do stuff here
}
#Override
protected void onPostExecute(String response) {
this.response = response;
}
}
Somehow, I can't seem to update the response string from the onPostExecute method. I know onPostExecute is supposed to update the UI thread, but I want to update the object first, which essentially runs in the UI thread (I think). How is this done? I can't find anything about it really.
#Override
protected void onPostExecute(String response) {
this.response = response;
}
In this scope, this refers to the instance of BackgroundTask and NOT to ApiRequest. I'm surprised your code even compiles.
Change it to ApiRequest.this.response = response.
I would like to pass a single string into an asynctask. Could anyone show me how it is done? my getEntity needs The method getEntity(Activity, String, EntityGetListener) but I keep passing this String[]
String pass= story.get(position).getEntity();
new RemoteDataTask().execute(pass);
private class RemoteDataTask extends AsyncTask<String, String, Long> {
#Override
protected Long doInBackground(String... params) {
// TODO Auto-generated method stub
EntityUtils.getEntity(activity, params, new EntityGetListener() {
#Override
public void onGet(Entity entity) {
viewcount = entity.getEntityStats().getViews();
}
#Override
public void onError(SocializeException error) {
}
});
return null;
}
}
You already have this
new RemoteDataTask().execute(pass); // assuming pass is a string
In doInbackground
#Override
protected Long doInBackground(String... params) {
String s = params[0]; // here's youre string
... //rest of the code.
}
You can find more info #
http://developer.android.com/reference/android/os/AsyncTask.html
Update
Asynctask is depecated. Should be using kotlin coroutines or rxjava or any other threading mechanism as alternatives.
You can build AsyncTask with a constructor.
public class RemoteDataTask extends AsyncTask<String, String, Long> {
private String data;
public RemoteDataTask(String passedData) {
data = passedData;
}
#Override
protected String doInBackground(Context... params) {
// you can access "data" variable here.
EntityUtils.getEntity(activity, params, new EntityGetListener() {
#Override
public void onGet(Entity entity) {
viewcount = entity.getEntityStats().getViews();
}
#Override
public void onError(SocializeException error) {
}
});
return null;
}
}
In the application (Activity, Service etc), you can use;
private RemoteDataTask mTask;
private void doStuff(){
String pass = "meow"; // story.get(position).getEntity();
mTask = new RemoteDataTask(pass);
mTask.execute();
}
How to pass more values in the doInBackground
My AsyncTask looks like this.
private class DownloadFile extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... sUrl) {
{
}
}
Is it possible somehow to pass more values on my protected String DoInBackground
for example: protected String doInBackground(String... sUrl, String... otherUrl, Context context)
And how to execute the AsyncTask after? new DownloadFile.execute("","",this) or something?
you can send multiple parameters as you can send them as varargs. But you have to use same Type of parameter. So to do what you are trying you can follow any of the followings
Option 1
you can use a setter method to set some value of the class member then use those in doInBackGround. For example
private class DownloadFile extends AsyncTask<String, Integer, String> {
private Context context;
public void setContext(Context c){
context = c;
}
#Override
protected String doInBackground(String... sUrl) {
{
// use context here
}
}
Option 2
Or you can use constructor to pass the values like
private class DownloadFile extends AsyncTask<String, Integer, String> {
private Context context;
public DownloadFile (Context c){
context = c;
}
#Override
protected String doInBackground(String... sUrl) {
{
// use context here
}
}
String... sUrl
the three consecutive dots meaning more then one String. The dots are varargs
And how to pass the Context?
you can force it adding a constructor that takes the Context as parameter:
private Context mContext;
public void setContext(Context context){
if (context == null) {
throw new IllegalArgumentException("Context can't be null");
}
mContext = context;
}
you can do something like this inside your doInBackground method:
String a = sUrl[0]
String b = sUrl[1]
execute AsyncTask in this way:
new DownloadFile().execute(string1,string2);
the first value : sUrl[0] will be the one passed from string1 and
surl[1] will be the second value passed i.e string2 !
Yes you can pass more values in constructor but not in doInBackground
Try this way
new DownloadFile(String sUrl,String other Url,Context context).execute();
Async Task
private class DownloadFile extends AsyncTask<String, Integer, String> {
public DownloadFile(String url,String url2,Context ctx)
{
}
#Override
protected String doInBackground(String... sUrl) {
{
}
}
You cannot, for the following reasons :
protected String doInBackground(String... sUrl, String... otherUrl, Context context)
is not a valid method signature. The dots notations (Varargs) can only be used as the last parameter of the method. This restriction is because otherwise it would make polymorphism much more complex. In fact, how would java know which of your Strings go to sUrl, and which goes to otherUrl?
Moreover, doInBackground overrides a method from AsyncTask. As such, you cannot change the method signature.
What you can do, however, is make those values members of your class and pass in the constructor of your DownloadFile class or add setters to set them before calling execute.
you can use constructor
private class DownloadFile extends AsyncTask<String, Integer, String> {
private Context context;
public void DownloadFile(Context c,String one, int two){
context = c;
}
#Override
protected String doInBackground(String... sUrl) {
{
// use context here
}
}
new DownloadFile().execute(Str1,str2,str3,........);
this is one way to pass more url... if you want send more values in doinbackground method..
public class DownloadFile extends AsyncTask<DataHolders, Integer, String> {
public class DataHolders {
public String url;
public String myval;
}
#Override
protected String doInBackground(DataHolders... params) {
return null;
}
}
you can call the class with
DataHolders mhold = new DataHolders();
new DownloadFile().execute(mhold,mhold2,mhold3,........);
Ypu can create constructor to pass different type parameters and also strings data using String......str
private class DownloadTask extends AsyncTask<String, Integer, String> {
private Context context;
byte[] byteArray;
public DownloadTask (Context c,byte[] byteArray){
context = c;
byteArray=byteArray;
}
#Override
protected String doInBackground(String... str) {
{
// use context here
System.out.println(param[0]);
}
}
new DownloadTask(context,bytearray).excute("xyz");
new DownloadFile().execute("my url","other parameter or url");
private class DownloadFile extends AsyncTask<String, Integer, String> {
#Override
protected String doInBackground(String... sUrl) {
{
try {
return downloadContent(sUrl[0], sUrl[1]); // call
} catch (IOException e) {
return "Unable to retrieve data. URL may be invalid.";
}
}
}
Basically I am wanting to get access to a variable that has been assigned in doInBackground in a different class but I am not sure how to do this here. Below is my relevant class structure. This is for an android application. Thanks.
public class CreateNewPlayers extends AsyncTask<String, String, String> {
public String doInBackground(String... args) {
String playerid = playerid1.getText().toString();
you can get access to intrim data using publishProgress() and onProgressUpdate()
public class CreateNewPlayers extends AsyncTask<String, String, String> {
public SomeOtherClass soc = null;
#Override
public String doInBackground(String... args) {
String playerid = playerid1.getText().toString();
publishProgress(playerid);
#Override
public String onProgressUpdate(String... args) {
super.onProgressUpdate(args);
soc.setPlayerID(args[0]);
soc.DoSomething();
}
Edit
more complete
public class SomeOtherClass {
protected String thisPlayerID = null;
public setPlayerID (String pid) {
thisPlayerID = pid;
}
public DoSomthing () {
// act on data
}
}
public class mainActivity extend Activity {
public CreateNewPlayers cnp = new CreateNewPlayers();
public SomeOtherClass soc = new SomeOtherClass();
#Override
protected void onCreate(Bundle data) {
super.onCreate(data);
cnp.soc = soc;
cnp.exectue("")
}
}