Reputation: 1355
I am trying to send a string from one class to another using AsyncTask. In the code below everything is working with no errors, but I am wanting to get the returned str from newThread.execute() and save it to the string test. I have tried test = newThread.execute(), but I that produces the following error: Type mismatch: cannot convert from AsyncTask to String.
Class1.java
public void changText(View view) {
String test = "";
NewThread newThread = new NewThread();
newThread.execute();
}
Class2.java
public class NewThread extends AsyncTask<String, Integer, String> {
@Override
protected String doInBackground(String... params) {
String str = "this is a test";
return str;
}
Any help would be greatly appreciated.
Upvotes: 0
Views: 2319
Reputation: 63955
You need a way to publish the result via some callback mechanism if you put an AsyncTask
into it's own file. According to the dependency inversion principle it's better to let the AsyncTask define the callback mechanism instead of making it depend on some activity directly.
The resulting task could then look like this:
public class NewThread extends AsyncTask<String, Integer, String> {
/** A callback interface to be implemented by clients of this class */
public interface NewThreadClient {
void onNewThreadResult(String result);
}
private final NewThreadClient mClient;
public NewThread(NewThreadClient client) {
mClient = client;
}
@Override
protected String doInBackground(String... params) {
String str = "this is a test";
return str;
}
@Override
protected void onPostExecute(String result) {
mClient.onNewThreadResult(result);
}
}
To use it you'll need something that implements the callback. For example an Activity
public class TestActivity extends Activity implements NewThread.NewThreadClient {
private TextView mText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// simple textview actually intended for listviews..
setContentView(android.R.layout.simple_list_item_1);
mText = (TextView) findViewById(android.R.id.text1);
new NewThread(this).execute();
}
@Override
public void onNewThreadResult(String result) {
mText.setText(result);
}
}
The point of AsyncTask is that it does things asynchronously (while your program does other things, the result will be calculated at some point in the future). You can not (there are ways but it makes absolutely no sense) get the result immediately. test = newThread.execute()
would require that the result is immediately available. If you start to wait for the result you would block any progress that could happen in the meantime.
Callbacks are the most common way to get a result at a later point in time. AsyncTask
has onPostExecute
built-in for that purpose (also to deliver the result within the UI thread) and you can use it directly if you make your AsyncTasks
an inner class. Add another layer of callbacks and you can easily use them across classes.
Upvotes: 1
Reputation: 132982
As in Doc AsyncTask. execute (Params... params)
Return instance of AsyncTask.
but you are trying to assign AsyncTask instance to String. to get result back from Asynctask as String you should call execute().get()
method on main thread as:
NewThread newThread = new NewThread();
String test= newThread.execute().get(); //<< get String from doInBackground
but this will stop execution of main thread until doInBackground method execution not completed.
if you want to get result from doInBackground
without stopping execution of main thread then use onPostExecute
for updating UI because this method called on Main UI Thread when doInBackground execution complete :
@Override
protected void onPostExecute(String result) {
test = result; //<< get result here
}
Upvotes: 0
Reputation: 22527
Try this:
String test = newThread.execute().get();
The value returned from newThread.execute() is not the results of the computation; it's the AsyncTask itself. To publish your results, write a method in NewThread :
void onPostExecute(ArrayList<HashMap<String,String>> result) {
returnString = result; // or something similar
// then update the UI to reflect the results
}
Upvotes: 0
Reputation: 91
AsyncTask doesn't work like that, AsyncTask must be subclassed to be used.
the propose of an AsyncTask is execute some code in a separate thread (different from UI thread), but the result from that code, when ready, will be delivered in onPostExecute
.
So, your code will look like this:
public Class1{
String test = "";
public void changText(View view) {
NewThread newThread = new NewThread();
newThread.execute("input");
}
public class NewThread extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
String str = params[0] + " this is a test";
return str;
}
@Override
protected void onPostExecute(String result) {
test = result;
}
}
}
Upvotes: 2
Reputation: 751
See if you intend to do what i have done in following code
package com.example.myfirstapp;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
public class MyActivity extends Activity {
private String test;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
NewThread newThread = new NewThread();
newThread.execute();
}
class NewThread extends AsyncTask<String, Integer, String> {
@Override
protected String doInBackground(String... params) {
String str = "this is a test";
return str;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
test=result;
// update the UI like view.setText(test);
}
}
}
Upvotes: 0