I have a AsyncTask class that connect to web service to get something and then print to the screen.
Here is my code:
public class GetCreditAsyncTask extends AsyncTask<Object, Boolean, String>{
private MainActivity callerActivity;
private String credit;
public GetCreditAsyncTask(Context context){
callerActivity = (MainActivity )context;
}
#Override
protected String doInBackground(Object... params) {
.....//do something and get the credit
}
#Override
protected void onPostExecute(String response) {
callerActivity.txtView.setText(credit);
}
}
It works perfect but now, I have one more Activity ProfileActivity
which also want to use GetCreditAsyncTask to get the credit and print it to the txtView,
but at the begining of GetCreditAsyncTask, I cast the callerActivity to MainActivity.
The question is how to just use one AsyncTask class so that I can call it and get the credit.
You can define an interface that both activities implement. Instead of casting to MainActivity, you must cast to this interface.
public interface ActivityListener {
public void setText(String text);
}
public class MainActivity extends Activity implements ActivityListener {
...
public void setText(String text) {
TextView tv = findViewById(R.id.main_text);
tv.setText(text);
}
}
public class SecondActivity extends Activity implements ActivityListener {
...
public void setText(String text) {
TextView tv = findViewById(R.id.secondary_text);
tv.setText(text);
}
}
public class GetCreditAsyncTask extends AsyncTask<Object, Boolean, String>{
private ActivityListener callerActivity;
private String credit;
public GetCreditAsyncTask(Context context){
callerActivity = (ActivityListener) context;
}
#Override
protected String doInBackground(Object... params) {
.....//do something and get the credit
}
#Override
protected void onPostExecute(String response) {
callerActivity.setText(credit);
}
}
Related
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);
This is what i have so far:
I have 3 activities
In every activity is a connection to a Database to send and
recieve data
Every input (String) and Output (JSONObject) works the same
At first i implemented an asynctask in every activity to send and recieve the data
The result is handeld in the activity that started the task
To reduce the code i transfered the asynctask to an extra class
Every activity implements an interface "AsyncResponse"
My Problem is:
With the implementation i use delegate to set a reference to the calling activity. I cant find a way to change the delegation. If i want to create a new asynctask in my second activity and try to delegate it, it shows an incompatible types error.
So is there a way that i can send the asyncresults back to a specific calling activity?
Example for the implementation
public class MainActivity extends AppCompatActivity implements AsyncResponse
public void startAsync(String[] stringArray)
{
AsyncTaskRequest objMyTask = new AsyncTaskRequest(this);
// objMyTask.delegate = this; // *.delegate in another Task in not possible
objMyTask.execute(stringArray);
}
AsyncResponse Interface
public interface AsyncResponse
{
void taskDone(JSONObject x);
}
Example for the AsyncTask
public class AsyncTaskRequest extends android.os.AsyncTask<String,
Void, JSONObject>
{
//MainActivity delegate = null;
private AsyncResponse delegate;
public AsyncTaskRequest(AsyncResponse delegation)
{
delegate=delegation;
}
protected JSONObject doInBackground(String... postData)
{.......}
#Override
protected void onPostExecute(JSONObject x)
{
delegate.taskDone(x);
}
}
You can use a listener inside you ASyncTask
In your ASyncTask:
public class AsyncTaskRequest extends android.os.AsyncTask<String,
Void, JSONObject>
{
private OnTaskCompleted listener;
public interface OnTaskCompleted{
void onTaskCompleted(Boolean output);
}
private AsyncResponse delegate;
public AsyncTaskRequest(AsyncResponse delegation)
{
delegate=delegation;
}
protected JSONObject doInBackground(String... postData)
{.......}
#Override
protected void onPostExecute(JSONObject x)
{
delegate.taskDone(x);
if (listener != null)
listener.onTaskCompleted(result);
}
}
and in your java file call this function:
public OnTaskCompleted listener =new OnTaskCompleted() {
public void onTaskCompleted(Boolean output) {
//your code here
}
};
I tried to call the "AsyncTask" class from another class called "MainActivity" but "AsyncTask" Class is inside the class called "SiteAdapter". I tried to pass a reference but it not working. How could do that?
Main Activity:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.i("StackSites", "OnCreate()");
setContentView(R.layout.activity_main);
//Call the class AsyncTask
new GetAddressTask(this).execute(); // <----ERROR - GetAddressTask cannot be resolved to a type
}
}
AsyncTask inside SitesAdapter class:
public class SitesAdapter extends ArrayAdapter<StackSite> {
...//PROCESS
public class GetAddressTask extends AsyncTask<String, Void, String> {
Context mContext;
public GetAddressTask(Context context) {
super();
mContext = context;
}
//Pass a reference to MainActivity
private MainActivity mainActivity; // <--- WARNING - The value of the field SitesAdapter.GetAddressTask.mainActivity is not used
public GetAddressTask(MainActivity mainActivity)
{
this.mainActivity = mainActivity;
}
#Override
protected String doInBackground(String... arg0) {
...
}
#Override
protected void onPostExecute(String result) {
...
}
}
}
First of all, MainActivity is not a class that you can not define an object from. It extends Activity.
Change your AsyncTask class with it;
public static class GetAddressTask extends AsyncTask<String, Void, String> {
Context mContext;
public GetAddressTask(Context context) {
super();
mContext = context;
}
#Override
protected String doInBackground(String... values) {
// If you want to use 'values' string in here
String values = values[0];
}
#Override
protected void onPostExecute(String result) {
...
}
}
Then call this with it;
String values = ""; //You can pass any string value to GetAddressTask with that parameter
//Call the class AsyncTask
new SitesAdapter.GetAddressTask(this).execute(values);
make GetAddressTask static:
public static class GetAddressTask
Try this, this is working for me.
Just create a method in your SitesAdapter class and call it from your MainActivity like this :
new SitesAdapter().start(MainActivity.this);
now in your SitesAdapter class do this :
private Context mContext;
public void start(){
mContext = context;
new GetAddressTask().execute();
}
May this help you
You could make it static then call it with
SitesAdapter.GetAddressTask myClass = new SitesAdapter.GetAddressTask();
myClass.execute();
But, if you are going to be needing this in multiple activities, then it is probably worth it to take it out of that class and put it in its own file.
If you will need to update your UI from the task, you can see this answer on using an interface with a callback to your calling Activity.
My code goes as below :-
public class Activity2 extends ListActivity {
protected void onCreate(Bundle savedInstanceState)
{
.
.
readDatafromfile();
}
public void readDatafromfile(){
..
}
Now I want to do this reading asynchronously. I have created yet another class for this but I am not able to call the method ( readDatafromfile() ).
Please help.
You have three options to do that:
Define readDatafromfile() as static in your Activity class.
public class Activity2 extends ListActivity
{ public void readDatafromfile(){} }
Define readDatafromfile() in your AsyncTask and pass your Activity as context.
public class MyAsync extends AsyncTask < Void , Void , Void >
{
Context ctx;
public MyAsync ( Context ctx ){ this.ctx = ctx; }
public void readDatafromfile(){}
}
Create and interface IOOperation that contains readDatafromfile() , let your activity implement that, and pass it to your AsyncTask.
interface
public interface IOOperation
{ public void readDatafromfile(); }
activity
public class Activity2 extends ListActivity implements IOOperation
{
#override
public void readDatafromfile(){} }
asynctask
public class MyAsync extends AsyncTask < Void , Void , Void >
{
IOOperation reader;
public MyAsync ( IOOperation reader){ this.reader= reader; }
protected Void doInBackground(Void... args)
{ reader.readDatafromfile(); }
}
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("")
}
}