How to create AsyncTask for global use? - android

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();

Related

How to pass a value to AsyncTask?

What is the proper way in the following code (it's a bit complicated structure to me) to get url from the method gotUrl() to the doInBackground() method of AsyncTask in order to use it in onPostExecute(), after the doInBackground() method has completed its task?
public class PlayerActivity extends CustomActivity implements
ProblemListener{
public class PlayChannel extends
AsyncTask<CustomChangeChannel, String, String> {
#Override
protected String doInBackground(CustomChangeChannel... params) {
initOctoshapeSystem();
return url;
}
#Override
protected void onPostExecute(String url){
}
}
public void initOctoshapeSystem() {
os = OctoStatic.create(this, this, null);
os.setOctoshapeSystemListener(new OctoshapeSystemListener() {
#Override
public void onConnect() {
mStreamPlayer = setupStream(OCTOLINK);
mStreamPlayer.requestPlay();
}
});
}
public StreamPlayer setupStream(final String stream) {
StreamPlayer sp = os.createStreamPlayer(stream);
sp.setStatusChangedListener(new StatusChangedListener() {
#Override
public void statusChanged(byte oldStatus,
final byte newStatus) {
runOnUiThread(new Runnable() {
#Override
public void run() {
//todo
}
});
}
});
sp.setListener(new StreamPlayerListener() {
#Override
public void gotUrl(String url) {
//String to be passed
}
});
return sp;
}
}
AsyncTask<Param1, Param2, Param3>
Param 1 is the param that you pass into your doInBackground method.
Param 2 is what you want to get while the AsyncTask working.
Param 3 is what you want to get as result.
You can declare all them as Void.
AsyncTask<Void, Void, Void>
In your case you want to pass String URL to your doInBackground, so:
AsyncTask<String, Void, Void>
Pass your URL String when you call the execute.
mAsyncTask.execute("your url");
Then get it in the doInBackground:
protected Void doInBackground(String... params) {
String yourURL = params[0];
return null;
}
change this
public class PlayChannel extends
AsyncTask<CustomChangeChannel, String, String>
to this
public class PlayChannel extends
AsyncTask<String, String, String>
and then use
PlayChannel channel = new PlayChannel(url);

How to pass data from an asynchronous task to an activity that called it?

I am new to Android. I am using Sockets in an asynchronous task and I wish to pass data back to the activity that called it. But I do not want the asynchronous task to handle the UI. I just wish to pass data.
The class that e![enter image description here][1]xtends async task is not a part of the class that extends activity
My activity has 2 buttons. When the button is clicked, async task is called and corresponding changes should be made to rest of the activity.
From How do I send data back from OnPostExecute in an AsyncTask:
class YourActivity extends Activity {
private static final int DIALOG_LOADING = 1;
public void onCreate(Bundle savedState) {
setContentView(R.layout.yourlayout);
new LongRunningTask1().execute(1,2,3);
}
private void onBackgroundTaskDataObtained(List<String> results) {
//do stuff with the results here..
}
private class LongRunningTask extends AsyncTask<Long, Integer, List<String>> {
#Override
protected void onPreExecute() {
//do pre execute stuff
}
#Override
protected List<String> doInBackground(Long... params) {
List<String> myData = new ArrayList<String>();
for (int i = 0; i < params.length; i++) {
try {
Thread.sleep(params[i] * 1000);
myData.add("Some Data" + i);
} catch(InterruptedException ex) { }
}
return myData;
}
#Override
protected void onPostExecute(List<String> result) {
YourActivity.this.onBackgroundTaskDataObtained(result);
}
}
}
Yes you can use handler to communicate between AsyncTask and Activity, see following example, it will help,
#Override
protected void onPostExecute(Object result) {
super.onPostExecute(result);
Message message = new Message();
Bundle bundle = new Bundle();
bundle.putString("file", pdfPath);
message.setData(bundle);
handler.sendMessage(message); // pass handler object from activity
}
put following code into Activity class
Handler handler = new android.os.Handler() {
#Override
public void handleMessage(Message msg) {
String filePath = msg.getData().getString("file"); // You can change this according to your requirement.
}
};
If you dont't aware of Handler class then first read following link, it will help you
https://developer.android.com/training/multiple-threads/communicate-ui.html
There are different way to pass data back to activity. As explained below
Suppose u have one class
public class Socket {
private Activity activity;
//create interface
public interface OnAyscronusCallCompleteListener{
public void onComplete(/*your data as parameter*/);
}
private void setAsyncListener(Activity activity){
this.activity = activity;
}
//rest of your code
// send back data to activity
activity.onComplete(/* your data */)
}
//Now your activity
class YourActivity extends Activity implements Socket.OnAyscronusCallCompleteListener {
// rest of your activity life cycle methods
onCreate(Bundle onSaved)
{Socket socket = new Socket();
socket.setAsyncListener(this);
}
public void onComplete(/*your data*/){
// perform action on data
}
}
In your Activity Class
new YourAsyncTask().execute("String1","String2","12");
Your AsyncTask
AsyncTask<Params, Progress, Result>
private class YourAsyncTask extends AsyncTask<String, Void, Void > {
protected Long doInBackground(String... s) {
String s1 = s[0]; //="String1";
String s2 = s[1]; //="String2";
int s1 = Integer.parseInt(s[2]); //=3;
}
protected void onProgressUpdate(Void... values) {
}
protected void onPostExecute() {
}
}
A great explanation is here
Example to implement callback method using interface.
Define the interface, NewInterface.java.
package javaapplication1;
public interface NewInterface {
void callback();
}
Create a new class, NewClass.java. It will call the callback method in main class.
package javaapplication1;
public class NewClass {
private NewInterface mainClass;
public NewClass(NewInterface mClass){
mainClass = mClass;
}
public void calledFromMain(){
//Do somthing...
//call back main
mainClass.callback();
}
}
The main class, JavaApplication1.java, to implement the interface NewInterface - callback() method. It will create and call NewClass object. Then, the NewClass object will callback it's callback() method in turn.
package javaapplication1;
public class JavaApplication1 implements NewInterface{
NewClass newClass;
public static void main(String[] args) {
System.out.println("test...");
JavaApplication1 myApplication = new JavaApplication1();
myApplication.doSomething();
}
private void doSomething(){
newClass = new NewClass(this);
newClass.calledFromMain();
}
#Override
public void callback() {
System.out.println("callback");
}
}
Then regarding your answer, in actually you have a 2 possibilities... The first one is the answer from #Rodolfoo Perottoni and the other possibility are correctly, read this post please!
I prefer the second way because I can update when I need it.
I would create a inner class in the MainActivity that extends the AsyncTask and voila all data is there already by getters.

Is there any way to get result from an asynctask class in a non activity class?

I am new in Android development. Is there any way to get result from an AsyncTask in a non-activity class? I know about the standard procedure of using an interface and getting the parsed result from the onPostExecute. But this is not working, using context instead of activityname.this in the non activity class(where I sent the context as a parameter). I am building a library and it is required for that. Any help would be greatly appreciated.
in MainActivity.java --->
Library l1 = new Library();
l1.init(portalHitter, "security certificate file name");
if(l1.getLoginStatus(MainActivity.this)){
start intent to go to another activity
}
in Library.java --->
CommonMethods commonMethods;
public void init(String portalHitter, String certName){
.....
}
public boolean getLoginStatus(Context context){
if(clint is initialized){
commonMethods = new CommonMethods(context, CommonValues.LOGIN_REQUEST);
}else{
/* error */
}
if(CommonValues.LOGIN_STATUS)
return true;
else
return false;
}
in CommonMethods.java --->
public CommonMethods(Context context, int reqest_code){
this.context = context;
this.request_for_which_service = reqest_code;
executeService();
}
public void executeService(){
switch(request_for_which_service){
case CommonValues.LOGIN_REQUEST:
loginAsyncTask = new LoginAsyncTask(context, params ...);
loginAsyncTask.execute();
loginAsyncTask.delegate = context;
break;
}
}
in LoginAsyncTask.java --->
public class LoginAsyncTask extends AsyncTask<String, String, String>{
...
public LoginCompleteInterface delegate = null;
public LoginAsyncTask(Context context, params...){
...
}
doInBacground(){
..do work..
return response;
}
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(exception_identifier == 0 || exception_identifier == 1 || exception_identifier == 2){
/* display dialog for exception on timeout, socket exceptions etc */
}else{
String tempLoginStatus = loginStatus(result);
delegate.loginCompleted(tempLoginStatus);
loginProgress.dismiss();
}
}
loginStatus(String result){
// parse and return success and failure //
}
...
}
and in the LoginCompleteInterface.java --->
public interface LoginCompleteInterface {
void loginCompleted(String output);
}
Now, if commonmethods was an activity, then it did not create a problem, but now it is creating problem, even after passing the context from MainActivity.java
loginAsyncTask.delegate = context; line.
You can use Event Bus for same .
You can set a bus and subscribe to a class where you want to have the callback.
Some common Event Bus are
TinyBus
Otto
You can get with the help of Interface.
Create an Interface which has method getResponse(String data).
implements Interface to your Activity.
when you call AsyncTask from Activity pass then reference of Interface.
In AsyncTask onPostExecute() call then Interface method and pass the data as parameter.
you will get the data in override method of interface in Activity.
Code
Interface
public interface MyInterface {
public void getResponse(String data);
}
Activity Class:
public class MainActivity extends AppCompatActivity implements MyInterface {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// CAll Async Task
new AsyncTaskClass(this).execute();
}
#Override
public void getResponse(String data) {
Toast.makeText(this, data, Toast.LENGTH_SHORT).show();
}
AsyncTask Class
public class AsyncTaskClass extends AsyncTask<String, String, String> {
private MyInterface mInterface;
public AsyncTaskClass(MyInterface reference) {
mInterface = reference;
}
#Override
protected String doInBackground(String... params) {
return "this data";
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
// call getResponse(_) of interface.
mInterface.getResponse(s);
}
}
----------------------For non-Activity Class--------------
public class SimpleClass implements MyInterface
{
public void someMethod()
{
// CAll Async Task
new AsyncTaskClass(this).execute();
}
}
Interface and AsyncTask class will be the same.

AsyncTask in separate object

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.

Android Asynctask passing a single string

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();
}

Categories

Resources