如何从可运行线程中获取局部变量

How to get a local variable from a Runnable Thread

我有一个助手(不是 activity)class 查询 API,它有一个名为 run() 的 public 函数,并且在新线程上运行(根据 Android 规范)。我的 MainActivity 创建一个新的 MakeQuery 对象并运行它的 run() 函数:

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

但是,我需要从线程内访问一个变量。下面是一个简短的代码示例:

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

异步任务

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

主要Activity

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

    startActivity(intent);
}

我已经试着上网看了好几个小时。我尝试过 AsyncTask,但我不确定如何用我现有的实现它。此外,使用 localThread<String> 没有帮助。

TLDR:我想知道是否有可能获得 NewString,以便我可以通过 Intent 将其传递给另一个 Activity。

解决方案 不要使用 Runnable,创建一个新的 AsyncTask,如下所示。另外,请确保 StartActivity 在助手 class 中而不是 MainActivity 中。这是因为在开始新的 activity.

之前我没有等待任务完成

如果您从 activityservice 调用此 runnable,您可以在构造函数中传入 context。只需在 run() 函数中使用 intent 启动 activity。

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

这是一个使用异步任务的实现:

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

你会这样执行:

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