Java – How to get local variables from a runnable thread

How to get local variables from a runnable thread… here is a solution to the problem.

How to get local variables from a runnable thread

I have a helper (not activity) class that makes queries against an API that has a public function called run(). and run on a new thread (according to the Android specification). My MainActivity creates a new MakeQuery object and runs its run() function:

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

However, I need to access a variable from within the thread. Here’s a short code example:

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

Asynchronous tasks

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

Primary activity

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

startActivity(intent);
}

I tried to check online for hours. I’ve tried doing AsyncTask, but I’m not sure how to implement it with what I have. Also, using localThread<String> doesn’t help.

TLDR: I was wondering if I could get NewString so I could pass it to another activity via an intent.

Solution
Instead of using Runnable, create a new AsyncTask as shown below. Also, make sure that the StartActivity is in the helper class and not in the MainActivity. This is because I didn’t wait for the task to complete before starting a new activity.

Solution

This is an implementation that uses asynchronous tasks:

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

You would do it like this:

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

Related Problems and Solutions