user908759
user908759

Reputation: 1355

Type mismatch: cannot convert from AsyncTask<String,Integer,String> to String

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

Answers (5)

zapl
zapl

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

ρяσѕρєя K
ρяσѕρєя K

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

Lazy Ninja
Lazy Ninja

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

Emaster
Emaster

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

MAkS
MAkS

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

Related Questions