How to get local variable from Runnable Thread

I have a helper class (not for activity) that makes a request to an API that has a public function called run()

and runs on a new thread (as per Android spec). Mine MainActivity

creates a new object MakeQuery

and runs its function run()

:

MakeQuery q = new MakeQuery();
q.run();

      

However, I need to access the variable from the stream. Below is a sample code:

public class MakeQuery implements Runnable {

    private void setNewString(String localThreadString){
       //NewString comes out null...
       NewString  = localThreadString;
    }

    public void run() {
        new Thread(new Runnable() {
            public void run() {
                android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);

                API Api = new API(keys and tokens);

                //queryAPI() returns string
                setNewString(queryAPI(Api, term1, term2));

                //Don't know how to send intent from here (No context), 
                //I would like:
                Intent i = new Intent(MainActivity.class, AnotherActivity.class)
        }
    }).start();
}

      

AsyncTask

//This runs in background thread
@Override
protected Void doInBackground(Void... params) {
    API Api = new API(keys and tokens);

    setNewString(queryAPI(Api, string1, string2));

    return null;
}

@Override
protected void onPostExecute(Void aVoid) {
    Intent intent = new Intent(mContext, Activity2.class);
    intent.putExtra("NewString", NewString);
    Log.d(MYTAG, NewString);
}

      

MainActivity

public void buttonPressed(View view) {
    Intent intent = new Intent(this, Activity2.class);
    ...
    MakeQuery task = new MakeQuery(this);
    task.execute();

    startActivity(intent);
}

      

I've been trying to watch online for hours. I tried to do AsyncTask

, but I'm not sure how to implement this with what I have. Also, using it localThread<String>

didn't help.

TL; DR: I would like to know if the NewString can be received so that I can pass it through the Intent for another action.

Solution Don't use Runnable

, create a new AsyncTask

one as shown below. Also, make sure to be StartActivity

in the helper class and not in the MainActivity

. This happened because I was not waiting for the task to complete before starting a new activity.

+3


source to share


2 answers


Here's an implementation using an async task:

public class MakeQueryTask extends AsyncTask<Void, Void, Void> {

    private Context mContext;

    private String newString;

    public MakeQueryTask(Context context) {
        mContext = context;
    }

    //This runs on a background thread
    @Override
    protected Void doInBackground(Void... params) {


        API Api = new API(keys and tokens);

        //queryAPI() returns string
        setNewString(queryAPI(Api, term1, term2));

        //You should start your activity on main thread. Do it in onPostExecute() which will be invoked after the background thread is done
        //Intent i = new Intent(mContext, AnotherActivity.class);
        //mContext.startActivity(intent);
        return null;
    }

    private void setNewString(String localThreadString){
        newString  = localThreadString;
    }

    //This will run on UI thread
    @Override
    protected void onPostExecute(Void aVoid) {
        Intent intent = new Intent(mContext, AnotherActivity.class);
       mContext.startActivity(intent);
    }
}

      



And you do the following:

 MakeQueryTask task = new MakeQueryTask(this); //Here this is an activity (context)
 task.execute();

      

+4


source


If you call this runnable

from activity

or service

, you can pass in the constructor context

. And just start the operation with intent

in a function run()

.



public class MakeQuery implements Runnable {

    private Context context;

    public MakeQuery(Context context) {
        this.context = context;
    }

    private void setNewString(String localThreadString){
       //NewString comes out null...
       NewString  = localThreadString;
    }

    public void run() {
        new Thread(new Runnable() {
            public void run() {
                android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_BACKGROUND);

                API Api = new API(keys and tokens);

                //queryAPI() returns string
                setNewString(queryAPI(Api, term1, term2));

                Intent intent = new Intent(MainActivity.class, AnotherActivity.class)
                context.startActivity(intent);
        }
    }).start();
}

      

+2


source







All Articles